" +
"You have been working for " + Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["b" /* convertTimeMsToTimeElapsedString */])(this.timeWorked) + "
" +
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " +
"but you will only gain half of the reputation you've earned so far."
}
PlayerObject.prototype.startWorkPartTime = function() {
this.resetWorkStatus();
this.isWorking = true;
this.workType = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeCompanyPartTime;
this.workHackExpGainRate = this.getWorkHackExpGain();
this.workStrExpGainRate = this.getWorkStrExpGain();
this.workDefExpGainRate = this.getWorkDefExpGain();
this.workDexExpGainRate = this.getWorkDexExpGain();
this.workAgiExpGainRate = this.getWorkAgiExpGain();
this.workChaExpGainRate = this.getWorkChaExpGain();
this.workRepGainRate = this.getWorkRepGain();
this.workMoneyGainRate = this.getWorkMoneyGain();
this.timeNeededToCompleteWork = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MillisecondsPer8Hours;
var newCancelButton = Object(__WEBPACK_IMPORTED_MODULE_15__utils_HelperFunctions_js__["b" /* clearEventListeners */])("work-in-progress-cancel-button");
newCancelButton.innerHTML = "Stop Working";
newCancelButton.addEventListener("click", function() {
Player.finishWorkPartTime();
return false;
});
//Display Work In Progress Screen
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadWorkInProgressContent();
}
PlayerObject.prototype.workPartTime = function(numCycles) {
this.workRepGainRate = this.getWorkRepGain();
this.workHackExpGained += this.workHackExpGainRate * numCycles;
this.workStrExpGained += this.workStrExpGainRate * numCycles;
this.workDefExpGained += this.workDefExpGainRate * numCycles;
this.workDexExpGained += this.workDexExpGainRate * numCycles;
this.workAgiExpGained += this.workAgiExpGainRate * numCycles;
this.workChaExpGained += this.workChaExpGainRate * numCycles;
this.workRepGained += this.workRepGainRate * numCycles;
this.workMoneyGained += this.workMoneyGainRate * numCycles;
var cyclesPerSec = 1000 / __WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"]._idleSpeed;
this.timeWorked += __WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"]._idleSpeed * numCycles;
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
if (this.timeWorked >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MillisecondsPer8Hours) {
var maxCycles = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].GameCyclesPer8Hours;
this.workHackExpGained = this.workHackExpGainRate * maxCycles;
this.workStrExpGained = this.workStrExpGainRate * maxCycles;
this.workDefExpGained = this.workDefExpGainRate * maxCycles;
this.workDexExpGained = this.workDexExpGainRate * maxCycles;
this.workAgiExpGained = this.workAgiExpGainRate * maxCycles;
this.workChaExpGained = this.workChaExpGainRate * maxCycles;
this.workRepGained = this.workRepGainRate * maxCycles;
this.workMoneyGained = this.workMoneyGainRate * maxCycles;
this.finishWorkPartTime();
return;
}
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
" at " + Player.companyName + "
" +
"You have been working for " + Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["b" /* convertTimeMsToTimeElapsedString */])(this.timeWorked) + "
" +
"You will automatically finish after working for 20 hours. You can cancel earlier if you wish. " +
"There is no penalty for cancelling earlier.";
}
//Money gained per game cycle
PlayerObject.prototype.getWorkMoneyGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.baseSalary * company.salaryMultiplier *
this.work_money_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkMoney;
}
//Hack exp gained per game cycle
PlayerObject.prototype.getWorkHackExpGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.hackingExpGain * company.expMultiplier *
this.hacking_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkExpGain;
}
//Str exp gained per game cycle
PlayerObject.prototype.getWorkStrExpGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.strengthExpGain * company.expMultiplier *
this.strength_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkExpGain;
}
//Def exp gained per game cycle
PlayerObject.prototype.getWorkDefExpGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.defenseExpGain * company.expMultiplier *
this.defense_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkExpGain;
}
//Dex exp gained per game cycle
PlayerObject.prototype.getWorkDexExpGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.dexterityExpGain * company.expMultiplier *
this.dexterity_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkExpGain;
}
//Agi exp gained per game cycle
PlayerObject.prototype.getWorkAgiExpGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.agilityExpGain * company.expMultiplier *
this.agility_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkExpGain;
}
//Charisma exp gained per game cycle
PlayerObject.prototype.getWorkChaExpGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
return this.companyPosition.charismaExpGain * company.expMultiplier *
this.charisma_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].CompanyWorkExpGain;
}
//Reputation gained per game cycle
PlayerObject.prototype.getWorkRepGain = function() {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
var jobPerformance = this.companyPosition.calculateJobPerformance(this.hacking_skill, this.strength,
this.defense, this.dexterity,
this.agility, this.charisma);
//Update reputation gain rate to account for company favor
var favorMult = 1 + (company.favor / 100);
if (isNaN(favorMult)) {favorMult = 1;}
return jobPerformance * this.company_rep_mult * favorMult;
}
PlayerObject.prototype.getFactionSecurityWorkRepGain = function() {
var t = 0.9 * (this.hacking_skill / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.strength / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.defense / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.dexterity / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.agility / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel) / 5;
return t * this.faction_rep_mult;
}
PlayerObject.prototype.getFactionFieldWorkRepGain = function() {
var t = 0.9 * (this.hacking_skill / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.strength / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.defense / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.dexterity / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.agility / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel +
this.charisma / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel) / 6;
return t * this.faction_rep_mult;
}
/* Creating a Program */
PlayerObject.prototype.startCreateProgramWork = function(programName, time, reqLevel) {
this.resetWorkStatus();
this.isWorking = true;
this.workType = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeCreateProgram;
//Time needed to complete work affected by hacking skill (linearly based on
//ratio of (your skill - required level) to MAX skill)
var timeMultiplier = (__WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel - (this.hacking_skill - reqLevel)) / __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].MaxSkillLevel;
if (timeMultiplier > 1) {timeMultiplier = 1;}
if (timeMultiplier < 0.01) {timeMultiplier = 0.01;}
this.timeNeededToCompleteWork = timeMultiplier * time;
//Check for incomplete program
for (var i = 0; i < Player.getHomeComputer().programs.length; ++i) {
var programFile = Player.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.createProgramName = programName;
var cancelButton = Object(__WEBPACK_IMPORTED_MODULE_15__utils_HelperFunctions_js__["b" /* clearEventListeners */])("work-in-progress-cancel-button");
cancelButton.innerHTML = "Cancel work on creating program";
cancelButton.addEventListener("click", function() {
Player.finishCreateProgramWork(true);
return false;
});
//Display Work In Progress Screen
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadWorkInProgressContent();
}
PlayerObject.prototype.createProgramWork = function(numCycles) {
this.timeWorked += __WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"]._idleSpeed * numCycles;
var programName = this.createProgramName;
if (this.timeWorked >= this.timeNeededToCompleteWork) {
this.finishCreateProgramWork(false);
}
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working on coding " + programName + ".
" +
"You have been working for " + Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["b" /* convertTimeMsToTimeElapsedString */])(this.timeWorked) + "
" +
"The program is " + (this.timeWorked / this.timeNeededToCompleteWork * 100).toFixed(2) + "% complete. " +
"If you cancel, your work will be saved and you can come back to complete the program later.";
}
PlayerObject.prototype.finishCreateProgramWork = function(cancelled, sing=false) {
var programName = this.createProgramName;
if (cancelled === false) {
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("You've finished creating " + programName + "! " +
"The new program can be found on your home computer.");
Player.getHomeComputer().programs.push(programName);
} else {
var perc = Math.floor(this.timeWorked / this.timeNeededToCompleteWork * 100).toString();
var incompleteName = programName + "-" + perc + "%-INC";
Player.getHomeComputer().programs.push(incompleteName);
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
Player.isWorking = false;
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadTerminalContent();
}
/* Studying/Taking Classes */
PlayerObject.prototype.startClass = function(costMult, expMult, className) {
this.resetWorkStatus();
this.isWorking = true;
this.workType = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeStudyClass;
this.className = className;
var gameCPS = 1000 / __WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"]._idleSpeed;
//Base exp gains per second
var baseStudyComputerScienceExp = 0.5;
var baseDataStructuresExp = 1;
var baseNetworksExp = 2;
var baseAlgorithmsExp = 4;
var baseManagementExp = 2;
var baseLeadershipExp = 4;
var baseGymExp = 1;
//Find cost and exp gain per game cycle
var cost = 0;
var hackExp = 0, strExp = 0, defExp = 0, dexExp = 0, agiExp = 0, chaExp = 0;
switch (className) {
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassStudyComputerScience:
hackExp = baseStudyComputerScienceExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassDataStructures:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassDataStructuresBaseCost * costMult / gameCPS;
hackExp = baseDataStructuresExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassNetworks:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassNetworksBaseCost * costMult / gameCPS;
hackExp = baseNetworksExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassAlgorithms:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassAlgorithmsBaseCost * costMult / gameCPS;
hackExp = baseAlgorithmsExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassManagement:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassManagementBaseCost * costMult / gameCPS;
chaExp = baseManagementExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassLeadership:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassLeadershipBaseCost * costMult / gameCPS;
chaExp = baseLeadershipExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymStrength:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymBaseCost * costMult / gameCPS;
strExp = baseGymExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymDefense:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymBaseCost * costMult / gameCPS;
defExp = baseGymExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymDexterity:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymBaseCost * costMult / gameCPS;
dexExp = baseGymExp * expMult / gameCPS;
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymAgility:
cost = __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymBaseCost * costMult / gameCPS;
agiExp = baseGymExp * expMult / gameCPS;
break;
default:
throw new Error("ERR: Invalid/unregocnized class name");
return;
}
this.workMoneyLossRate = cost;
this.workHackExpGainRate = hackExp * this.hacking_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].ClassGymExpGain;
this.workStrExpGainRate = strExp * this.strength_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].ClassGymExpGain;;
this.workDefExpGainRate = defExp * this.defense_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].ClassGymExpGain;;
this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].ClassGymExpGain;;
this.workAgiExpGainRate = agiExp * this.agility_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].ClassGymExpGain;;
this.workChaExpGainRate = chaExp * this.charisma_exp_mult * __WEBPACK_IMPORTED_MODULE_1__BitNode_js__["a" /* BitNodeMultipliers */].ClassGymExpGain;;
var cancelButton = Object(__WEBPACK_IMPORTED_MODULE_15__utils_HelperFunctions_js__["b" /* clearEventListeners */])("work-in-progress-cancel-button");
if (className == __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymStrength ||
className == __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymDefense ||
className == __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymDexterity ||
className == __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].ClassGymAgility) {
cancelButton.innerHTML = "Stop training at gym";
} else {
cancelButton.innerHTML = "Stop taking course";
}
cancelButton.addEventListener("click", function() {
Player.finishClass();
return false;
});
//Display Work In Progress Screen
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadWorkInProgressContent();
}
PlayerObject.prototype.takeClass = function(numCycles) {
this.timeWorked += __WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"]._idleSpeed * numCycles;
var className = this.className;
this.workHackExpGained += this.workHackExpGainRate * numCycles;
this.workStrExpGained += this.workStrExpGainRate * numCycles;
this.workDefExpGained += this.workDefExpGainRate * numCycles;
this.workDexExpGained += this.workDexExpGainRate * numCycles;
this.workAgiExpGained += this.workAgiExpGainRate * numCycles;
this.workChaExpGained += this.workChaExpGainRate * numCycles;
this.workRepGained += this.workRepGainRate * numCycles;
this.workMoneyGained += this.workMoneyGainRate * numCycles;
this.workMoneyGained -= this.workMoneyLossRate * numCycles;
var cyclesPerSec = 1000 / __WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"]._idleSpeed;
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You have been " + className + " for " + Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["b" /* convertTimeMsToTimeElapsedString */])(this.timeWorked) + "
" +
"You gained: "+
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.workHackExpGained, 4) + " hacking experience " +
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.workStrExpGained, 4) + " strength experience " +
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.workDefExpGained, 4) + " defense experience " +
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.workDexExpGained, 4) + " dexterity experience " +
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.workAgiExpGained, 4) + " agility experience " +
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.workChaExpGained, 4) + " charisma experience");
}
this.gainWorkExp();
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadLocationContent();
}
//Cancels the player's current "work" assignment and gives the proper rewards
//Used only for Singularity functions, so no popups are created
PlayerObject.prototype.singularityStopWork = function() {
if (!this.isWorking) {return "";}
var res; //Earnings text for work
switch (this.workType) {
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeStudyClass:
res = this.finishClass(true);
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeCompany:
res = this.finishWork(true, true);
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeCompanyPartTime:
res = this.finishWorkPartTime(true);
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeFaction:
res = this.finishFactionWork(true, true);
break;
case __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].WorkTypeCreateProgram:
res = this.finishCreateProgramWork(true, true);
break;
default:
console.log("ERROR: Unrecognized work type");
return "";
}
return res;
}
//Returns true if hospitalized, false otherwise
PlayerObject.prototype.takeDamage = function(amt) {
this.hp -= amt;
if (this.hp <= 0) {
this.hospitalize();
return true;
} else {
return false;
}
}
PlayerObject.prototype.hospitalize = function() {
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("You were in critical condition! You were taken to the hospital where " +
"luckily they were able to save your life. You were charged $" +
Object(__WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.max_hp * __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].HospitalCostPerHp, 2));
Player.loseMoney(this.max_hp * __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].HospitalCostPerHp);
this.hp = this.max_hp;
}
/********* Company job application **********/
//Determines the job that the Player should get (if any) at the current company
//The 'sing' argument designates whether or not this is being called from
//the applyToCompany() Netscript Singularity function
PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
var currCompany = "";
if (this.companyName != "") {
currCompany = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
}
var currPositionName = "";
if (this.companyPosition != "") {
currPositionName = this.companyPosition.positionName;
}
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (sing && !(company instanceof __WEBPACK_IMPORTED_MODULE_2__Company_js__["b" /* Company */])) {
return "ERROR: Invalid company name: " + this.location + ". applyToCompany() failed";
}
var pos = entryPosType;
if (!this.isQualified(company, pos)) {
var reqText = Object(__WEBPACK_IMPORTED_MODULE_2__Company_js__["f" /* getJobRequirementText */])(company, pos);
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position " + reqText);
return;
}
while (true) {
if (__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].Debug) {console.log("Determining qualification for next Company Position");}
var newPos = Object(__WEBPACK_IMPORTED_MODULE_2__Company_js__["g" /* getNextCompanyPosition */])(pos);
if (newPos == null) {break;}
//Check if this company has this position
if (company.hasPosition(newPos)) {
if (!this.isQualified(company, newPos)) {
//If player not qualified for next job, break loop so player will be given current job
break;
}
pos = newPos;
} else {
break;
}
}
//Check if the determined job is the same as the player's current job
if (currCompany != "") {
if (currCompany.companyName == company.companyName &&
pos.positionName == currPositionName) {
var nextPos = Object(__WEBPACK_IMPORTED_MODULE_2__Company_js__["g" /* getNextCompanyPosition */])(pos);
if (nextPos == null) {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("You are already at the highest position for your field! No promotion available");
} else if (company.hasPosition(nextPos)) {
if (sing) {return false;}
var reqText = Object(__WEBPACK_IMPORTED_MODULE_2__Company_js__["f" /* getJobRequirementText */])(company, nextPos);
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unfortunately, you do not qualify for a promotion " + reqText);
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("You are already at the highest position for your field! No promotion available");
}
return; //Same job, do nothing
}
}
//Lose reputation from a Company if you are leaving it for another job
var leaveCompany = false;
var oldCompanyName = "";
if (currCompany != "") {
if (currCompany.companyName != company.companyName) {
leaveCompany = true;
oldCompanyName = currCompany.companyName;
company.playerReputation -= 1000;
if (company.playerReputation < 0) {company.playerReputation = 0;}
}
}
this.companyName = company.companyName;
this.companyPosition = pos;
Player.firstJobRecvd = true;
if (leaveCompany) {
if (sing) {return true;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Congratulations! You were offered a new job at " + this.companyName + " as a " +
pos.positionName + "! " +
"You lost 1000 reputation at your old company " + oldCompanyName + " because you left.");
} else {
if (sing) {return true;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.positionName + "!");
}
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadLocationContent();
}
//Returns your next position at a company given the field (software, business, etc.)
PlayerObject.prototype.getNextCompanyPosition = function(company, entryPosType) {
var currCompany = null;
if (this.companyName != "") {
currCompany = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
}
//Not employed at this company, so return the entry position
if (currCompany == null || (currCompany.companyName != company.companyName)) {
return entryPosType;
}
//If the entry pos type and the player's current position have the same type,
//return the player's "nextCompanyPosition". Otherwise return the entryposType
//Employed at this company, so just return the next position if it exists.
if ((this.companyPosition.isSoftwareJob() && entryPosType.isSoftwareJob()) ||
(this.companyPosition.isITJob() && entryPosType.isITJob()) ||
(this.companyPosition.isSecurityEngineerJob() && entryPosType.isSecurityEngineerJob()) ||
(this.companyPosition.isNetworkEngineerJob() && entryPosType.isNetworkEngineerJob()) ||
(this.companyPosition.isSecurityJob() && entryPosType.isSecurityJob()) ||
(this.companyPosition.isAgentJob() && entryPosTypeisAgentJob()) ||
(this.companyPosition.isSoftwareConsultantJob() && entryPosType.isSoftwareConsultantJob()) ||
(this.companyPosition.isBusinessConsultantJob() && entryPosType.isBusinessConsultantJob()) ||
(this.companyPosition.isPartTimeJob() && entryPosType.isPartTimeJob())) {
return Object(__WEBPACK_IMPORTED_MODULE_2__Company_js__["g" /* getNextCompanyPosition */])(this.companyPosition);
}
return entryPosType;
}
PlayerObject.prototype.applyForSoftwareJob = function(sing=false) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].SoftwareIntern, sing);
}
PlayerObject.prototype.applyForSoftwareConsultantJob = function(sing=false) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].SoftwareConsultant, sing);
}
PlayerObject.prototype.applyForItJob = function(sing=false) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].ITIntern, sing);
}
PlayerObject.prototype.applyForSecurityEngineerJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].SecurityEngineer)) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].SecurityEngineer, sing);
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForNetworkEngineerJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].NetworkEngineer)) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].NetworkEngineer, sing);
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForBusinessJob = function(sing=false) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].BusinessIntern, sing);
}
PlayerObject.prototype.applyForBusinessConsultantJob = function(sing=false) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].BusinessConsultant, sing);
}
PlayerObject.prototype.applyForSecurityJob = function(sing=false) {
//TODO If case for POlice departments
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].SecurityGuard, sing);
}
PlayerObject.prototype.applyForAgentJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].FieldAgent)) {
return this.applyForJob(__WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].FieldAgent, sing);
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].Employee)) {
Player.firstJobRecvd = true;
this.companyName = company.companyName;
this.companyPosition = __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].Employee;
if (sing) {return true;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Congratulations, you are now employed at " + this.companyName);
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadLocationContent();
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].PartTimeEmployee)) {
Player.firstJobRecvd = true;
this.companyName = company.companyName;
this.companyPosition = __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].PartTimeEmployee;
if (sing) {return true;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Congratulations, you are now employed part-time at " + this.companyName);
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadLocationContent();
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].Waiter)) {
Player.firstJobRecvd = true;
this.companyName = company.companyName;
this.companyPosition = __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].Waiter;
if (sing) {return true;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Congratulations, you are now employed as a waiter at " + this.companyName);
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadLocationContent();
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForPartTimeWaiterJob = function(sing=false) {
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.location]; //Company being applied to
if (this.isQualified(company, __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].PartTimeWaiter)) {
Player.firstJobRecvd = true;
this.companyName = company.companyName;
this.companyPosition = __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].PartTimeWaiter;
if (sing) {return true;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Congratulations, you are now employed as a part-time waiter at " + this.companyName);
__WEBPACK_IMPORTED_MODULE_6__engine_js__["Engine"].loadLocationContent();
} else {
if (sing) {return false;}
Object(__WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Unforunately, you do not qualify for this position");
}
}
//Checks if the Player is qualified for a certain position
PlayerObject.prototype.isQualified = function(company, position) {
var offset = company.jobStatReqOffset;
var reqHacking = position.requiredHacking > 0 ? position.requiredHacking+offset : 0;
var reqStrength = position.requiredStrength > 0 ? position.requiredStrength+offset : 0;
var reqDefense = position.requiredDefense > 0 ? position.requiredDefense+offset : 0;
var reqDexterity = position.requiredDexterity > 0 ? position.requiredDexterity+offset : 0;
var reqAgility = position.requiredDexterity > 0 ? position.requiredDexterity+offset : 0;
var reqCharisma = position.requiredCharisma > 0 ? position.requiredCharisma+offset : 0;
if (this.hacking_skill >= reqHacking &&
this.strength >= reqStrength &&
this.defense >= reqDefense &&
this.dexterity >= reqDexterity &&
this.agility >= reqAgility &&
this.charisma >= reqCharisma &&
company.playerReputation >= position.requiredReputation) {
return true;
}
return false;
}
/********** Reapplying Augmentations and Source File ***********/
PlayerObject.prototype.reapplyAllAugmentations = function(resetMultipliers=true) {
console.log("Re-applying augmentations");
if (resetMultipliers) {
this.resetMultipliers();
}
for (let i = 0; i < this.augmentations.length; ++i) {
//Compatibility with new version
if (typeof this.augmentations[i] === 'string' || this.augmentations[i] instanceof String) {
var newOwnedAug = new PlayerOwnedAugmentation(this.augmentations[i]);
if (this.augmentations[i] == __WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["b" /* AugmentationNames */].NeuroFluxGovernor) {
newOwnedAug.level = __WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["c" /* Augmentations */][__WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["b" /* AugmentationNames */].NeuroFluxGovernor].level;
}
this.augmentations[i] = newOwnedAug;
}
var augName = this.augmentations[i].name;
var aug = __WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["c" /* Augmentations */][augName];
aug.owned = true;
if (aug == null) {
console.log("WARNING: Invalid augmentation name");
continue;
}
if (aug.name == __WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["b" /* AugmentationNames */].NeuroFluxGovernor) {
for (let j = 0; j < aug.level; ++j) {
Object(__WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["e" /* applyAugmentation */])(this.augmentations[i], true);
}
continue;
}
Object(__WEBPACK_IMPORTED_MODULE_0__Augmentations_js__["e" /* applyAugmentation */])(this.augmentations[i], true);
}
}
PlayerObject.prototype.reapplyAllSourceFiles = function() {
console.log("Re-applying source files");
//Will always be called after reapplyAllAugmentations() so multipliers do not have to be reset
//this.resetMultipliers();
for (let i = 0; i < this.sourceFiles.length; ++i) {
var srcFileKey = "SourceFile" + this.sourceFiles[i].n;
var sourceFileObject = __WEBPACK_IMPORTED_MODULE_12__SourceFile_js__["b" /* SourceFiles */][srcFileKey];
if (sourceFileObject == null) {
console.log("ERROR: Invalid source file number: " + this.sourceFiles[i].n);
continue;
}
Object(__WEBPACK_IMPORTED_MODULE_12__SourceFile_js__["c" /* applySourceFile */])(this.sourceFiles[i]);
}
}
/*************** Check for Faction Invitations *************/
//This function sets the requirements to join a Faction. It checks whether the Player meets
//those requirements and will return an array of all factions that the Player should
//receive an invitation to
PlayerObject.prototype.checkForFactionInvitations = function() {
let invitedFactions = []; //Array which will hold all Factions th eplayer should be invited to
var numAugmentations = this.augmentations.length;
var company = __WEBPACK_IMPORTED_MODULE_2__Company_js__["a" /* Companies */][this.companyName];
var companyRep = 0;
if (company != null) {
companyRep = company.playerReputation;
}
//Illuminati
var illuminatiFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Illuminati"];
if (!illuminatiFac.isBanned && !illuminatiFac.isMember && !illuminatiFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(150000000000) &&
this.hacking_skill >= 1500 &&
this.strength >= 1200 && this.defense >= 1200 &&
this.dexterity >= 1200 && this.agility >= 1200) {
invitedFactions.push(illuminatiFac);
}
//Daedalus
var daedalusFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Daedalus"];
if (!daedalusFac.isBanned && !daedalusFac.isMember && !daedalusFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(100000000000) &&
(this.hacking_skill >= 2500 ||
(this.strength >= 1500 && this.defense >= 1500 &&
this.dexterity >= 1500 && this.agility >= 1500))) {
invitedFactions.push(daedalusFac);
}
//The Covenant
var covenantFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["The Covenant"];
if (!covenantFac.isBanned && !covenantFac.isMember && !covenantFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(75000000000) &&
this.hacking_skill >= 850 &&
this.strength >= 850 &&
this.defense >= 850 &&
this.dexterity >= 850 &&
this.agility >= 850) {
invitedFactions.push(covenantFac);
}
//ECorp
var ecorpFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["ECorp"];
if (!ecorpFac.isBanned && !ecorpFac.isMember && !ecorpFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].AevumECorp && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(ecorpFac);
}
//MegaCorp
var megacorpFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["MegaCorp"];
if (!megacorpFac.isBanned && !megacorpFac.isMember && !megacorpFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12MegaCorp && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(megacorpFac);
}
//Bachman & Associates
var bachmanandassociatesFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Bachman & Associates"];
if (!bachmanandassociatesFac.isBanned && !bachmanandassociatesFac.isMember &&
!bachmanandassociatesFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].AevumBachmanAndAssociates && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(bachmanandassociatesFac);
}
//Blade Industries
var bladeindustriesFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Blade Industries"];
if (!bladeindustriesFac.isBanned && !bladeindustriesFac.isMember && !bladeindustriesFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12BladeIndustries && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(bladeindustriesFac);
}
//NWO
var nwoFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["NWO"];
if (!nwoFac.isBanned && !nwoFac.isMember && !nwoFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].VolhavenNWO && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(nwoFac);
}
//Clarke Incorporated
var clarkeincorporatedFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Clarke Incorporated"];
if (!clarkeincorporatedFac.isBanned && !clarkeincorporatedFac.isMember && !clarkeincorporatedFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].AevumClarkeIncorporated && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(clarkeincorporatedFac);
}
//OmniTek Incorporated
var omnitekincorporatedFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["OmniTek Incorporated"];
if (!omnitekincorporatedFac.isBanned && !omnitekincorporatedFac.isMember && !omnitekincorporatedFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].VolhavenOmniTekIncorporated && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(omnitekincorporatedFac);
}
//Four Sigma
var foursigmaFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Four Sigma"];
if (!foursigmaFac.isBanned && !foursigmaFac.isMember && !foursigmaFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12FourSigma && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(foursigmaFac);
}
//KuaiGong International
var kuaigonginternationalFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["KuaiGong International"];
if (!kuaigonginternationalFac.isBanned && !kuaigonginternationalFac.isMember &&
!kuaigonginternationalFac.alreadyInvited &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].ChongqingKuaiGongInternational && companyRep >= __WEBPACK_IMPORTED_MODULE_3__Constants_js__["a" /* CONSTANTS */].CorpFactionRepRequirement) {
invitedFactions.push(kuaigonginternationalFac);
}
//Fulcrum Secret Technologies - If u've unlocked fulcrum secret technolgoies server and have a high rep with the company
var fulcrumsecrettechonologiesFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Fulcrum Secret Technologies"];
var fulcrumSecretServer = __WEBPACK_IMPORTED_MODULE_10__Server_js__["b" /* AllServers */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["a" /* SpecialServerIps */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["b" /* SpecialServerNames */].FulcrumSecretTechnologies]];
if (fulcrumSecretServer == null) {
console.log("ERROR: Could not find Fulcrum Secret Technologies Server");
} else {
if (!fulcrumsecrettechonologiesFac.isBanned && !fulcrumsecrettechonologiesFac.isMember &&
!fulcrumsecrettechonologiesFac.alreadyInvited &&
fulcrumSecretServer.manuallyHacked &&
this.companyName == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].AevumFulcrumTechnologies && companyRep >= 250000) {
invitedFactions.push(fulcrumsecrettechonologiesFac);
}
}
//BitRunners
var bitrunnersFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["BitRunners"];
var homeComp = this.getHomeComputer();
var bitrunnersServer = __WEBPACK_IMPORTED_MODULE_10__Server_js__["b" /* AllServers */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["a" /* SpecialServerIps */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["b" /* SpecialServerNames */].BitRunnersServer]];
if (bitrunnersServer == null) {
console.log("ERROR: Could not find BitRunners Server");
} else if (!bitrunnersFac.isBanned && !bitrunnersFac.isMember && bitrunnersServer.manuallyHacked &&
!bitrunnersFac.alreadyInvited && this.hacking_skill >= 500 && homeComp.maxRam >= 128) {
invitedFactions.push(bitrunnersFac);
}
//The Black Hand
var theblackhandFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["The Black Hand"];
var blackhandServer = __WEBPACK_IMPORTED_MODULE_10__Server_js__["b" /* AllServers */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["a" /* SpecialServerIps */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["b" /* SpecialServerNames */].TheBlackHandServer]];
if (blackhandServer == null) {
console.log("ERROR: Could not find The Black Hand Server");
} else if (!theblackhandFac.isBanned && !theblackhandFac.isMember && blackhandServer.manuallyHacked &&
!theblackhandFac.alreadyInvited && this.hacking_skill >= 350 && homeComp.maxRam >= 64) {
invitedFactions.push(theblackhandFac);
}
//NiteSec
var nitesecFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["NiteSec"];
var nitesecServer = __WEBPACK_IMPORTED_MODULE_10__Server_js__["b" /* AllServers */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["a" /* SpecialServerIps */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["b" /* SpecialServerNames */].NiteSecServer]];
if (nitesecServer == null) {
console.log("ERROR: Could not find NiteSec Server");
} else if (!nitesecFac.isBanned && !nitesecFac.isMember && nitesecServer.manuallyHacked &&
!nitesecFac.alreadyInvited && this.hacking_skill >= 200 && homeComp.maxRam >= 32) {
invitedFactions.push(nitesecFac);
}
//Chongqing
var chongqingFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Chongqing"];
if (!chongqingFac.isBanned && !chongqingFac.isMember && !chongqingFac.alreadyInvited &&
this.money.gte(20000000) && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Chongqing) {
invitedFactions.push(chongqingFac);
}
//Sector-12
var sector12Fac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Sector-12"];
if (!sector12Fac.isBanned && !sector12Fac.isMember && !sector12Fac.alreadyInvited &&
this.money.gte(15000000) && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12) {
invitedFactions.push(sector12Fac);
}
//New Tokyo
var newtokyoFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["New Tokyo"];
if (!newtokyoFac.isBanned && !newtokyoFac.isMember && !newtokyoFac.alreadyInvited &&
this.money.gte(20000000) && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].NewTokyo) {
invitedFactions.push(newtokyoFac);
}
//Aevum
var aevumFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Aevum"];
if (!aevumFac.isBanned && !aevumFac.isMember && !aevumFac.alreadyInvited &&
this.money.gte(40000000) && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Aevum) {
invitedFactions.push(aevumFac);
}
//Ishima
var ishimaFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Ishima"];
if (!ishimaFac.isBanned && !ishimaFac.isMember && !ishimaFac.alreadyInvited &&
this.money.gte(30000000) && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Ishima) {
invitedFactions.push(ishimaFac);
}
//Volhaven
var volhavenFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Volhaven"];
if (!volhavenFac.isBanned && !volhavenFac.isMember && !volhavenFac.alreadyInvited &&
this.money.gte(50000000) && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Volhaven) {
invitedFactions.push(volhavenFac);
}
//Speakers for the Dead
var speakersforthedeadFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Speakers for the Dead"];
if (!speakersforthedeadFac.isBanned && !speakersforthedeadFac.isMember && !speakersforthedeadFac.alreadyInvited &&
this.hacking_skill >= 100 && this.strength >= 300 && this.defense >= 300 &&
this.dexterity >= 300 && this.agility >= 300 && this.numPeopleKilled >= 30 &&
this.karma <= -45 && this.companyName != __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12CIA &&
this.companyName != __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12NSA) {
invitedFactions.push(speakersforthedeadFac);
}
//The Dark Army
var thedarkarmyFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["The Dark Army"];
if (!thedarkarmyFac.isBanned && !thedarkarmyFac.isMember && !thedarkarmyFac.alreadyInvited &&
this.hacking_skill >= 300 && this.strength >= 300 && this.defense >= 300 &&
this.dexterity >= 300 && this.agility >= 300 && this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Chongqing &&
this.numPeopleKilled >= 5 && this.karma <= -45 && this.companyName != __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12CIA &&
this.companyName != __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12NSA) {
invitedFactions.push(thedarkarmyFac);
}
//The Syndicate
var thesyndicateFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["The Syndicate"];
if (!thesyndicateFac.isBanned && !thesyndicateFac.isMember && !thesyndicateFac.alreadyInvited &&
this.hacking_skill >= 200 && this.strength >= 200 && this.defense >= 200 &&
this.dexterity >= 200 && this.agility >= 200 &&
(this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Aevum || this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12) &&
this.money.gte(10000000) && this.karma <= -90 &&
this.companyName != __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12CIA && this.companyName != __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Sector12NSA) {
invitedFactions.push(thesyndicateFac);
}
//Silhouette
var silhouetteFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Silhouette"];
if (!silhouetteFac.isBanned && !silhouetteFac.isMember && !silhouetteFac.alreadyInvited &&
(this.companyPosition.positionName == __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].CTO.positionName ||
this.companyPosition.positionName == __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].CFO.positionName ||
this.companyPosition.positionName == __WEBPACK_IMPORTED_MODULE_2__Company_js__["d" /* CompanyPositions */].CEO.positionName) &&
this.money.gte(15000000) && this.karma <= -22) {
invitedFactions.push(silhouetteFac);
}
//Tetrads
var tetradsFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Tetrads"];
if (!tetradsFac.isBanned && !tetradsFac.isMember && !tetradsFac.alreadyInvited &&
(this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Chongqing || this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].NewTokyo ||
this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Ishima) && this.strength >= 75 && this.defense >= 75 &&
this.dexterity >= 75 && this.agility >= 75 && this.karma <= -18) {
invitedFactions.push(tetradsFac);
}
//SlumSnakes
var slumsnakesFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Slum Snakes"];
if (!slumsnakesFac.isBanned && !slumsnakesFac.isMember && !slumsnakesFac.alreadyInvited &&
this.strength >= 30 && this.defense >= 30 && this.dexterity >= 30 &&
this.agility >= 30 && this.karma <= -9 && this.money.gte(1000000)) {
invitedFactions.push(slumsnakesFac);
}
//Netburners
var netburnersFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Netburners"];
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;
}
if (!netburnersFac.isBanned && !netburnersFac.isMember && !netburnersFac.alreadyInvited &&
this.hacking_skill >= 80 && totalHacknetRam >= 8 &&
totalHacknetCores >= 4 && totalHacknetLevels >= 100) {
invitedFactions.push(netburnersFac);
}
//Tian Di Hui
var tiandihuiFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["Tian Di Hui"];
if (!tiandihuiFac.isBanned && !tiandihuiFac.isMember && !tiandihuiFac.alreadyInvited &&
this.money.gte(1000000) && this.hacking_skill >= 50 &&
(this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Chongqing || this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].NewTokyo ||
this.city == __WEBPACK_IMPORTED_MODULE_9__Location_js__["a" /* Locations */].Ishima)) {
invitedFactions.push(tiandihuiFac);
}
//CyberSec
var cybersecFac = __WEBPACK_IMPORTED_MODULE_7__Faction_js__["b" /* Factions */]["CyberSec"];
var cybersecServer = __WEBPACK_IMPORTED_MODULE_10__Server_js__["b" /* AllServers */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["a" /* SpecialServerIps */][__WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__["b" /* SpecialServerNames */].CyberSecServer]];
if (cybersecServer == null) {
console.log("ERROR: Could not find CyberSec Server");
} else if (!cybersecFac.isBanned && !cybersecFac.isMember && cybersecServer.manuallyHacked &&
!cybersecFac.alreadyInvited && this.hacking_skill >= 50) {
invitedFactions.push(cybersecFac);
}
return invitedFactions;
}
/*************** Gang ****************/
//Returns true if Player is in a gang and false otherwise
PlayerObject.prototype.inGang = function() {
if (this.gang == null || this.gang == undefined) {return false;}
return (this.gang instanceof __WEBPACK_IMPORTED_MODULE_8__Gang_js__["b" /* Gang */]);
}
PlayerObject.prototype.startGang = function(factionName, hacking) {
this.gang = new __WEBPACK_IMPORTED_MODULE_8__Gang_js__["b" /* Gang */](factionName, hacking);
}
/************* BitNodes **************/
PlayerObject.prototype.setBitNodeNumber = function(n) {
this.bitNodeN = n;
}
/* Functions for saving and loading the Player data */
function loadPlayer(saveString) {
Player = JSON.parse(saveString, __WEBPACK_IMPORTED_MODULE_17__utils_JSONReviver_js__["c" /* Reviver */]);
//Parse Decimal.js objects
Player.money = new __WEBPACK_IMPORTED_MODULE_13__utils_decimal_js___default.a(Player.money);
Player.total_money = new __WEBPACK_IMPORTED_MODULE_13__utils_decimal_js___default.a(Player.total_money);
Player.lifetime_money = new __WEBPACK_IMPORTED_MODULE_13__utils_decimal_js___default.a(Player.lifetime_money);
}
PlayerObject.prototype.toJSON = function() {
return Object(__WEBPACK_IMPORTED_MODULE_17__utils_JSONReviver_js__["b" /* Generic_toJSON */])("PlayerObject", this);
}
PlayerObject.fromJSON = function(value) {
return Object(__WEBPACK_IMPORTED_MODULE_17__utils_JSONReviver_js__["a" /* Generic_fromJSON */])(PlayerObject, value.data);
}
__WEBPACK_IMPORTED_MODULE_17__utils_JSONReviver_js__["c" /* Reviver */].constructors.PlayerObject = PlayerObject;
let Player = new PlayerObject();
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* unused harmony export sizeOfObject */
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return addOffset; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return clearEventListeners; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return getRandomInt; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return compareArrays; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return printArray; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return powerOfTwo; });
//General helper functions
//Returns the size (number of keys) of an object
function sizeOfObject(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
}
//Adds a random offset to a number within a certain percentage
//e.g. addOffset(100, 5) will return anything from 95 to 105.
//The percentage argument must be between 0 and 100;
function addOffset(n, percentage) {
if (percentage < 0 || percentage > 100) {return;}
var offset = n * (percentage / 100);
return n + ((Math.random() * (2 * offset)) - offset);
}
//Given an element by its Id(usually an 'a' element), removes all event listeners
//from that element by cloning and replacing. Then returns the new cloned element
function clearEventListeners(elemId) {
var elem = document.getElementById(elemId);
if (elem == null) {console.log("ERR: Could not find element for: " + elemId); return null;}
var newElem = elem.cloneNode(true);
elem.parentNode.replaceChild(newElem, elem);
return newElem;
}
function getRandomInt(min, max) {
if (min > max) {return getRandomInt(max, min);}
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//Returns true if all elements are equal, and false otherwise
//Assumes both arguments are arrays and that there are no nested arrays
function compareArrays(a1, a2) {
if (a1.length != a2.length) {
return false;
}
for (var i = 0; i < a1.length; ++i) {
if (a1[i] != a2[i]) {return false;}
}
return true;
}
function printArray(a) {
return "[" + a.join(", ") + "]";
}
//Returns bool indicating whether or not its a power of 2
function powerOfTwo(n) {
if (isNaN(n)) {return false;}
return n && (n & (n-1)) === 0;
}
/***/ }),
/* 2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return dialogBoxCreate; });
/* Pop up Dialog Box */
let dialogBoxes = [];
//Close dialog box when clicking outside
$(document).click(function(event) {
if (dialogBoxOpened && dialogBoxes.length >= 1) {
if (!$(event.target).closest(dialogBoxes[0]).length){
dialogBoxes[0].remove();
dialogBoxes.splice(0, 1);
if (dialogBoxes.length == 0) {
dialogBoxOpened = false;
} else {
dialogBoxes[0].style.visibility = "visible";
}
}
}
});
//Dialog box close buttons
$(document).on('click', '.dialog-box-close-button', function( event ) {
if (dialogBoxOpened && dialogBoxes.length >= 1) {
dialogBoxes[0].remove();
dialogBoxes.splice(0, 1);
if (dialogBoxes.length == 0) {
dialogBoxOpened = false;
} else {
dialogBoxes[0].style.visibility = "visible";
}
}
});
var dialogBoxOpened = false;
function dialogBoxCreate(txt) {
var container = document.createElement("div");
container.setAttribute("class", "dialog-box-container");
var content = document.createElement("div");
content.setAttribute("class", "dialog-box-content");
var closeButton = document.createElement("span");
closeButton.setAttribute("class", "dialog-box-close-button");
closeButton.innerHTML = "×"
var textE = document.createElement("p");
textE.innerHTML = txt;
content.appendChild(closeButton);
content.appendChild(textE);
container.appendChild(content);
document.body.appendChild(container);
if (dialogBoxes.length >= 1) {
container.style.visibility = "hidden";
}
dialogBoxes.push(container);
setTimeout(function() {
dialogBoxOpened = true;
}, 400);
}
/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(8)))
/***/ }),
/* 3 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CONSTANTS; });
let CONSTANTS = {
Version: "0.28.1",
//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
//the player will have this level assuming no multipliers. Multipliers can cause skills to go above this.
MaxSkillLevel: 975,
//How much reputation is needed to join a megacorporation's faction
CorpFactionRepRequirement: 250000,
/* Base costs */
BaseCostFor1GBOfRamHome: 30000,
BaseCostFor1GBOfRamServer: 50000, //1 GB of RAM
BaseCostFor1GBOfRamHacknetNode: 30000,
BaseCostForHacknetNode: 1000,
BaseCostForHacknetNodeCore: 500000,
/* Hacknet Node constants */
HacknetNodeMoneyGainPerLevel: 1.6,
HacknetNodePurchaseNextMult: 1.85, //Multiplier when purchasing an additional hacknet node
HacknetNodeUpgradeLevelMult: 1.04, //Multiplier for cost when upgrading level
HacknetNodeUpgradeRamMult: 1.28, //Multiplier for cost when upgrading RAM
HacknetNodeUpgradeCoreMult: 1.48, //Multiplier for cost when buying another core
HacknetNodeMaxLevel: 200,
HacknetNodeMaxRam: 64,
HacknetNodeMaxCores: 16,
/* Faction and Company favor */
FactionReputationToFavorBase: 500,
FactionReputationToFavorMult: 1.02,
CompanyReputationToFavorBase: 500,
CompanyReputationToFavorMult: 1.02,
/* Augmentation */
//NeuroFlux Governor cost multiplier as you level up
NeuroFluxGovernorLevelMult: 1.14,
//RAM Costs for different commands
ScriptWhileRamCost: 0.2,
ScriptForRamCost: 0.2,
ScriptIfRamCost: 0.1,
ScriptHackRamCost: 0.1,
ScriptGrowRamCost: 0.15,
ScriptWeakenRamCost: 0.15,
ScriptScanRamCost: 0.2,
ScriptNukeRamCost: 0.05,
ScriptBrutesshRamCost: 0.05,
ScriptFtpcrackRamCost: 0.05,
ScriptRelaysmtpRamCost: 0.05,
ScriptHttpwormRamCost: 0.05,
ScriptSqlinjectRamCost: 0.05,
ScriptRunRamCost: 0.8,
ScriptExecRamCost: 1.1,
ScriptScpRamCost: 0.5,
ScriptKillRamCost: 0.5, //Kill and killall
ScriptHasRootAccessRamCost: 0.05,
ScriptGetHostnameRamCost: 0.05,
ScriptGetHackingLevelRamCost: 0.05,
ScriptGetServerCost: 0.1,
ScriptFileExistsRamCost: 0.1,
ScriptIsRunningRamCost: 0.1,
ScriptOperatorRamCost: 0.01,
ScriptPurchaseHacknetRamCost: 1.5,
ScriptHacknetNodesRamCost: 1.0, //Base cost for accessing hacknet nodes array
ScriptHNUpgLevelRamCost: 0.4,
ScriptHNUpgRamRamCost: 0.6,
ScriptHNUpgCoreRamCost: 0.8,
ScriptGetStockRamCost: 2.0,
ScriptBuySellStockRamCost: 2.5,
ScriptPurchaseServerRamCost: 2.0,
ScriptRoundRamCost: 0.05,
ScriptReadWriteRamCost: 1.0,
ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args
ScriptGetScriptRamCost: 0.1,
ScriptGetHackTimeRamCost: 0.05,
ScriptSingularityFn1RamCost: 1,
ScriptSingularityFn2RamCost: 2,
ScriptSingularityFn3RamCost: 3,
MultithreadingRAMCost: 1,
//Server constants
ServerBaseGrowthRate: 1.03, //Unadjusted Growth rate
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
PurchasedServerLimit: 25,
//Augmentation Constants
AugmentationCostMultiplier: 5, //Used for balancing costs without having to readjust every Augmentation cost
AugmentationRepMultiplier: 2.5, //Used for balancing rep cost without having to readjust every value
MultipleAugMultiplier: 1.9,
//How much a TOR router costs
TorRouterCost: 200000,
//Infiltration constants
InfiltrationBribeBaseAmount: 100000, //Amount per clearance level
InfiltrationMoneyValue: 2000, //Convert "secret" value to money
//Stock market constants
WSEAccountCost: 200000000,
TIXAPICost: 5000000000,
StockMarketCommission: 100000,
//Hospital/Health
HospitalCostPerHp: 100000,
//Gang constants
GangRespectToReputationRatio: 2, //Respect is divided by this to get rep gain
MaximumGangMembers: 20,
GangRecruitCostMultiplier: 2,
GangTerritoryUpdateTimer: 150,
MillisecondsPer20Hours: 72000000,
GameCyclesPer20Hours: 72000000 / 200,
MillisecondsPer10Hours: 36000000,
GameCyclesPer10Hours: 36000000 / 200,
MillisecondsPer8Hours: 28800000,
GameCyclesPer8Hours: 28800000 / 200,
MillisecondsPer4Hours: 14400000,
GameCyclesPer4Hours: 14400000 / 200,
MillisecondsPer2Hours: 7200000,
GameCyclesPer2Hours: 7200000 / 200,
MillisecondsPerHour: 3600000,
GameCyclesPerHour: 3600000 / 200,
MillisecondsPerHalfHour: 1800000,
GameCyclesPerHalfHour: 1800000 / 200,
MillisecondsPerQuarterHour: 900000,
GameCyclesPerQuarterHour: 900000 / 200,
MillisecondsPerFiveMinutes: 300000,
GameCyclesPerFiveMinutes: 300000 / 200,
FactionWorkHacking: "Faction Hacking Work",
FactionWorkField: "Faction Field Work",
FactionWorkSecurity: "Faction Security Work",
WorkTypeCompany: "Working for Company",
WorkTypeCompanyPartTime: "Working for Company part-time",
WorkTypeFaction: "Working for Faction",
WorkTypeCreateProgram: "Working on Create a Program",
WorkTypeStudyClass: "Studying or Taking a class at university",
WorkTypeCrime: "Committing a crime",
ClassStudyComputerScience: "studying Computer Science",
ClassDataStructures: "taking a Data Structures course",
ClassNetworks: "taking a Networks course",
ClassAlgorithms: "taking an Algorithms course",
ClassManagement: "taking a Management course",
ClassLeadership: "taking a Leadership course",
ClassGymStrength: "training your strength at a gym",
ClassGymDefense: "training your defense at a gym",
ClassGymDexterity: "training your dexterity at a gym",
ClassGymAgility: "training your agility at a gym",
ClassDataStructuresBaseCost: 40,
ClassNetworksBaseCost: 80,
ClassAlgorithmsBaseCost: 320,
ClassManagementBaseCost: 160,
ClassLeadershipBaseCost: 320,
ClassGymBaseCost: 120,
CrimeShoplift: "shoplift",
CrimeRobStore: "rob a store",
CrimeMug: "mug someone",
CrimeLarceny: "commit larceny",
CrimeDrugs: "deal drugs",
CrimeTraffickArms: "traffick illegal arms",
CrimeHomicide: "commit homicide",
CrimeGrandTheftAuto: "commit grand theft auto",
CrimeKidnap: "kidnap someone for ransom",
CrimeAssassination: "assassinate a high-profile target",
CrimeHeist: "pull off the ultimate heist",
/* Tutorial related things */
TutorialNetworkingText: "Servers are a central part of the game. You start with a single personal server (your home computer) " +
"and you can purchase additional servers as you progress through the game. Connecting to other servers " +
"and hacking them can be a major source of income and experience. Servers can also be used to run " +
"scripts which can automatically hack servers for you.
" +
"In order to navigate between machines, use the 'scan' or 'scan-analyze' Terminal command to see all servers " +
"that are reachable from your current server. Then, you can use the 'connect [hostname/ip]' " +
"command to connect to one of the available machines.
" +
"The 'hostname' and 'ifconfig' commands can be used to display the hostname/IP of the " +
"server you are currently connected to.",
TutorialHackingText: "In the year 2077, currency has become digital and decentralized. People and corporations " +
"store their money on servers. By hacking these servers, you can steal their money and gain " +
"experience.
" +
"
Gaining root access
" +
"The key to hacking a server is to gain root access to that server. This can be done using " +
"the NUKE virus (NUKE.exe). You start the game with a copy of the NUKE virus on your home " +
"computer. The NUKE virus attacks the target server's open ports using buffer overflow " +
"exploits. When successful, you are granted root administrative access to the machine.
" +
"Typically, in order for the NUKE virus to succeed, the target server needs to have at least " +
"one of its ports opened. Some servers have no security and will not need any ports opened. Some " +
"will have very high security and will need many ports opened. In order to open ports on another " +
"server, you will need to run programs that attack the server to open specific ports. These programs " +
"can be coded once your hacking skill gets high enough, or they can be purchased if you can find " +
"a seller.
" +
"In order to determine how many ports need to be opened to successfully NUKE a server, connect to " +
"that server and run the 'analyze' command. This will also show you which ports have already been " +
"opened.
" +
"Once you have enough ports opened and have ran the NUKE virus to gain root access, the server " +
"can then be hacked by simply calling the 'hack' command through terminal, or by using a script.
" +
"
Hacking mechanics
" +
"When you execute the hack command, either manually through the terminal or automatically through " +
"a script, you attempt to hack the server. This action takes time. The more advanced a server's " +
"security is, the more time it will take. Your hacking skill level also affects the hacking time, " +
"with a higher hacking skill leading to shorter hacking times. Also, running the hack command " +
"manually through terminal is faster than hacking from a script.
" +
"Your attempt to hack a server will not always succeed. The chance you have to successfully hack a " +
"server is also determined by the server's security and your hacking skill level. Even if your " +
"hacking attempt is unsuccessful, you will still gain experience points.
" +
"When you successfully hack a server. You steal a certain percentage of that server's total money. This " +
"percentage is determined by the server's security and your hacking skill level. 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 (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.
" +
"
Server Security
" +
"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 " +
"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 " +
"getServerSecurityLevel(server) function in Netscript. See the Netscript documentation for more details. " +
"This function will give you an exact value for a server's security.
" +
"Whenever a server is hacked manually or through a script, its security level increases by a small amount. Calling " +
"the grow() command in a script will also increase security level of the target server. These actions will " +
"make it harder for you to hack the server, and decrease the amount of money you can steal. You can lower a " +
"server's security level in a script using the weaken(server) function in Netscript. See the Netscript " +
"documentation for more details.
" +
"A server has a minimum security level that is equal to one third of its starting security, rounded to the " +
"nearest integer. To be more precise:
" +
"This means that a server's security will not fall below this value if you are trying to weaken it.",
TutorialScriptsText: "Scripts can be used to automate the hacking process. Scripts must be written in the Netscript language. " +
"Documentation about the Netscript language can be found in the 'Netscript Programming Language' " +
"section of this 'Tutorial' page.
" +
"It is highly recommended that you have a basic background in programming to start writing scripts. " +
"You by no means need to be an expert. All you need is some familiarity with basic programming " +
"constructs like for/while loops, if statements, " +
"functions, variables, etc. The Netscript programming language most resembles the Javascript language. " +
"Therefore, a good beginner's programming tutorial to read might be " +
"this one. Note that while the Netscript language is similar to Javascript, it is not the exact same, so the " +
"syntax will vary a little bit.
" +
"Running a script requires RAM. The more complex a script is, the more RAM " +
"it requires to run. Scripts can be run on any server you have root access to.
" +
"Here are some Terminal commands that are useful when working with scripts:
" +
"check [script] [args...] Prints the logs of the script specified by the name and arguments to Terminal. Arguments should be separated " +
"by a space. Note that scripts are uniquely " +
"identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'check' it you must " +
"also add the 'foodnstuff' argument to the check command as so: check foo.script foodnstuff
" +
"free Shows the current server's RAM usage and availability
" +
"kill [script] [args...] Stops a script that is running with the specified script name and arguments. " +
"Arguments should be separated by a space. Note that " +
"scripts are uniquely identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the " +
"argument 1 and 2, then just typing 'kill foo.script' will not work. You have to use 'kill foo.script 1 2'.
" +
"mem [script] [-t] [n] Check how much RAM a script requires to run with n threads
" +
"nano [script] Create/Edit a script. The name of the script must end with the '.script' extension
" +
"ps Displays all scripts that are actively running on the current server
" +
"rm [script] Delete a script
" +
"run [script] [-t] [n] [args...] Run a script with n threads and the specified arguments. Each argument should be separated by a space. " +
"Both the arguments and thread specification are optional. If neither are specified, then the script will be run single-threaded with no arguments. " +
"Examples: run foo.script The command above will run 'foo.script' single-threaded with no arguments." +
" run foo.script -t 10 The command above will run 'foo.script' with 10 threads and no arguments." +
" run foo.script foodnstuff sigma-cosmetics 10 The command above will run 'foo.script' single-threaded with three arguments: [foodnstuff, sigma-cosmetics, 10]" +
" run foo.script -t 50 foodnstuff The command above will run 'foo.script' with 50 threads and a single argument: [foodnstuff]
" +
"tail [script] [args...] Displays the logs of the script specified by the name and arguments. Note that scripts are uniquely " +
"identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'tail' it you must " +
"also add the 'foodnstuff' argument to the tail command as so: tail foo.script foodnstuff
" +
"top Displays all active scripts and their RAM usage
" +
"
Multithreading scripts
" +
"Scripts can be multithreaded. A multithreaded script runs the script's code once in each thread. The result is that " +
"every call to the hack(), grow(), and weaken() Netscript functions will have its effect multiplied by the number of threads. " +
"For example, if a normal single-threaded script is able to hack $10,000, then running the same script with 5 threads would " +
"yield $50,000.
" +
"When multithreading a script, the total RAM cost can be calculated by simply multiplying the base RAM cost of the script " +
"with the number of threads, where the base cost refers to the amount of RAM required to run the script single-threaded. " +
"In the terminal, you can run the " +
"'mem [scriptname] -t n' command to see how much RAM a script requires with n threads.
" +
"Every method for running a script has an option for making it multihreaded. To run a script with " +
"n threads from a Terminal: " +
"run [scriptname] -t n
" +
" The scripts that you write and execute are interpreted in Javascript. For this " +
"reason, it is not possible for these scripts to run while offline (when the game is closed). " +
"It is important to note that for this reason, conditionals such as if/else statements and certain " +
"commands such as purchaseHacknetNode() or nuke() will not work while the game is offline.
" +
"However, Scripts WILL continue to generate money and hacking exp for you while the game is offline. This " +
"offline production is based off of the scripts' production while the game is online.
" +
"grow() and weaken() are two Netscript commands that will also be applied when the game is offline, although at a slower rate " +
"compared to if the game was open. This is done by having each script keep track of the " +
"rate at which the grow() and weaken() commands are called when the game is online. These calculated rates are used to determine how many times " +
"these function calls would be made while the game is offline.
" +
"Also, note that because of the way the Netscript interpreter is implemented, " +
"whenever you reload or re-open the game all of the scripts that you are running will " +
"start running from the BEGINNING of the code. The game does not keep track of where exactly " +
"the execution of a script is when it saves/loads.
",
TutorialNetscriptText: "Netscript is a programming language implemented for this game. The language has " +
"your basic programming constructs and several built-in commands that are used to hack.
" +
"The following data types are supported by Netscript: " +
"numeric - Integers and floats (eg. 6, 10.4999) " +
"string - Encapsulated by single or double quotes (eg. 'this is a string') " +
"boolean - true or false
" +
"Strings are fully functional Javascript strings, " +
"which means that all of the member functions of Javascript strings such as toLowerCase() and includes() are also " +
"available in Netscript!
" +
"To create a variable, use the assign (=) operator. The language is not strongly typed. Examples: " +
"i = 5; " +
"s = 'this game is awesome!';
" +
"In the first example above, we are creating the variable i and assigning it a value of 5. In the second, " +
"we are creating the variable s and assigning it the value of a string. Note that all expressions must be " +
"ended with a semicolon.
" +
"
Operators
" +
"The following operators are supported by Netscript: " +
" + " +
" - " +
" * " +
" / " +
" % " +
" && " +
" || " +
" < " +
" > " +
" <= " +
" >= " +
" == " +
" != " +
" ++ (Note: This ONLY pre-increments. Post-increment does not work) " +
" -- (Note: This ONLY pre-decrements. Post-decrement does not work) " +
" - (Negation operator) " +
" !
" +
"
Arrays
" +
"Netscript arrays have the same properties and functions as javascript arrays. For information see javascripts array documentation.
"+
"
Script Arguments
" +
"Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " +
"operator. (args[0], args[1], args[2]...)
" +
"For example, let's say we want to make a generic script 'generic-run.script' and we plan to pass two arguments into that script. The first argument will be the name of " +
"another script, and the second argument will be a number. This generic script will run the script specified in the first argument " +
"with the amount of threads specified in the second element. The code would look like:
" +
"run(args[0], args[1]);
" +
"It is also possible to get the number of arguments that was passed into a script using:
" +
"args.length
" +
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
"args array.
" +
"
Functions
" +
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
"you may use:
" +
"hack(hostname/ip) Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " +
"either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security level. " +
" A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. " +
"For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. A successful hack() on " +
"a server will raise that server's security level by 0.002. Returns true if the hack is successful and " +
"false otherwise. " +
"Examples: hack('foodnstuff'); or hack('148.192.0.12');
" +
"sleep(n, log=true) Suspends the script for n milliseconds. The second argument is an optional boolean that indicates " +
"whether or not the function should log the sleep action. If this argument is true, then calling this function will write " +
"'Sleeping for N milliseconds' to the script's logs. If it's false, then this function will not log anything. " +
"If this argument is not specified then it will be true by default. Example: sleep(5000);
" +
"grow(hostname/ip) Use your hacking skills to increase the amount of money available on a server. The argument passed in " +
"must be a string with either the IP or hostname of the target server. The runtime for this command depends on your hacking level and the target server's security level. " +
"When grow() completes, the money available on a target server will be increased by a certain, fixed percentage. This percentage " +
"is determined by the server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates.
" +
"Like hack(), grow() can be called on any server, regardless of where the script is running. " +
"The grow() command requires root access to the target server, but there is no required hacking level to run the command. " +
"It also raises the security level of the target server by 0.004. " +
"Returns the number by which the money on the server was multiplied for the growth. " +
"Works offline at a slower rate. Example: grow('foodnstuff');
" +
"weaken(hostname/ip) Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " +
"in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " +
"hacking level and the target server's security level. This function lowers the security level of the target server by " +
"0.05.
Like hack() and grow(), weaken() can be called on " +
"any server, regardless of where the script is running. This command requires root access to the target server, but " +
"there is no required hacking level to run the command. Returns " +
"0.1. Works offline at a slower rate Example: weaken('foodnstuff');
" +
"print(x) Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ).
" +
"tprint(x) Prints a value or a variable to the Terminal
" +
"clearLog() Clears the script's logs.
" +
"scan(hostname/ip) 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.
" +
"nuke(hostname/ip) Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline Example: nuke('foodnstuff');
" +
"brutessh(hostname/ip) Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer. Does NOT work while offline Example: brutessh('foodnstuff');
" +
"ftpcrack(hostname/ip) Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer. Does NOT work while offline Example: ftpcrack('foodnstuff');
" +
"relaysmtp(hostname/ip) Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer. Does NOT work while offline Example: relaysmtp('foodnstuff');
" +
"httpworm(hostname/ip) Run HTTPWorm.exe on the target server. HTTPWorm.exe must exist on your home computer. Does NOT work while offline Example: httpworm('foodnstuff');
" +
"sqlinject(hostname/ip) Run SQLInject.exe on the target server. SQLInject.exe must exist on your home computer. Does NOT work while offline Example: sqlinject('foodnstuff');
" +
"run(script, [numThreads], [args...]) Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " +
"be used to run scripts located on the current server (the server running the script that calls this function). The second argument " +
"is optional, and it specifies how many threads to run the script with. This argument must be a number greater than 0. If it is omitted, then the script will be run single-threaded. Any additional arguments will specify " +
"arguments to pass into the new script that is being run. If arguments are specified for the new script, then the second argument numThreads argument must be filled in with a value.
" +
"Returns true if the script is successfully started, and false otherwise. Requires a significant amount " +
"of RAM to run this command. Does NOT work while offline
" +
"The simplest way to use the run command is to call it with just the script name. The following example will run 'foo.script' single-threaded with no arguments:
" +
"run('foo.script');
" +
"The following example will run 'foo.script' but with 5 threads instead of single-threaded:
" +
"run('foo.script', 5);
" +
"The following example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script as an argument:
" +
"run('foo.script', 1, 'foodnstuff');
" +
"exec(script, hostname/ip, [numThreads], [args...]) Run a script as a separate process on another server. The first argument is the name of the script as a string. The " +
"second argument is a string with the hostname or IP of the 'target server' on which to run the script. The specified script must exist on the target server. " +
"The third argument is optional, and it specifies how many threads to run the script with. If it is omitted, then the script will be run single-threaded. " +
"This argument must be a number that is greater than 0. Any additional arguments will specify arguments to pass into the new script that is being run. If " +
"arguments are specified for the new script, then the third argument numThreads must be filled in with a value.
Returns " +
"true if the script is successfully started, and false otherwise. Does NOT work while offline
" +
"The simplest way to use the exec command is to call it with just the script name and the target server. The following example will try to run 'generic-hack.script' " +
"on the 'foodnstuff' server:
" +
"exec('generic-hack.script', 'foodnstuff');
" +
"The following example will try to run the script 'generic-hack.script' on the 'joesguns' server with 10 threads:
" +
"exec('generic-hack.script', 'joesguns', 10);
" +
"The following example will try to run the script 'foo.script' on the 'foodnstuff' server with 5 threads. It will also pass the number 1 and the string 'test' in as arguments " +
"to the script.
" +
"kill(script, hostname/ip, [args...]) Kills the script on the target server specified by the script's name and arguments. Remember that " +
"scripts are uniquely identified by both their name and arguments. For example, if 'foo.script' is run with the argument 1, then this is not the " +
"same as 'foo.script' run with the argument 2, even though they have the same code.
" +
"The first argument must be a string with the name of the script. The name is case-sensitive. " +
"The second argument must be a string with the hostname or IP of the target server. Any additional arguments to the function will specify the arguments passed " +
"into the script that should be killed.
The function will try to kill the specified script on the target server. " +
"If the script is found on the specified server and is running, then it will be killed and this function " +
"will return true. Otherwise, this function will return false.
" +
"Examples: " +
"If you are trying to kill a script named 'foo.script' on the 'foodnstuff' server that was ran with no arguments, use this:
" +
"kill('foo.script', 'foodnstuff');
" +
"If you are trying to kill a script named 'foo.script' on the current server that was ran with no arguments, use this:
" +
"kill('foo.script', getHostname());
" +
"If you are trying to kill a script named 'foo.script' on the current server that was ran with the arguments 1 and 'foodnstuff', use this:
" +
"killall(hostname/ip) 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.
" +
"scp(script, hostname/ip) 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. Example: scp('hack-template.script', 'foodnstuff');
" +
"hasRootAccess(hostname/ip) 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. " +
"Example: if (hasRootAccess('foodnstuff') == false) { nuke('foodnstuff'); }
" +
"getHostname() Returns a string with the hostname of the server that the script is running on
" +
"getHackingLevel() Returns the Player's current hacking level. Does NOT work while offline
" +
"getServerMoneyAvailable(hostname/ip) 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 Example: getServerMoneyAvailable('foodnstuff');
" +
"getServerMaxMoney(hostname/ip) Returns the maximum amount of money that can be available on a server. The argument passed in must be a string with " +
"the hostname or IP of the target server. Does NOT work while offline Example: getServerMaxMoney('foodnstuff');
" +
"getServerGrowth(hostname/ip) Returns the server's intrinsic 'growth parameter'. This growth parameter is a number " +
"between 1 and 100 that represents how quickly the server's money grows. This parameter affects the percentage by which this server's " +
"money is increased when using the grow() function. A higher growth parameter will result in a higher percentage from grow().
" +
"The argument passed in must be a string with the hostname or IP of the target server.
" +
"getServerSecurityLevel(hostname/ip) Returns the security level of a server. The argument passed in must be a string with either the " +
"hostname or IP of the target server. A server's security is denoted by a number between 1 and 100. Does NOT work while offline.
" +
"getServerBaseSecurityLevel(hostname/ip) Returns the base security level of a server. This is the security level that the server starts out with. " +
"This is different than getServerSecurityLevel() because getServerSecurityLevel() returns the current security level of a server, which can constantly change " +
"due to hack(), grow(), and weaken() calls on that server. The base security level will stay the same until you reset by installing an Augmentation.
" +
"The argument passed in must be a string with either the hostname or IP of the target server. A server's base security is denoted by a number between 1 and 100. " +
"Does NOT work while offline.
" +
"getServerRequiredHackingLevel(hostname/ip) Returns the required hacking level of a server. The argument passed in must be a string with either the " +
"hostname or IP or the target server. Does NOT work while offline
" +
"getServerNumPortsRequired(hostname/ip) Returns the number of open ports required to successfully run NUKE.exe 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
" +
"getServerRam(hostname/ip) 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.
" +
"fileExists(filename, [hostname/ip]) 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.
" +
"The second argument is a string with the hostname or IP of the server on which to search for the program. This second argument is optional. " +
"If it is omitted, then the function will search through the current server (the server running the script that calls this function) for the file. " +
"Example: fileExists('foo.script', 'foodnstuff'); " +
"Example: fileExists('ftpcrack.exe');
" +
"The first example above will return true if the script named 'foo.script' exists on the 'foodnstuff' server, and false otherwise. The second example above will " +
"return true if the current server (the server on which this function runs) contains the FTPCrack.exe program, and false otherwise.
" +
"isRunning(filename, hostname/ip, [args...]) Returns a boolean (true or false) indicating whether the specified script is running on a server. " +
"Remember that a script is uniquely identified by both its name and its arguments.
" +
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is a string with the " +
"hostname or IP of the target server. Any additional arguments passed to the function will specify the arguments passed into the target script. " +
"The function will check whether the script is running on that target server. " +
"Example: isRunning('foo.script', 'foodnstuff'); " +
"Example: isRunning('foo.script', getHostname()); " +
"Example: isRunning('foo.script', 'joesguns', 1, 5, 'test');
" +
"The first example above will return true if there is a script named 'foo.script' with no arguments running on the 'foodnstuff' server, and false otherwise. The second " +
"example above will return true if there is a script named 'foo.script' with no arguments running on the current server, and false otherwise. " +
"The third example above will return true if there is a script named 'foo.script' with the arguments 1, 5, and 'test' running on the 'joesguns' server, and " +
"false otherwise.
" +
"getNextHacknetNodeCost() Returns the cost of purchasing a new Hacknet Node
" +
"purchaseHacknetNode() Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " +
"at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " +
"a new Hacknet Node then the function will return false. Does NOT work offline
" +
"purchaseServer(hostname, ram) Purchases a server with the specified hostname and amount of RAM. The first argument can be any data type, " +
"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...).
" +
"Purchasing a server using this Netscript function is twice as expensive as manually purchasing a server from a location in the World.
" +
"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.
" +
"round(n) Rounds the number n to the nearest integer. If the argument passed in is not a number, then the function will return 0.
" +
"write(port, data) 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.
" +
"read(port) Reads data from a port. The first argument must be a number between 1 and 10 that specifies the port. A port is a serialized queue. " +
"This function will remove the first element from the queue and return it. If the queue is empty, then the string 'NULL PORT DATA' will be returned.
" +
"scriptRunning(scriptname, hostname/ip) Returns a boolean indicating whether any instance of the specified script is running " +
"on a server, regardless of its arguments. This is different than the isRunning() function because it does not " +
"try to identify a specific instance of a running script by its arguments.
" +
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " +
"a string with the hostname or IP of the target server. Both arguments are required.
" +
"scriptKill(scriptname, hostname/ip) Kills all scripts with the specified filename that are running on the server specified by the " +
"hostname/ip, regardless of arguments. Returns true if one or more scripts were successfully killed, and false if there were none.
" +
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " +
"a string with the hostname or IP of the target server. Both arguments are required.
" +
"getScriptRam(scriptname, hostname/ip) Returns the amount of RAM required to run the specified script on the " +
"target server. The first argument must be a string with the name of the script. The script name is case sensitive. " +
"The second argument is a string with the hostname or IP of the server where that script is. Both arguments are required.
" +
"getHackTime(hostname/ip) Returns the amount of time in seconds it takes to execute the hack() Netscript function " +
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.
" +
"getGrowTime(hostname/ip) Returns the amount of time in seconds it takes to execute the grow() Netscript function " +
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.
" +
"getWeakenTime(hostname/ip) 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.
" +
"
Hacknet Nodes API
" +
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.
" +
"hacknetnodes A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
"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].
" +
"hacknetnodes.length Returns the number of Hacknet Nodes that the player owns
" +
"hacknetnodes[i].level Returns the level of the corresponding Hacknet Node
" +
"hacknetnodes[i].ram Returns the amount of RAM on the corresponding Hacknet Node
" +
"hacknetnodes[i].cores Returns the number of cores on the corresponding Hacknet Node
" +
"hacknetnodes[i].upgradeLevel(n) 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.
" +
"hacknetnodes[i].upgradeRam() Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
"RAM is successfully upgraded, and false otherwise.
" +
"hacknetnodes[i].upgradeCore() Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
"additional core is successfully purchase, and false otherwise.
" +
"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 " +
"to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.
" +
"getStockPrice(sym) Returns the price of a stock. The argument passed in must be the stock's symbol (NOT THE COMPANY NAME!). The symbol " +
"is a sequence of two to four capital letters. The symbol argument must be a string.
" +
"Example: getStockPrice('FSIG');
" +
"getStockPosition(sym) Returns an array of two elements that represents the player's position in a stock. The first element " +
"in the array is the number of shares the player owns of the specified stock. The second element in the array is the average price of the player's " +
"shares. Both elements are numbers. The argument passed in must be the stock's symbol, which is a sequence of two to four capital letters.
"+
"buyStock(sym, shares) Attempts to purchase shares of a stock. The first argument must be a string with the stock's symbol. The second argument " +
"must be the number of shares to purchase.
" +
"If the player does not have enough money to purchase specified number of shares, then no shares will be purchased (it will not purchase the most you can afford). " +
"Remember that every transaction on the stock exchange costs a certain commission fee.
" +
"The function will return true if it successfully purchases the specified number of shares of stock, and false otherwise.
" +
"sellStock(sym, shares) Attempts to sell shares of a stock. The first argument must be a string with the stock's symbol. The second argument " +
"must be the number of shares to sell.
" +
"If the specified number of shares in the function exceeds the amount that the player actually owns, then this function will sell all owned shares. " +
"Remember that every transaction on the stock exchange costs a certain commission fee.
" +
"The net profit made from selling stocks with this function is reflected in the script's statistics. This net profit is calculated as:
" +
"shares * (sell price - average price of purchased shares)
" +
"This function will return true if the shares of stock are successfully sold and false otherwise.
" +
"
While loops
" +
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met.
" +
"while ([cond]) { [code] }
" +
"As long as [cond] remains true, the code block [code] will continuously execute. Example:
" +
"i = 0; while (i < 10) { hack('foodnstuff'); i = i + 1; }
" +
"This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits.
" +
"while(true) { hack('foodnstuff'); }
" +
"This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " +
"Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code
" +
"
For loops
" +
"A for loop is another control flow statement that allows code to be repeated by iterations. The structure is:
" +
"for ([init]; [cond]; [post]) { code }
" +
"The [init] expression evaluates before the for loop begins. The for loop will continue to execute " +
"as long as [cond] is met. The [post] expression will evaluate at the end of every iteration " +
"of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " +
" using a for loop:
" +
"for (i = 0; i < 10; i = i++) { hack('foodnstuff'); }
" +
"
If statements
" +
"If/Else if/Else statements are conditional statements used to perform different actions based on different conditions:
" +
"In the code above, first condition1 will be checked. If this condition is true, then code1 will execute and the " +
"rest of the if/else if/else statement will be skipped. If condition1 is NOT true, then the code will then go on to check " +
"condition2. If condition2 is true, then code2 will be executed, and the rest of the if/else if/else statement " +
"will be skipped. If none of the conditions are true, then the code within the else block (code3) will be executed. " +
"Note that a conditional statement can have any number of 'else if' statements.
" +
"The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " +
"If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " +
"then the code will call grow('foodnstuff') instead and add more money to the server.
",
TutorialSingularityFunctionsText: "
Singularity Functions
" +
"The Singularity Functions are a special set of Netscript functions that are unlocked in BitNode-4. " +
"These functions allow you to control many additional aspects of the game through scripts, such as " +
"working for factions/companies, purchasing/installing Augmentations, and creating programs.
" +
"If you are in BitNode-4, then you will automatically have access to all of these functions. " +
"You can use the Singularity Functions in other BitNodes if and only if you have the Source-File " +
"for BitNode-4 (aka Source-File 4). Each level of Source-File 4 will open up additional Singularity " +
"Functions that you can use in other BitNodes. If your Source-File 4 is upgraded all the way to level 3, " +
"then you will be able to access all of the Singularity Functions.
" +
"Note that Singularity Functions require a lot of RAM outside of BitNode-4 (their RAM costs are multiplied by " +
"10 if you are not in BitNode-4).
" +
"universityCourse(universityName, courseName) " +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
" +
"This function will automatically set you to start taking a course at a university. If you are already " +
"in the middle of some 'working' action (such as working at a company, for a faction, or on a program), " +
"then running this function will automatically cancel that action and give you your earnings.
" +
"The first argument must be a string with the name of the university. The names are NOT case-sensitive. " +
"Note that you must be in the correct city for whatever university you specify. The three universities are:
" +
"Summit University Rothman University ZB Institute of Technology
" +
"The second argument must be a string with the name of the course you are taking. These names are NOT case-sensitive. " +
"The available courses are:
" +
"The cost and experience gains for all of these universities and classes are the same as if you were to manually " +
"visit and take these classes.
" +
"This function will return true if you successfully start taking the course, and false otherwise.
" +
"gymWorkout(gymName, stat) " +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
" +
"This function will automatically set you to start working out at a gym to train a particular stat. If you are " +
"already in the middle of some 'working' action (such as working at a company, for a faction, or on a program), then " +
"running this function will automatically cancel that action and give you your earnings.
" +
"The first argument must be a string with the name of the gym. The names are NOT case-sensitive. Note that you must " +
"be in the correct city for whatever gym you specify. The available gyms are:
" +
"The second argument must be a string with the stat you want to work out. These are NOT case-sensitive. " +
"The valid stats are:
strength OR str defense OR def dexterity OR dex agility OR agi
" +
"The cost and experience gains for all of these gyms are the same as if you were to manually visit these gyms and train " +
"This function will return true if you successfully start working out at the gym, and false otherwise.
" +
"travelToCity(cityname) " +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
" +
"This function allows the player to travel to any city. The cost for using this function is the same as the cost for traveling through the Travel Agency.
" +
"The argument passed into this must be a string with the name of the city to travel to. Note that this argument IS CASE SENSITIVE. The valid cities are:
" +
"Aevum Chongqing Sector-12 New Tokyo Ishima Volhaven
" +
"This function will return true if you successfully travel to the specified city and false otherwise.
" +
"purchaseTor() " +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
" +
"This function allows you to automatically purchase a TOR router. The cost for purchasing a TOR router using this " +
"function is the same as if you were to manually purchase one.
" +
"This function will return true if it successfully purchase a TOR router and false otherwise.
" +
"purchaseProgram(programName) " +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
" +
"This function allows you to automatically purchase programs. You MUST have a TOR router in order to use this function.
" +
"The argument passed in must be a string with the name of the program (including the '.exe' extension). This argument is " +
"NOT case-sensitive.
Example: " +
"purchaseProgram('brutessh.exe');
" +
"The cost of purchasing programs using this function is the same as if you were purchasing them through the Dark Web (using " +
"the buy Terminal command).
" +
"This function will return true if the specified program is purchased, and false otherwise.
" +
"upgradeHomeRam() " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually.
" +
"This function will return true if the player's home computer RAM is successfully upgraded, and false otherwise.
" +
"getUpgradeHomeRamCost() " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"Returns the cost of upgrading the player's home computer RAM.
" +
"workForCompany() " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function will automatically set you to start working at the company at which you are employed. If you are already " +
"in the middle of some 'working' action (such as working for a faction, training at a gym, or creating a program), then " +
"running this function will automatically cancel that action and give you your earnings.
" +
"This function will return true if the player starts working, and false otherwise.
" +
"applyToCompany(companyName, field) " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function will automatically try to apply to the specified company for a position in the specified field. This " +
"function can also be used to apply for promotions by specifying the company and field you are already employed at.
" +
"The first argument must be a string with the name of the company. This argument IS CASE-SENSITIVE. The second argument must " +
"be a string representing the 'field' to which you want to apply. This second argument is NOT case-sensitive. Valid values for " +
"the second argument are:
" +
"software software consultant it security engineer network engineer business business consultant " +
"security agent employee part-time employee waiter part-time waiter
" +
"This function will return true if you successfully get a job/promotion, and false otherwise. Note " +
"that if you are trying to use this function to apply for a promotion and you don't get one, it will return false.
" +
"getCompanyRep(companyName) " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function will return the amount of reputation you have at the specified company. If the company passed in as " +
"an argument is invalid, -1 will be returned.
" +
"The argument passed in must be a string with the name of the company. This argument IS CASE-SENSITIVE.
" +
"checkFactionInvitations() " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"Returns an array with the name of all Factions you currently have oustanding invitations from.
" +
"joinFaction(name) " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function will automatically accept an invitation from a faction and join it.
" +
"The argument must be a string with the name of the faction. This name IS CASE-SENSITIVE.
" +
"workForFaction(factionName, workType) " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function will automatically set you to start working for the specified Faction. Obviously, you " +
"must be a member of the Faction or else this function will fail. If you are already in the middle of " +
"some 'working' action (such as working for a company, training at a gym, or creating a program), then running " +
"this function will automatically cancel that action and give you your earnings.
" +
"The first argument must be a string with the name of the faction. This argument IS CASE-SENSITIVE. The second argument " +
"must be a string with the type of work you want to perform for the faction. The valid values for this argument are:
" +
" hacking/hacking contracts/hackingcontracts field/fieldwork/field work security/securitywork/security work
" +
"This function will return true if you successfully start working for the specified faction, and false otherwise.
" +
"getFactionRep(factionName) " +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
" +
"This function returns the amount of reputation you have for the specified Faction. The argument must be a " +
"string with the name of the Faction. The argument IS CASE-SENSITIVE.
" +
"createProgram(programName) " +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
" +
"This function will automatically set you to start working on creating the specified program. If you are already in " +
"the middle of some 'working' action (such as working for a company, training at a gym, or taking a course), then " +
"running this function will automatically cancel that action and give you your earnings.
" +
"The argument passed in must be a string designating the name of the program. This argument is NOT case-sensitive.
" +
"Example:
createProgram('relaysmtp.exe');
" +
"Note that creating a program using this function has the same hacking level requirements as it normally would. These level requirements are:
" +
"This function returns true if you successfully start working on the specified program, and false otherwise.
" +
"getAugmentationCost(augName) " +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
" +
"This function returns an array with two elements that gives the cost for the specified Augmentation" +
". The first element in the returned array is the reputation requirement of the Augmentation, and the second element " +
"is the money cost.
" +
"The argument passed in must be a string with the name of the Augmentation. This argument IS CASE-SENSITIVE. " +
"If an invalid Augmentation name is passed in, this function will return the array [-1, -1].
" +
"purchaseAugmentation(factionName, augName) " +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
" +
"This function will try to purchase the specified Augmentation through the given Faction.
" +
"The two arguments must be strings specifying the name of the Faction and Augmentation, respectively. These arguments are both CASE-SENSITIVE.
" +
"This function will return true if the Augmentation is successfully purchased, and false otherwise.
" +
"installAugmentations() " +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
" +
"This function will automatically install your Augmentations, resetting the game as usual.
" +
"It will return true if successful, and false otherwise.",
TutorialTravelingText:"There are six major cities in the world that you are able to travel to:
" +
"To travel between cities, visit your current city's travel agency through the 'World' page. " +
"From the travel agency you can travel to any other city. Doing so costs money.
" +
"Each city has its own set of companies and unique locations. Also, certain content is only available to you " +
"if you are in certain cities, so get exploring!",
TutorialCompaniesText: "Hacking is not the only way to gain money and experience! Located around the world are many " +
"different companies which you can work for. By working for a company you can earn money, " +
"train your various labor skills, and unlock powerful passive perks.
" +
"To apply for a job, visit the company you want to work for through the 'World' menu. The company " +
"page will have options that let you apply to positions in the company. There might be several different " +
"positions you can apply for, ranging from software engineer to business analyst to security officer.
" +
"When you apply for a job, you will get the offer if your stats are high enough. Your first position at " +
"a company will be an entry-level position such as 'intern'. Once you get the job, an button will appear on " +
"the company page that allows you to work for the company. Click this button to start working.
" +
"Working occurs in 8 hour shifts. Once you start working, you will begin earning money, experience, " +
"and reputation. The rate at which you money and experience depends on the company and your position. " +
"The amount of reputation you gain for your company is based on your job performance, which is affected by " +
"your stats. Different positions value different stats. When you are working, you are unable to perform any " +
"other actions such as using your terminal or visiting other locations (However, note that any scripts you have " +
"running on servers will continue to run as you work!). It is possible to cancel your work shift before the " +
"8 hours is up. However, if you have a full-time job, then cancelling a shift early will result in you gaining " +
"only half of the reputation " +
"that you had earned up to that point. There are also part-time/consultant jobs available where you will not " +
" be penalized if you cancel a work shift early. However, these positions pay less than full-time positions.
" +
"As you continue to work at a company, you will gain more and more reputation at that company. When your stats " +
"and reputation are high enough, you can get a promotion. You can apply for a promotion on the company page, just like " +
"you applied for the job originally. Higher positions at a company provide better salaries and stat gains.
" +
"
Infiltrating Companies
" +
"Many companies have facilities that you can attempt to infiltrate. By infiltrating, you can steal classified company secrets " +
"and then sell these for money or for faction reputation. To try and infiltrate a company, visit a company through the " +
"'World' menu. There will be an option that says 'Infiltrate Company'.
" +
"When infiltrating a company, you must progress through clearance levels in the facility. Every clearance level " +
"has some form of security that you must get past. There are several forms of security, ranging from high-tech security systems to " +
"armed guards. For each form of security, there are a variety of options that you can choose to try and bypass the security. Examples " +
"include hacking the security, engaging in combat, assassination, or sneaking past the security. The chance to succeed for each option " +
"is determined in part by your stats. So, for example, trying to hack the security system relies on your hacking skill, whereas trying to " +
"sneak past the security relies on your agility level.
" +
"The facility has a 'security level' that affects your chance of success when trying to get past a clearance level. " +
"Every time you advance to the next clearance level, the facility's security level will increase by a fixed amount. Furthermore " +
"the options you choose and whether you succeed or fail will affect the security level as well. For example, " +
"if you try to kill a security guard and fail, the security level will increase by a lot. If you choose to sneak past " +
"security and succeed, the security level will not increase at all.
" +
"Every 5 clearance levels, you will steal classified company secrets that can be sold for money or faction reputation. However, " +
"in order to sell these secrets you must successfully escape the facility using the 'Escape' option. Furthermore, companies have " +
"a max clearance level. If you reach the max clearance level you will automatically escape the facility with all of your " +
"stolen secrets.
",
TutorialFactionsText: "Throughout the game you may receive invitations from factions. There are many different factions, and each faction " +
"has different criteria for determining its potential members. Joining a faction and furthering its cause is crucial " +
"to progressing in the game and unlocking endgame content.
" +
"It is possible to join multiple factions if you receive invitations from them. However, note that joining a faction " +
"may prevent you from joining other rival factions.
" +
"The 'Factions' link on the menu brings up a list of all factions that you have joined. " +
"You can select a Faction on this list to go to that Faction page. This page displays general " +
"information about the Faction and also lets you perform work for the faction. " +
"Working for a Faction is similar to working for a company except that you don't get paid a salary. " +
"You will only earn reputation in your Faction and train your stats. Also, cancelling work early " +
"when working for a Faction does NOT result in reduced experience/reputation earnings.
" +
"Earning reputation for a Faction unlocks powerful Augmentations. Purchasing and installing these Augmentations will " +
"upgrade your abilities. The Augmentations that are available to unlock vary from faction to faction.",
TutorialAugmentationsText: "Advances in science and medicine have lead to powerful new technologies that allow people to augment themselves " +
"beyond normal human capabilities. There are many different types of Augmentations, ranging from cybernetic to " +
"genetic to biological. Acquiring these Augmentations enhances the user's physical and mental faculties.
" +
"Because of how powerful these Augmentations are, the technology behind them is kept private and secret by the " +
"corporations and organizations that create them. Therefore, the only way for the player to obtain Augmentations is " +
"through Factions. After joining a Faction and earning enough reputation in it, you will be able to purchase " +
"its Augmentations. Different Factions offer different Augmentations. Augmentations must be purchased in order to be installed, " +
"and they are fairly expensive.
" +
"When you purchase an Augmentation, the price of purchasing another Augmentation increases by 90%. This multiplier stacks for " +
"each Augmentation you purchase. You will not gain the benefits of your purchased Augmentations until you install them. You can " +
"choose to install Augmentations through the 'Augmentations' menu tab. Once you install your purchased Augmentations, " +
"their costs are reset back to the original price.
" +
"Unfortunately, installing Augmentations has side effects. You will lose most of the progress you've made, including your " +
"skills, stats, and money. You will have to start over, but you will have all of the Augmentations you have installed to " +
"help you progress.
" +
"To summarize, here is a list of everything you will LOSE when you install an Augmentation:
" +
"Stats/Skills " +
"Money " +
"Scripts on all servers EXCEPT your home computer " +
"Purchased servers " +
"Hacknet Nodes " +
"Company/faction reputation " +
"Jobs and Faction memberships " +
"Programs " +
"Stocks " +
"TOR router
" +
"Here is everything you will KEEP when you install an Augmentation:
" +
"Every Augmentation you have installed " +
"Scripts on your home computer " +
"RAM Upgrades on your home computer " +
"World Stock Exchange account and TIX API Access ",
LatestUpdate:
"v0.28.1 " +
"-The script editor now uses the open-source Ace editor, which provides a much better experience when coding! " +
"-Added tprint() Netscript function
" +
"v0.28.0 " +
"-Added BitNode-4: The Singularity " +
"-Added BitNode-11: The Big Crash " +
"-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)"
}
/***/ }),
/* 4 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Engine", function() { return Engine; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_DialogBox_js__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_GameOptions_js__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_HelperFunctions_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_StringHelperFunctions_js__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_LogBox_js__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__ActiveScriptsUI_js__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Augmentations_js__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__BitNode_js__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Company_js__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__CreateProgram_js__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__Faction_js__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__Location_js__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__Gang_js__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__HacknetNode_js__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__InteractiveTutorial_js__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__Literature_js__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__Message_js__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__NetscriptFunctions_js__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__NetscriptWorker_js__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__Player_js__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__Prestige_js__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__RedPill_js__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24__SaveObject_js__ = __webpack_require__(58);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_25__Script_js__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_26__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_27__Settings_js__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_28__SourceFile_js__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29__SpecialServerIps_js__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_30__StockMarket_js__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_31__Terminal_js__ = __webpack_require__(19);
var ace = __webpack_require__(33);
__webpack_require__(35);
__webpack_require__(36);
__webpack_require__(49);
__webpack_require__(50);
/* Shortcuts to navigate through the game
* Alt-t - Terminal
* Alt-c - Character
* Alt-e - Script editor
* Alt-s - Active scripts
* Alt-h - Hacknet Nodes
* Alt-w - City
* Alt-j - Job
* Alt-r - Travel Agency of current city
* Alt-p - Create program
* Alt-f - Factions
* Alt-a - Augmentations
* Alt-u - Tutorial
* Alt-o - Options
*/
$(document).keydown(function(e) {
if (!__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].isWorking && !__WEBPACK_IMPORTED_MODULE_23__RedPill_js__["b" /* redPillFlag */]) {
if (e.keyCode == 84 && e.altKey) {
e.preventDefault();
Engine.loadTerminalContent();
} else if (e.keyCode == 67 && e.altKey) {
e.preventDefault();
Engine.loadCharacterContent();
} else if (e.keyCode == 69 && e.altKey) {
e.preventDefault();
Engine.loadScriptEditorContent();
} else if (e.keyCode == 83 && e.altKey) {
e.preventDefault();
Engine.loadActiveScriptsContent();
} else if (e.keyCode == 72 && e.altKey) {
e.preventDefault();
Engine.loadHacknetNodesContent();
} else if (e.keyCode == 87 && e.altKey) {
e.preventDefault();
Engine.loadWorldContent();
} else if (e.keyCode == 74 && e.altKey) {
e.preventDefault();
Engine.loadJobContent();
} else if (e.keyCode == 82 && e.altKey) {
e.preventDefault();
Engine.loadTravelContent();
} else if (e.keyCode == 80 && e.altKey) {
e.preventDefault();
Engine.loadCreateProgramContent();
} else if (e.keyCode == 70 && e.altKey) {
e.preventDefault();
Engine.loadFactionsContent();
} else if (e.keyCode == 65 && e.altKey) {
e.preventDefault();
Engine.loadAugmentationsContent();
} else if (e.keyCode == 85 && e.altKey) {
e.preventDefault();
Engine.loadTutorialContent();
}
}
if (e.keyCode == 79 && e.altKey) {
e.preventDefault();
Object(__WEBPACK_IMPORTED_MODULE_1__utils_GameOptions_js__["b" /* gameOptionsBoxOpen */])();
}
});
let Engine = {
version: "",
Debug: true,
//Clickable objects
Clickables: {
//Main menu buttons
terminalMainMenuButton: null,
characterMainMenuButton: null,
scriptEditorMainMenuButton: null,
activeScriptsMainMenuButton: null,
hacknetNodesMainMenuButton: null,
worldMainMenuButton: null,
travelMainMenuButton: null,
jobMainMenuButton: null,
createProgramMainMenuButton: null,
factionsMainMenuButton: null,
augmentationsMainMenuButton: null,
tutorialMainMenuButton: null,
saveMainMenuButton: null,
deleteMainMenuButton: null,
//Tutorial buttons
tutorialNetworkingButton: null,
tutorialHackingButton: null,
tutorialScriptsButton: null,
tutorialNetscriptButton: null,
tutorialTravelingButton: null,
tutorialCompaniesButton: null,
tutorialFactionsButton: null,
tutorialAugmentationsButton: null,
tutorialBackButton: null,
},
//Display objects
Display: {
//Progress bar
progress: null,
//Display for status text (such as "Saved" or "Loaded")
statusText: null,
hacking_skill: null,
//Main menu content
terminalContent: null,
characterContent: null,
scriptEditorContent: null,
activeScriptsContent: null,
hacknetNodesContent: null,
worldContent: null,
createProgramContent: null,
factionsContent: null,
factionContent: null,
factionAugmentationsContent: null,
augmentationsContent: null,
tutorialContent: null,
infiltrationContent: null,
stockMarketContent: null,
locationContent: null,
workInProgressContent: null,
redPillContent: null,
//Character info
characterInfo: null,
},
//Current page status
Page: {
Terminal: "Terminal",
CharacterInfo: "CharacterInfo",
ScriptEditor: "ScriptEditor",
ActiveScripts: "ActiveScripts",
HacknetNodes: "HacknetNodes",
World: "World",
CreateProgram: "CreateProgram",
Factions: "Factions",
Faction: "Faction",
Augmentations: "Augmentations",
Tutorial: "Tutorial",
Location: "Location",
workInProgress: "WorkInProgress",
RedPill: "RedPill",
Infiltration: "Infiltration",
StockMarket: "StockMarket",
Gang: "Gang",
},
currentPage: null,
//Time variables (milliseconds unix epoch time)
_lastUpdate: new Date().getTime(),
_idleSpeed: 200, //Speed (in ms) at which the main loop is updated
/* Load content when a main menu button is clicked */
loadTerminalContent: function() {
Engine.hideAllContent();
Engine.Display.terminalContent.style.visibility = "visible";
Engine.currentPage = Engine.Page.Terminal;
document.getElementById("terminal-menu-link").classList.add("active");
},
loadCharacterContent: function() {
Engine.hideAllContent();
Engine.Display.characterContent.style.visibility = "visible";
Engine.displayCharacterInfo();
Engine.currentPage = Engine.Page.CharacterInfo;
document.getElementById("stats-menu-link").classList.add("active");
},
loadScriptEditorContent: function(filename = "", code = "") {
Engine.hideAllContent();
Engine.Display.scriptEditorContent.style.visibility = "visible";
var editor = ace.edit('javascript-editor');
if (filename != "") {
document.getElementById("script-editor-filename").value = filename;
editor.setValue(code);
}
editor.focus();
Object(__WEBPACK_IMPORTED_MODULE_25__Script_js__["f" /* updateScriptEditorContent */])();
Engine.currentPage = Engine.Page.ScriptEditor;
document.getElementById("create-script-menu-link").classList.add("active");
},
loadActiveScriptsContent: function() {
Engine.hideAllContent();
Engine.Display.activeScriptsContent.style.visibility = "visible";
Object(__WEBPACK_IMPORTED_MODULE_6__ActiveScriptsUI_js__["c" /* setActiveScriptsClickHandlers */])();
Engine.currentPage = Engine.Page.ActiveScripts;
document.getElementById("active-scripts-menu-link").classList.add("active");
},
loadHacknetNodesContent: function() {
Engine.hideAllContent();
Engine.Display.hacknetNodesContent.style.visibility = "visible";
Object(__WEBPACK_IMPORTED_MODULE_15__HacknetNode_js__["a" /* displayHacknetNodesContent */])();
Engine.currentPage = Engine.Page.HacknetNodes;
document.getElementById("hacknet-nodes-menu-link").classList.add("active");
},
loadWorldContent: function() {
Engine.hideAllContent();
Engine.Display.worldContent.style.visibility = "visible";
Engine.displayWorldInfo();
Engine.currentPage = Engine.Page.World;
document.getElementById("city-menu-link").classList.add("active");
},
loadCreateProgramContent: function() {
Engine.hideAllContent();
Engine.Display.createProgramContent.style.visibility = "visible";
Object(__WEBPACK_IMPORTED_MODULE_11__CreateProgram_js__["b" /* displayCreateProgramContent */])();
Engine.currentPage = Engine.Page.CreateProgram;
document.getElementById("create-program-menu-link").classList.add("active");
},
loadFactionsContent: function() {
Engine.hideAllContent();
Engine.Display.factionsContent.style.visibility = "visible";
Engine.displayFactionsInfo();
Engine.currentPage = Engine.Page.Factions;
document.getElementById("factions-menu-link").classList.add("active");
},
loadFactionContent: function() {
Engine.hideAllContent();
Engine.Display.factionContent.style.visibility = "visible";
Engine.currentPage = Engine.Page.Faction;
},
loadAugmentationsContent: function() {
Engine.hideAllContent();
Engine.Display.augmentationsContent.style.visibility = "visible";
Engine.displayAugmentationsContent();
Engine.currentPage = Engine.Page.Augmentations;
document.getElementById("augmentations-menu-link").classList.add("active");
},
loadTutorialContent: function() {
Engine.hideAllContent();
Engine.Display.tutorialContent.style.visibility = "visible";
Engine.displayTutorialContent();
Engine.currentPage = Engine.Page.Tutorial;
document.getElementById("tutorial-menu-link").classList.add("active");
},
loadLocationContent: function() {
Engine.hideAllContent();
Engine.Display.locationContent.style.visibility = "visible";
Object(__WEBPACK_IMPORTED_MODULE_13__Location_js__["b" /* displayLocationContent */])();
Engine.currentPage = Engine.Page.Location;
},
loadTravelContent: function() {
switch(__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].city) {
case __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].Aevum:
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].AevumTravelAgency;
break;
case __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].Chongqing:
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].ChongqingTravelAgency;
break;
case __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].Sector12:
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].Sector12TravelAgency;
break;
case __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].NewTokyo:
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].NewTokyoTravelAgency;
break;
case __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].Ishima:
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].IshimaTravelAgency;
break;
case __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].Volhaven:
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_13__Location_js__["a" /* Locations */].VolhavenTravelAgency;
break;
default:
Object(__WEBPACK_IMPORTED_MODULE_0__utils_DialogBox_js__["a" /* dialogBoxCreate */])("ERROR: Invalid city. This is a bug please contact game dev");
break;
}
Engine.loadLocationContent();
},
loadJobContent: function() {
if (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].companyName == "") {
Object(__WEBPACK_IMPORTED_MODULE_0__utils_DialogBox_js__["a" /* dialogBoxCreate */])("You do not currently have a job! You can visit various companies " +
"in the city and try to find a job.");
return;
}
__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].location = __WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].companyName;
Engine.loadLocationContent();
},
loadWorkInProgressContent: function() {
Engine.hideAllContent();
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden";
Engine.Display.workInProgressContent.style.visibility = "visible";
Engine.currentPage = Engine.Page.WorkInProgress;
},
loadRedPillContent: function() {
Engine.hideAllContent();
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden";
Engine.Display.redPillContent.style.visibility = "visible";
Engine.currentPage = Engine.Page.RedPill;
},
loadInfiltrationContent: function() {
Engine.hideAllContent();
Engine.Display.infiltrationContent.style.visibility = "visible";
Engine.currentPage = Engine.Page.Infiltration;
},
loadStockMarketContent: function() {
Engine.hideAllContent();
Engine.Display.stockMarketContent.style.visibility = "visible";
Object(__WEBPACK_IMPORTED_MODULE_30__StockMarket_js__["c" /* displayStockMarketContent */])();
Engine.currentPage = Engine.Page.StockMarket;
},
loadGangContent: function() {
Engine.hideAllContent();
if (document.getElementById("gang-container") || __WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].inGang()) {
Object(__WEBPACK_IMPORTED_MODULE_14__Gang_js__["c" /* displayGangContent */])();
Engine.currentPage = Engine.Page.Gang;
} else {
Engine.loadTerminalContent();
Engine.currentPage = Engine.Page.Terminal;
}
},
//Helper function that hides all content
hideAllContent: function() {
Engine.Display.terminalContent.style.visibility = "hidden";
Engine.Display.characterContent.style.visibility = "hidden";
Engine.Display.scriptEditorContent.style.visibility = "hidden";
Engine.Display.activeScriptsContent.style.visibility = "hidden";
Engine.Display.hacknetNodesContent.style.visibility = "hidden";
Engine.Display.worldContent.style.visibility = "hidden";
Engine.Display.createProgramContent.style.visibility = "hidden";
Engine.Display.factionsContent.style.visibility = "hidden";
Engine.Display.factionContent.style.visibility = "hidden";
Engine.Display.factionAugmentationsContent.style.visibility = "hidden";
Engine.Display.augmentationsContent.style.visibility = "hidden";
Engine.Display.tutorialContent.style.visibility = "hidden";
Engine.Display.locationContent.style.visibility = "hidden";
Engine.Display.workInProgressContent.style.visibility = "hidden";
Engine.Display.redPillContent.style.visibility = "hidden";
Engine.Display.infiltrationContent.style.visibility = "hidden";
Engine.Display.stockMarketContent.style.visibility = "hidden";
if (document.getElementById("gang-container")) {
document.getElementById("gang-container").style.visibility = "hidden";
}
//Location lists
Engine.aevumLocationsList.style.display = "none";
Engine.chongqingLocationsList.style.display = "none";
Engine.sector12LocationsList.style.display = "none";
Engine.newTokyoLocationsList.style.display = "none";
Engine.ishimaLocationsList.style.display = "none";
Engine.volhavenLocationsList.style.display = "none";
//Make nav menu tabs inactive
document.getElementById("terminal-menu-link").classList.remove("active");
document.getElementById("create-script-menu-link").classList.remove("active");
document.getElementById("active-scripts-menu-link").classList.remove("active");
document.getElementById("create-program-menu-link").classList.remove("active");
document.getElementById("stats-menu-link").classList.remove("active");
document.getElementById("factions-menu-link").classList.remove("active");
document.getElementById("augmentations-menu-link").classList.remove("active");
document.getElementById("hacknet-nodes-menu-link").classList.remove("active");
document.getElementById("city-menu-link").classList.remove("active");
document.getElementById("tutorial-menu-link").classList.remove("active");
document.getElementById("options-menu-link").classList.remove("active");
},
displayCharacterOverviewInfo: function() {
if (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].hp == null) {__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].hp = __WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].max_hp;}
document.getElementById("character-overview-text").innerHTML =
("Hp: " + __WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].hp + " / " + __WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].max_hp + " " +
"Money: " + __WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js___default()(__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].money.toNumber()).format('($0.000a)') + " " +
"Hack: " + (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].hacking_skill).toLocaleString() + " " +
"Str: " + (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].strength).toLocaleString() + " " +
"Def: " + (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].defense).toLocaleString() + " " +
"Dex: " + (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].dexterity).toLocaleString() + " " +
"Agi: " + (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].agility).toLocaleString() + " " +
"Cha: " + (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].charisma).toLocaleString()
).replace( / /g, " " );
},
/* Display character info */
displayCharacterInfo: function() {
var companyPosition = "";
if (__WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].companyPosition != "") {
companyPosition = __WEBPACK_IMPORTED_MODULE_21__Player_js__["a" /* Player */].companyPosition.positionName;
}
Engine.Display.characterInfo.innerHTML =
('General