Merge pull request #174 from danielyxie/dev

v0.34.1
This commit is contained in:
danielyxie 2018-01-19 23:17:38 -06:00 committed by GitHub
commit 73bca9099f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1085 additions and 623 deletions

@ -121,11 +121,12 @@
}
.cmpy-mgmt-upgrade-div {
display:inline-block;
border:1px solid white;
margin:4px;
padding:12px;
border-radius:25px;
width:95%;
width:45%;
color:var(--my-font-color);
}

942
dist/bundle.js vendored

File diff suppressed because it is too large Load Diff

@ -164,9 +164,7 @@
<!-- Character Info page -->
<div id="character-container" class="generic-menupage-container">
<div id="character-content">
<p id="character-info"> </p>
</div>
<div id="character-content"></div>
</div>
<!-- Active scripts info page -->
@ -441,48 +439,7 @@
at any time. Your progress will be saved and you can continue later.
</p>
<ul id="create-program-list">
<a class="a-link-button tooltip" id="create-program-nuke">
NUKE.exe
<span class="tooltiptext"> This virus is used to gain root access to a machine if enough ports are opened. </span>
</a>
<a class="a-link-button tooltip" id="create-program-brutessh">
BruteSSH.exe
<span class="tooltiptext"> This program executes a brute force attack that opens SSH ports </span>
</a>
<a class="a-link-button tooltip" id="create-program-ftpcrack">
FTPCrack.exe
<span class="tooltiptext"> This program cracks open FTP ports</span>
</a>
<a class="a-link-button tooltip" id="create-program-relaysmtp">
relaySMTP.exe
<span class="tooltiptext"> This program opens SMTP ports by redirecting data </span>
</a>
<a class="a-link-button tooltip" id="create-program-httpworm">
HTTPWorm.exe
<span class="tooltiptext"> This virus opens up HTTP ports </span>
</a>
<a class="a-link-button tooltip" id="create-program-sqlinject">
SQLInject.exe
<span class="tooltiptext"> This virus opens SQL ports</span>
</a>
<a class="a-link-button tooltip" id="create-program-deepscanv1">
DeepscanV1.exe
<span class="tooltiptext"> This program allows you to use the scan-analyze command with a depth up to 5</span>
</a>
<a class="a-link-button tooltip" id="create-program-deepscanv2">
DeepscanV2.exe
<span class="tooltiptext"> This program allows you to use the scan-analyze command with a depth up to 10</span>
</a>
<a class="a-link-button tooltip" id="create-program-serverprofiler">
ServerProfiler.exe
<span class="tooltiptext">This program is used to display hacking and Netscript-related information about servers</span>
</a>
<a class="a-link-button tooltip" id="create-program-autolink">
AutoLink.exe
<span class="tooltiptext">This program allows you to directly connect to other servers through the 'scan-analyze' command</span>
</a>
</ul>
<ul id="create-program-list"></ul>
</div>
<!-- Factions -->
@ -947,6 +904,20 @@
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
</fieldset>
<!-- Autosave Interval -->
<fieldset>
<label for="settingsAutosaveIntervalVal" class="tooltip">Autosave Interval
<span class="tooltiptext">
The time (in seconds) between each autosave. Set to 0 to disable autosave.
</span>
</label>
<input type="range" max="600" min="0"
step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60">
</input>
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em>
</fieldset>
<!-- Suppress messages -->
<fieldset>
<label for="settingsSuppressMessages" class="tooltip">Suppress Messages:

@ -78,7 +78,7 @@ function initBitNodes() {
"by 1's and 0's. They were wrong.<br><br>" +
"In this BitNode:<br><br>" +
"The base security level of servers is doubled<br>" +
"The starting money on servers is halved, but the maximum money is doubled<br>" +
"The starting money on servers is halved, but the maximum money remains the same<br>" +
"Most methods of earning money now give significantly less<br>" +
"Infiltration gives 50% more reputation and money<br>" +
"Augmentations are more expensive<br>" +

@ -101,68 +101,70 @@ Material.prototype.init = function(mats={}) {
case "Water":
this.dmd = 75; this.dmdR = [65, 85];
this.cmp = 50; this.cmpR = [40, 60];
this.bCost = 750; this.mv = 0.2;
this.mku = 15;
this.bCost = 1000; this.mv = 0.2;
this.mku = 12;
break;
case "Energy":
this.dmd = 90; this.dmdR = [80, 100];
this.cmp = 80; this.cmpR = [65, 95];
this.bCost = 1125; this.mv = 0.2;
this.mku = 15;
this.bCost = 1500; this.mv = 0.2;
this.mku = 12;
break;
case "Food":
this.dmd = 80; this.dmdR = [70, 90];
this.cmp = 60; this.cmpR = [35, 85];
this.bCost = 3750; this.mv = 1;
this.mku = 9;
this.bCost = 5000; this.mv = 1;
this.mku = 7.5;
break;
case "Plants":
this.dmd = 70; this.dmdR = [20, 90];
this.cmp = 50; this.cmpR = [30, 70];
this.bCost = 2250; this.mv = 0.6;
this.mku = 12;
this.bCost = 3000; this.mv = 0.6;
this.mku = 10;
break;
case "Metal":
this.dmd = 80; this.dmdR = [75, 85];
this.cmp = 70; this.cmpR = [60, 80];
this.bCost = 2000; this.mv = 1;
this.mku = 15;
this.bCost = 2650; this.mv = 1;
this.mku = 12;
break;
case "Hardware":
this.dmd = 85; this.dmdR = [80, 90];
this.cmp = 80; this.cmpR = [65, 95];
this.bCost = 3000; this.mv = 0.5; //Less mv bc its processed twice
this.mku = 7;
this.bCost = 4000; this.mv = 0.5; //Less mv bc its processed twice
this.mku = 5.5;
break;
case "Chemicals":
this.dmd = 55; this.dmdR = [40, 70];
this.cmp = 60; this.cmpR = [40, 80];
this.bCost = 5000; this.mv = 1.2;
this.mku = 8;
this.bCost = 6750; this.mv = 1.2;
this.mku = 6.5;
break;
case "Real Estate":
this.dmd = 50; this.dmdR = [5, 100];
this.cmp = 50; this.cmpR = [25, 75];
this.bCost = 12000; this.mv = 1.5; //Less mv bc its processed twice
this.mku = 6;
this.bCost = 16e3; this.mv = 1.5; //Less mv bc its processed twice
this.mku = 5;
break;
case "Drugs":
this.dmd = 60; this.dmdR = [45, 75];
this.cmp = 70; this.cmpR = [40, 100];
this.bCost = 6000; this.mv = 1.6;
this.mku = 5;
this.bCost = 8e3; this.mv = 1.6;
this.mku = 4;
break;
case "Robots":
this.dmd = 90; this.dmdR = [80, 100];
this.cmp = 90; this.cmpR = [80, 100];
this.bCost = 15000; this.mv = 0.5; //Less mv bc its processed twice
this.mku = 3;
this.bCost = 20e3; this.mv = 0.5; //Less mv bc its processed twice
this.mku = 2.5;
break;
case "AI Cores":
this.dmd = 90; this.dmdR = [80, 100];
this.cmp = 90; this.cmpR = [80, 100];
this.bCost = 20000; this.mv = 0.8; //Less mv bc its processed twice
this.mku = 2;
this.bCost = 27e3; this.mv = 0.8; //Less mv bc its processed twice
this.mku = 1.8;
break;
case "Scientific Research":
break;
default:
console.log("Invalid material type in init(): " + this.name);
@ -175,7 +177,7 @@ Material.prototype.processMarket = function() {
//This 1st random check determines whether competition increases or decreases
//More competition = lower market price
var v = (Math.random() * this.mv) / 100;
var pv = (Math.random() * this.mv) / 100;
var pv = (Math.random() * this.mv) / 300;
if (Math.random() < 0.42) {
this.cmp *= (1+v);
if (this.cmp > this.cmpR[1]) {this.cmp = this.cmpR[1]};
@ -189,7 +191,7 @@ Material.prototype.processMarket = function() {
//This 2nd random check determines whether demand increases or decreases
//More demand = higher market price
v = (Math.random() * this.mv) / 100;
pv = (Math.random() * this.mv) / 100;
pv = (Math.random() * this.mv) / 300;
if (Math.random() < 0.45) {
this.dmd *= (1+v);
if (this.dmd > this.dmdR[1]) {this.dmd = this.dmdR[1];}
@ -591,7 +593,7 @@ function Industry(params={}) {
this.thisCycleRevenue = new Decimal(0);
this.thisCycleExpenses = new Decimal(0);
this.state = 0;
this.state = "START";
this.init();
}
@ -613,6 +615,7 @@ Industry.prototype.init = function() {
this.prodMats = ["Energy"];
break;
case Industries.Utilities:
case "Utilities":
this.reFac = 0.4;
this.sciFac = 0.6;
this.robFac = 0.3;
@ -718,6 +721,7 @@ Industry.prototype.init = function() {
this.makesProducts = true;
break;
case Industries.Computer:
case "Computer":
this.reFac = 0.2;
this.sciFac = 0.65;
this.robFac = 0.4;
@ -796,6 +800,7 @@ Industry.prototype.getProductDescriptionText = function() {
return "develop new pharmaceutical drugs";
break;
case Industries.Computer:
case "Computer":
return "create new computer hardware and networking infrastructures";
break;
case Industries.Robotics:
@ -864,7 +869,7 @@ Industry.prototype.process = function(marketCycles=1, state, company) {
for (var officeLoc in this.offices) {
if (this.offices.hasOwnProperty(officeLoc) &&
this.offices[officeLoc] instanceof OfficeSpace) {
employeeSalary += this.offices[officeLoc].process(marketCycles, this);
employeeSalary += this.offices[officeLoc].process(marketCycles, {industry:this, corporation:company});
}
}
this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary);
@ -881,7 +886,7 @@ Industry.prototype.process = function(marketCycles=1, state, company) {
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
//Process creation, production & sale of products
res = this.processProducts(marketCycles);
res = this.processProducts(marketCycles, company);
this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
}
@ -995,7 +1000,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
} else {
prod = maxProd;
}
prod *= (SecsPerMarketCycle * marketCycles * this.prodMult); //Convert production from per second to per market cycle
prod *= (SecsPerMarketCycle * marketCycles * this.prodMult * company.getProductionMultiplier()); //Convert production from per second to per market cycle
//Calculate net change in warehouse storage making
//the produced materials will cost
var totalMatSize = 0;
@ -1095,7 +1100,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
} else {
sellAmt = maxSell;
}
sellAmt = (sellAmt * SecsPerMarketCycle * marketCycles);
sellAmt = (sellAmt * company.getSalesMultiplier() * SecsPerMarketCycle * marketCycles);
sellAmt = Math.min(mat.qty, sellAmt);
if (sellAmt < 0) {
console.log("ERROR: sellAmt is negative");
@ -1112,7 +1117,6 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
} //End processing of sale of materials
break;
/* TODO Process Export of materials */
case "EXPORT":
for (var matName in warehouse.materials) {
if (warehouse.materials.hasOwnProperty(matName)) {
@ -1158,14 +1162,15 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
//Produce Scientific Research based on R&D employees
//Scientific Research can be produced without a warehouse
if (office instanceof OfficeSpace) {
this.sciResearch.qty += .01 * Math.pow(office.employeeProd[EmployeePositions.RandD], 0.5);
this.sciResearch.qty += (.01 * Math.pow(office.employeeProd[EmployeePositions.RandD], 0.5)
* company.getScientificResearchMultiplier());
}
}
return [revenue, expenses];
}
//Process production & sale of this industry's FINISHED products (including all of their stats)
Industry.prototype.processProducts = function(marketCycles=1) {
Industry.prototype.processProducts = function(marketCycles=1, corporation) {
var revenue = 0, expenses = 0;
//Create products
@ -1198,7 +1203,7 @@ Industry.prototype.processProducts = function(marketCycles=1) {
if (this.products.hasOwnProperty(prodName)) {
var prod = this.products[prodName];
if (prod instanceof Product && prod.fin) {
revenue += this.processProduct(marketCycles, prod);
revenue += this.processProduct(marketCycles, prod, corporation);
}
}
}
@ -1206,7 +1211,7 @@ Industry.prototype.processProducts = function(marketCycles=1) {
}
//Processes FINISHED products
Industry.prototype.processProduct = function(marketCycles=1, product) {
Industry.prototype.processProduct = function(marketCycles=1, product, corporation) {
var totalProfit = 0;
for (var i = 0; i < Cities.length; ++i) {
var city = Cities[i], office = this.offices[city], warehouse = this.warehouses[city];
@ -1230,7 +1235,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product) {
} else {
prod = maxProd;
}
prod *= (this.prodMult * SecsPerMarketCycle * marketCycles);
prod *= (this.prodMult * corporation.getProductionMultiplier() * SecsPerMarketCycle * marketCycles);
//Calculate net change in warehouse storage making the Products will cost
@ -1303,7 +1308,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product) {
} else {
sellAmt = maxSell;
}
sellAmt = sellAmt * SecsPerMarketCycle * marketCycles;
sellAmt = sellAmt * corporation.getSalesMultiplier() * SecsPerMarketCycle * marketCycles;
sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty
if (sellAmt && product.sCost) {
product.data[city][0] -= sellAmt; //data[0] is qty
@ -1409,29 +1414,33 @@ Employee.prototype.process = function(marketCycles=1, office) {
return salary;
}
Employee.prototype.calculateProductivity = function() {
Employee.prototype.calculateProductivity = function(corporation) {
var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
effCha = this.cha * corporation.getEmployeeChaMultiplier(),
effInt = this.int * corporation.getEmployeeIntMultiplier(),
effEff = this.eff * corporation.getEmployeeEffMultiplier();
var prodBase = this.mor * this.hap * this.ene * 1e-6, prodMult;
switch(this.pos) {
//Calculate productivity based on position. This is multipled by prodBase
//to get final value
case EmployeePositions.Operations:
prodMult = (0.6 * this.int) + (0.1 * this.cha) + (this.exp) +
(0.5 * this.cre) + (this.eff);
prodMult = (0.6 * effInt) + (0.1 * effCha) + (this.exp) +
(0.5 * effCre) + (effEff);
break;
case EmployeePositions.Engineer:
prodMult = (this.int) + (0.1 * this.cha) + (1.5 * this.exp) +
(this.eff);
prodMult = (effInt) + (0.1 * effCha) + (1.5 * this.exp) +
(effEff);
break;
case EmployeePositions.Business:
prodMult = (0.4 * this.int) + (this.cha) + (0.5 * this.exp);
prodMult = (0.4 * effInt) + (effCha) + (0.5 * this.exp);
break;
case EmployeePositions.Management:
prodMult = (2 * this.cha) + (this.exp) + (0.2 * this.cre) +
(0.7 * this.eff);
prodMult = (2 * effCha) + (this.exp) + (0.2 * effCre) +
(0.7 * effEff);
break;
case EmployeePositions.RandD:
prodMult = (1.5 * this.int) + (0.8 * this.exp) + (this.cre) +
(0.5 * this.eff);
prodMult = (1.5 * effInt) + (0.8 * this.exp) + (effCre) +
(0.5 * effEff);
break;
default:
console.log("Invalid employee position: " + this.pos);
@ -1451,7 +1460,11 @@ Employee.prototype.throwParty = function(money) {
}
//'panel' is the DOM element on which to create the UI
Employee.prototype.createUI = function(panel) {
Employee.prototype.createUI = function(panel, corporation) {
var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
effCha = this.cha * corporation.getEmployeeChaMultiplier(),
effInt = this.int * corporation.getEmployeeIntMultiplier(),
effEff = this.eff * corporation.getEmployeeEffMultiplier();
panel.style.color = "white";
panel.appendChild(createElement("p", {
id:"cmpy-mgmt-employee-" + this.name + "-panel-text",
@ -1459,11 +1472,11 @@ Employee.prototype.createUI = function(panel) {
"Happiness: " + formatNumber(this.hap, 3) + "<br>" +
"Energy: " + formatNumber(this.ene, 3) + "<br>" +
"Age: " + formatNumber(this.age, 3) + "<br>" +
"Intelligence: " + formatNumber(this.int, 3) + "<br>" +
"Charisma: " + formatNumber(this.cha, 3) + "<br>" +
"Intelligence: " + formatNumber(effInt, 3) + "<br>" +
"Charisma: " + formatNumber(effCha, 3) + "<br>" +
"Experience: " + formatNumber(this.exp, 3) + "<br>" +
"Creativity: " + formatNumber(this.cre, 3) + "<br>" +
"Efficiency: " + formatNumber(this.eff, 3) + "<br>" +
"Creativity: " + formatNumber(effCre, 3) + "<br>" +
"Efficiency: " + formatNumber(effEff, 3) + "<br>" +
"Salary: " + numeral(this.sal).format("$0.000a") + "/ s<br>",
}));
@ -1492,7 +1505,11 @@ Employee.prototype.createUI = function(panel) {
panel.appendChild(selector);
}
Employee.prototype.updateUI = function(panel) {
Employee.prototype.updateUI = function(panel, corporation) {
var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
effCha = this.cha * corporation.getEmployeeChaMultiplier(),
effInt = this.int * corporation.getEmployeeIntMultiplier(),
effEff = this.eff * corporation.getEmployeeEffMultiplier();
if (panel == null) {
console.log("ERROR: Employee.updateUI() called with null panel");
return;
@ -1505,11 +1522,11 @@ Employee.prototype.updateUI = function(panel) {
"Happiness: " + formatNumber(this.hap, 3) + "<br>" +
"Energy: " + formatNumber(this.ene, 3) + "<br>" +
"Age: " + formatNumber(this.age, 3) + "<br>" +
"Intelligence: " + formatNumber(this.int, 3) + "<br>" +
"Charisma: " + formatNumber(this.cha, 3) + "<br>" +
"Intelligence: " + formatNumber(effInt, 3) + "<br>" +
"Charisma: " + formatNumber(effCha, 3) + "<br>" +
"Experience: " + formatNumber(this.exp, 3) + "<br>" +
"Creativity: " + formatNumber(this.cre, 3) + "<br>" +
"Efficiency: " + formatNumber(this.eff, 3) + "<br>" +
"Creativity: " + formatNumber(effCre, 3) + "<br>" +
"Efficiency: " + formatNumber(effEff, 3) + "<br>" +
"Salary: " + numeral(this.sal).format("$0.000a") + "/ s<br>";
}
@ -1552,7 +1569,8 @@ function OfficeSpace(params={}) {
};
}
OfficeSpace.prototype.process = function(marketCycles=1, industry) {
OfficeSpace.prototype.process = function(marketCycles=1, parentRefs) {
var corporation = parentRefs.corporation, industry = parentRefs.industry;
var perfMult=1; //Multiplier for employee morale/happiness/energy based on company performance
if (industry.funds < 0 && industry.lastCycleRevenue < 0) {
perfMult = Math.pow(0.99, marketCycles);
@ -1569,11 +1587,11 @@ OfficeSpace.prototype.process = function(marketCycles=1, industry) {
var salary = emp.process(marketCycles, this);
salaryPaid += salary;
}
this.calculateEmployeeProductivity(marketCycles);
this.calculateEmployeeProductivity(marketCycles, corporation);
return salaryPaid;
}
OfficeSpace.prototype.calculateEmployeeProductivity = function(marketCycles=1) {
OfficeSpace.prototype.calculateEmployeeProductivity = function(marketCycles=1, corporation) {
//Reset
for (var name in this.employeeProd) {
if (this.employeeProd.hasOwnProperty(name)) {
@ -1584,7 +1602,7 @@ OfficeSpace.prototype.calculateEmployeeProductivity = function(marketCycles=1) {
var total = 0;
for (var i = 0; i < this.employees.length; ++i) {
var employee = this.employees[i];
var prod = employee.calculateProductivity();
var prod = employee.calculateProductivity(corporation);
this.employeeProd[employee.pos] += prod;
total += prod;
}
@ -1711,6 +1729,8 @@ Reviver.constructors.OfficeSpace = OfficeSpace;
function Warehouse(params={}) {
this.loc = params.loc ? params.loc : "";
this.size = params.size ? params.size : 0;
this.level = 0;
this.sizeUsed = 0;
this.materials = {
@ -1743,6 +1763,15 @@ Warehouse.prototype.updateMaterialSizeUsed = function() {
}
}
Warehouse.prototype.updateSize = function(corporation) {
//Backwards compatibility
if (this.level == null || this.level === 0) {
this.level = Math.round(this.size / 100);
}
this.size = (this.level * 100) * corporation.getStorageMultiplier();
}
Warehouse.prototype.createUI = function(parentRefs) {
if (parentRefs.company == null || parentRefs.industry == null) {
console.log("ERROR: Warehouse.createUI called without parentRefs.company or parentRefs.industry");
@ -1766,7 +1795,13 @@ Warehouse.prototype.createUI = function(parentRefs) {
display:"inline-block",
class: company.funds.lt(upgradeCost) ? "a-link-button-inactive" : "a-link-button",
clickListener:()=>{
this.size += 100;
//Backwards compatibility
if (this.level == null || this.level === 0) {
this.level = Math.round(this.size / 100);
}
++this.level;
this.updateSize(company);
company.funds = company.funds.minus(upgradeCost);
this.createUI(parentRefs);
return;
@ -2390,48 +2425,60 @@ var CorporationUnlockUpgrades = {
// name, desc]
var CorporationUpgrades = {
//Smart factories, increases production
"0": [0, 10e9, 1.07, 0.02,
"0": [0, 4e9, 1.07, 0.02,
"Smart Factories", "Advanced AI automatically optimizes the operation and productivity " +
"of factories. Each level of this upgrade increases your global production by 2% (additive)."],
//Smart warehouses, increases storage size
"1": [1, 20e9, 1.07, .1,
"1": [1, 4e9, 1.07, .1,
"Smart Storage", "Advanced AI automatically optimizes your warehouse storage methods. " +
"Each level of this upgrade increases your global warehouse storage size by 10% (additive)."],
//Advertise through dreams, passive popularity/ awareness gain
"2": [2, 100e9, 1.08, .001,
"DreamSense", "Use DreamSense LCC Technologies to advertise your corporation " +
"2": [2, 999999e9, 1.08, .001,
"DreamSense", "NOT YET IMPLEMENTED! - Use DreamSense LCC Technologies to advertise your corporation " +
"to consumers through their dreams. Each level of this upgrade provides a passive " +
"increase in awareness of your company by 0.001 / second."],
//Makes advertising more effective
"3": [3, 5e9, 1.11, 0.1,
"Wilson Analytics", "Purchase data and analysis from Wilson, a marketing research " +
"3": [3, 999999e9, 1.11, 0.1,
"Wilson Analytics", "NOT YET IMPLEMENTED - Purchase data and analysis from Wilson, a marketing research " +
"firm. Each level of this upgrades increases the effectiveness of your " +
"advertising by 10% (additive)."],
//Augmentation for employees, increases cre
"4": [4, 10e9, 1.05, 0.1,
"4": [4, 2e9, 1.06, 0.1,
"Nuoptimal Nootropic Injector Implants", "Purchase the Nuoptimal Nootropic " +
"Injector augmentation for your employees. Each level of this upgrade " +
"globally increases the creativity of your employees by 10% (additive)."],
//Augmentation for employees, increases cha
"5": [5, 10e9, 1.05, 0.1,
"5": [5, 2e9, 1.06, 0.1,
"Speech Processor Implants", "Purchase the Speech Processor augmentation for your employees. " +
"Each level of this upgrade globally increases the charisma of your employees by 10% (additive)."],
//Augmentation for employees, increases int
"6": [6, 10e9, 1.05, 0.1,
"Neural Acelerators", "Purchase the Neural Accelerator augmentation for your employees. " +
"6": [6, 2e9, 1.06, 0.1,
"Neural Accelerators", "Purchase the Neural Accelerator augmentation for your employees. " +
"Each level of this upgrade globally increases the intelligence of your employees " +
"by 10% (additive)."],
//Augmentation for employees, increases eff
"7": [7, 10e9, 1.05, 0.1,
"7": [7, 2e9, 1.06, 0.1,
"FocusWires", "Purchase the FocusWire augmentation for your employees. Each level " +
"of this upgrade globally increases the efficiency of your employees by 10% (additive)."],
//Improves sales of materials/products
"8": [8, 1e9, 1.09, 0.01,
"ABC SalesBots", "Always Be Closing. Purchase these robotic salesmen to increase the amount of " +
"materials and products you sell. Each level of this upgrade globally increases your sales " +
"by 1% (additive)."],
//Improves scientific research rate
"9": [9, 5e9, 1.08, 0.05,
"Project Insight", "Purchase 'Project Insight', a R&D service provided by the secretive " +
"Fulcrum Technologies. Each level of this upgrade globally increases the amount of " +
"Scientific Research you produce by 5% (additive)."],
}
function Corporation(params={}) {
@ -2495,13 +2542,13 @@ Corporation.prototype.process = function(numCycles=1) {
Corporation.prototype.determineValuation = function() {
var val, profit = (this.revenue.minus(this.expenses)).toNumber();
if (this.public) {
val = 25e9 + this.funds.toNumber() + (profit * getRandomInt(7000, 8500));
val = 25e9 + this.funds.toNumber() + (profit * 25e3);
val *= (Math.pow(1.1, this.divisions.length));
val = Math.max(val, 0);
} else {
val = 10e9 + Math.max(this.funds.toNumber(), 0); //Base valuation
val = 10e9 + Math.max(this.funds.toNumber(), 0) / 3; //Base valuation
if (profit > 0) {
val += (profit * getRandomInt(12e3, 14e3));
val += (profit * 400e3);
val *= (Math.pow(1.1, this.divisions.length));
} else {
val = 10e9 * Math.pow(1.1, this.divisions.length);
@ -2630,7 +2677,7 @@ Corporation.prototype.upgrade = function(upgrade) {
upgradeAmt = upgrade[3]; //Amount by which the upgrade multiplier gets increased (additive)
while (this.upgrades.length <= upgN) {this.upgrades.push(0);}
while (this.upgradeMultipliers.length <= upgN) {this.upgradeMultipliers.push(1);}
var totalCost = basePrice * Math.pow(this.upgrades[upgN], priceMult);
var totalCost = basePrice * Math.pow(priceMult, this.upgrades[upgN]);
if (this.funds.lt(totalCost)) {
dialogBoxCreate("You don't have enough funds to purchase this!");
return;
@ -2640,8 +2687,68 @@ Corporation.prototype.upgrade = function(upgrade) {
//Increase upgrade multiplier
this.upgradeMultipliers[upgN] = 1 + (this.upgrades[upgN] * upgradeAmt);
//If storage size is being updated, update values in Warehouse objects
if (upgN === 1) {
for (var i = 0; i < this.divisions.length; ++i) {
var industry = this.divisions[i];
for (var city in industry.warehouses) {
if (industry.warehouses.hasOwnProperty(city) && industry.warehouses[city] instanceof Warehouse) {
industry.warehouses[city].updateSize(this);
}
}
}
}
this.updateCorporationOverviewContent();
}
Corporation.prototype.getProductionMultiplier = function() {
var mult = this.upgradeMultipliers[0];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getStorageMultiplier = function() {
var mult = this.upgradeMultipliers[1];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getAdvertisingMultiplier = function() {
var mult = this.upgradeMultipliers[3];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getEmployeeCreMultiplier = function() {
var mult = this.upgradeMultipliers[4];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getEmployeeChaMultiplier = function() {
var mult = this.upgradeMultipliers[5];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getEmployeeIntMultiplier = function() {
var mult = this.upgradeMultipliers[6];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getEmployeeEffMultiplier = function() {
var mult = this.upgradeMultipliers[7];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getSalesMultiplier = function() {
var mult = this.upgradeMultipliers[8];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
Corporation.prototype.getScientificResearchMultiplier = function() {
var mult = this.upgradeMultipliers[9];
if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
}
//Keep 'global' variables for DOM elements so we don't have to search
//through the DOM tree repeatedly when updating UI
var companyManagementDiv, companyManagementHeaderTabs, companyManagementPanel,
@ -3062,19 +3169,22 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
class:"cmpy-mgmt-upgrade-container",
});
upgradeContainer.appendChild(createElement("h1", {
innerText:"Upgrades", margin:"6px", padding:"6px",
innerText:"Unlocks", margin:"6px", padding:"6px",
}));
//Unlock upgrades
var corp = this;
var numUnlockUpgrades = Object.keys(CorporationUnlockUpgrades).length,
numUpgrades = Object.keys(CorporationUpgrades).length;
if (this.unlockUpgrades == null || this.upgrades == null) { //Backwards compatibility
var numUnlockUpgrades = Object.keys(CorporationUnlockUpgrades).length,
numUpgrades = Object.keys(CorporationUpgrades).length;
this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
this.upgrades = Array(numUpgrades).fill(0);
}
for (var i = 0; i < this.unlockUpgrades.length; ++i) {
while (this.unlockUpgrades.length < numUnlockUpgrades) {this.unlockUpgrades.push(0);}
while (this.upgrades.length < numUpgrades) {this.upgrades.push(0);}
while (this.upgradeMultipliers < numUpgrades) {this.upgradeMultipliers.push(1);}
for (var i = 0; i < numUnlockUpgrades; ++i) {
(function(i, corp) {
if (corp.unlockUpgrades[i] === 0) {
var upgrade = CorporationUnlockUpgrades[i.toString()];
@ -3085,7 +3195,8 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
upgradeContainer.appendChild(createElement("div", {
class:"cmpy-mgmt-upgrade-div",
innerHTML:upgrade[2] + " - " + numeral(upgrade[1]).format("$0.000a") + "<br><br>" + upgrade[3],
innerHTML:upgrade[2] + " - " + numeral(upgrade[1]).format("$0.000a"),
tooltip: upgrade[3],
clickListener:()=>{
if (corp.funds.lt(upgrade[1])) {
dialogBoxCreate("Insufficient funds");
@ -3100,8 +3211,11 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
}
//Levelable upgrades
/*
for (var i = 0; i < this.upgrades.length; ++i) {
upgradeContainer.appendChild(createElement("h1", {
innerText:"Upgrades", margin:"6px", padding:"6px",
}));
for (var i = 0; i < numUpgrades; ++i) {
(function(i, corp) {
var upgrade = CorporationUpgrades[i.toString()];
if (upgrade == null) {
@ -3110,10 +3224,11 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
}
var baseCost = upgrade[1], priceMult = upgrade[2];
var cost = baseCost * Math.pow(corp.upgrades[i], priceMult);
var cost = baseCost * Math.pow(priceMult, corp.upgrades[i]);
upgradeContainer.appendChild(createElement("div", {
class:"cmpy-mgmt-upgrade-div",
innerHTML:upgrade[4] + " - " + numeral(cost).format("$0.000a") + "<br><br>" + upgrade[5],
innerHTML:upgrade[4] + " - " + numeral(cost).format("$0.000a"),
tooltip:upgrade[5],
clickListener:()=>{
if (corp.funds.lt(cost)) {
dialogBoxCreate("Insufficient funds");
@ -3124,7 +3239,7 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
}
}));
})(i, corp);
}*/
}
companyManagementPanel.appendChild(upgradeContainer);
}
@ -3148,9 +3263,27 @@ Corporation.prototype.updateCorporationOverviewContent = function() {
"Total Profits: " + profitStr + " / s<br>" +
"Publicly Traded: " + (this.public ? "Yes" : "No") + "<br>" +
"Owned Stock Shares: " + numeral(this.numShares).format('0.000a') + "<br>" +
"Stock Price: " + (this.public ? "$" + formatNumber(this.sharePrice, 2) : "N/A") + "<br>";
p.innerHTML = txt;
"Stock Price: " + (this.public ? "$" + formatNumber(this.sharePrice, 2) : "N/A") + "<br><br>";
var prodMult = this.getProductionMultiplier(),
storageMult = this.getStorageMultiplier(),
advMult = this.getAdvertisingMultiplier(),
empCreMult = this.getEmployeeCreMultiplier(),
empChaMult = this.getEmployeeChaMultiplier(),
empIntMult = this.getEmployeeIntMultiplier(),
empEffMult = this.getEmployeeEffMultiplier(),
salesMult = this.getSalesMultiplier(),
sciResMult = this.getScientificResearchMultiplier();
if (prodMult > 1) {txt += "Production Multiplier: " + formatNumber(prodMult, 3) + "<br>";}
if (storageMult > 1) {txt += "Storage Multiplier: " + formatNumber(storageMult, 3) + "<br>";}
if (advMult > 1) {txt += "Advertising Multiplier: " + formatNumber(advMult, 3) + "<br>";}
if (empCreMult > 1) {txt += "Empl. Creativity Multiplier: " + formatNumber(empCreMult, 3) + "<br>";}
if (empChaMult > 1) {txt += "Empl. Charisma Multiplier: " + formatNumber(empChaMult, 3) + "<br>";}
if (empIntMult > 1) {txt += "Empl. Intelligence Multiplier: " + formatNumber(empIntMult, 3) + "<br>";}
if (empEffMult > 1) {txt += "Empl. Efficiency Multiplier: " + formatNumber(empEffMult, 3) + "<br>";}
if (salesMult > 1) {txt += "Sales Multiplier: " + formatNumber(salesMult, 3) + "<br>";}
if (sciResMult > 1) {txt += "Scientific Research Multiplier: " + formatNumber(sciResMult, 3) + "<br>";}
p.innerHTML = txt;
}
Corporation.prototype.displayDivisionContent = function(division, city) {
@ -3272,6 +3405,7 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
createProductPopupText = "Design and develop a new pharmaceutical drug!";
break;
case Industries.Computer:
case "Computer":
createProductButtonText = "Create Product";
createProductPopupText = "Design and manufacture a new computer hardware product!";
break;
@ -3528,7 +3662,7 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
});
industryEmployeePanel.appendChild(industryEmployeeList);
for (var i = 0; i < office.employees.length; ++i) {
(function() {
(function(corp) {
var emp = office.employees[i];
var li = createAccordionElement({
id:"cmpy-mgmt-employee-" + emp.name,
@ -3539,9 +3673,9 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
console.log("ERROR: Could not find employee accordion panel");
return;
}
emp.createUI(panel);
emp.createUI(panel, corp);
industryEmployeeList.appendChild(li);
})();
})(this);
}
//Warehouse Panel
@ -3615,11 +3749,11 @@ Corporation.prototype.updateDivisionContent = function(division) {
hdrText:emp.name,
});
panel = li.children[1];
emp.createUI(panel);
emp.createUI(panel, company);
employeeList.appendChild(li);
return;
}
emp.updateUI(panel);
emp.updateUI(panel, company);
})(this);
}
}

@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.34.0",
Version: "0.34.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
@ -1118,29 +1118,19 @@ let CONSTANTS = {
LatestUpdate:
"v0.34.1<br>" +
"-Added new 'secret' Terminal command. Try: run musicplayer<br>" +
"v0.34.0<br>" +
"-Added clear() and exit() Netscript functions<br>" +
"-When starting out or prestiging, you will now receive a 'Hacking Starter Guide'. It provides tips/pointers for new players<br>" +
"-Doubled the amount of RAM on low-level servers (up to required hacking level 150)<br>" +
"-Slightly increased experience gain from Infiltration<br>" +
"-buyStock(), sellStock(), shortStock(), and sellShort() Netscript function now return the stock price at which the transaction occurred, rather than a boolean. " +
"If the function fails for some reason, 0 will be returned.<br>" +
"-Hacking Mission Changes:<br>" +
"---You can now select multiple Nodes of the same type by double clicking. This allows you to set the " +
"action of all of selected nodes at once (e.g. set all Transfer Nodes to Fortify). Creating connections " +
"does not work with this multi-select functionality yet<br>" +
"---Shield and Firewall Nodes can now fortify<br>" +
"---The effects of Fortifying are now ~5% lower<br>" +
"---Conquering a Spam Node now increases your time limit by 25 seconds instead of 15<br>" +
"---Damage dealt by Attacking was slightly reduced<br>" +
"---The effect of Scanning was slightly reduced<br>" +
"---Enemy CPU Core Nodes start with slightly more attack. Misc Nodes start with slightly less defense<br>" +
"-Corporation Management changes:<br>" +
"---Added several upgrades that unlock new features<br>" +
"---Implemented Exporting mechanic<br>" +
"---Fixed many bugs<br>"
"-Updates to Corporation Management:<br>" +
"---Added a number of upgrades to various aspects of your Corporation<br>" +
"---Rebalanced the properties of Materials and the formula for determining the valuation of the Corporation<br>" +
"---Fixed a number of bugs<br>" +
"-'Stats' page now shows information about current BitNode<br>" +
"-You should now be able to create Corporations in other BitNodes if you have Source-File 3<br>" +
"-Added a new create-able program called b1t_flum3.exe. This program can be used to reset and switch BitNodes<br>" +
"-Added an option to adjust autosave interval<br>" +
"-Line feeds, newlines, and tabs will now work with the tprint() Netscript function<br>" +
"-Bug fix: 'check' Terminal command was broken<br>" +
"-Bug fix: 'theme' Terminal command was broken when manually specifying hex codes<br>" +
"-Bug fix: Incorrect promotion requirement for 'Business'-type jobs<br>" +
"-Bug fix: Settings input bars were incorrectly formatted when loading game<br>"
}
export {CONSTANTS};

@ -1,5 +1,6 @@
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {createElement} from "../utils/HelperFunctions.js";
/* Create programs */
let Programs = {
@ -14,22 +15,12 @@ let Programs = {
ServerProfiler: "ServerProfiler.exe",
AutoLink: "AutoLink.exe",
Flight: "fl1ght.exe",
BitFlume: "b1t_flum3.exe"
};
//TODO Right now the times needed to complete work are hard-coded...
//maybe later make this dependent on hacking level or something
var nukeALink, bruteSshALink, ftpCrackALink, relaySmtpALink, httpWormALink, sqlInjectALink,
deepscanv1ALink, deepscanv2ALink, servProfilerALink, autolinkALink, bitFlumeALink;
function displayCreateProgramContent() {
var nukeALink = document.getElementById("create-program-nuke");
var bruteSshALink = document.getElementById("create-program-brutessh");
var ftpCrackALink = document.getElementById("create-program-ftpcrack");
var relaySmtpALink = document.getElementById("create-program-relaysmtp");
var httpWormALink = document.getElementById("create-program-httpworm");
var sqlInjectALink = document.getElementById("create-program-sqlinject");
var deepscanv1ALink = document.getElementById("create-program-deepscanv1");
var deepscanv2ALink = document.getElementById("create-program-deepscanv2");
var servProfilerALink = document.getElementById("create-program-serverprofiler");
var autolinkALink = document.getElementById("create-program-autolink");
nukeALink.style.display = "none";
bruteSshALink.style.display = "none";
ftpCrackALink.style.display = "none";
@ -40,6 +31,7 @@ function displayCreateProgramContent() {
deepscanv2ALink.style.display = "none";
servProfilerALink.style.display = "none";
autolinkALink.style.display = "none";
bitFlumeALink.style.display = "none";
//NUKE.exe (in case you delete it lol)
if (Player.getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) {
@ -85,6 +77,10 @@ function displayCreateProgramContent() {
if (!Player.hasProgram(Programs.AutoLink) && Player.hacking_skill >= 25) {
autolinkALink.style.display = "inline-block";
}
//Bit Flume
if (!Player.hasProgram(Programs.BitFlume) && Player.sourceFiles.length > 0 && Player.hacking_skill >= 5) {
bitFlumeALink.style.display = "inline-block";
}
}
//Returns the number of programs that are currently available to be created
@ -134,6 +130,10 @@ function getNumAvailableCreateProgram() {
if (!Player.hasProgram(Programs.AutoLink) && Player.hacking_skill >= 25) {
++count;
}
//Bit Flume
if (!Player.hasProgram(Programs.BitFlume) && Player.sourceFiles.length > 0 && Player.hacking_skill >= 5) {
++count;
}
if (Player.firstProgramAvailable === false && count > 0) {
Player.firstProgramAvailable = true;
document.getElementById("create-program-tab").style.display = "list-item";
@ -144,16 +144,72 @@ function getNumAvailableCreateProgram() {
}
function initCreateProgramButtons() {
var nukeALink = document.getElementById("create-program-nuke");
var bruteSshALink = document.getElementById("create-program-brutessh");
var ftpCrackALink = document.getElementById("create-program-ftpcrack");
var relaySmtpALink = document.getElementById("create-program-relaysmtp");
var httpWormALink = document.getElementById("create-program-httpworm");
var sqlInjectALink = document.getElementById("create-program-sqlinject");
var deepscanv1ALink = document.getElementById("create-program-deepscanv1");
var deepscanv2ALink = document.getElementById("create-program-deepscanv2");
var servProfilerALink = document.getElementById("create-program-serverprofiler");
var autolinkALink = document.getElementById("create-program-autolink");
var createProgramList = document.getElementById("create-program-list");
nukeALink = createElement("a", {
class:"a-link-button", id:"create-program-nuke", innerText:Programs.NukeProgram,
tooltip:"This virus is used to gain root access to a machine if enough ports are opened.",
});
createProgramList.appendChild(nukeALink);
bruteSshALink = createElement("a", {
class:"a-link-button", id:"create-program-brutessh", innerText:Programs.BruteSSHProgram,
tooltip:"This program executes a brute force attack that opens SSH ports"
});
createProgramList.appendChild(bruteSshALink);
ftpCrackALink = createElement("a", {
class:"a-link-button", id:"create-program-ftpcrack", innerText:Programs.FTPCrackProgram,
tooltip:"This program cracks open FTP ports"
});
createProgramList.appendChild(ftpCrackALink);
relaySmtpALink = createElement("a", {
class:"a-link-button", id:"create-program-relaysmtp", innerText:Programs.RelaySMTPProgram,
tooltip:"This program opens SMTP ports by redirecting data"
}) ;
createProgramList.appendChild(relaySmtpALink);
httpWormALink = createElement("a", {
class:"a-link-button", id:"create-program-httpworm", innerText:Programs.HTTPWormProgram,
tooltip:"This virus opens up HTTP ports"
});
createProgramList.appendChild(httpWormALink);
sqlInjectALink = createElement("a", {
class:"a-link-button", id:"create-program-sqlinject", innerText:Programs.SQLInjectProgram,
tooltip:"This virus opens SQL ports"
});
createProgramList.appendChild(sqlInjectALink);
deepscanv1ALink = createElement("a", {
class:"a-link-button", id:"create-program-deepscanv1", innerText:Programs.DeepscanV1,
tooltip:"This program allows you to use the scan-analyze command with a depth up to 5"
});
createProgramList.appendChild(deepscanv1ALink);
deepscanv2ALink = createElement("a", {
class:"a-link-button", id:"create-program-deepscanv2", innerText:Programs.DeepscanV2,
tooltip:"This program allows you to use the scan-analyze command with a depth up to 10"
});
createProgramList.appendChild(deepscanv2ALink);
servProfilerALink = createElement("a", {
class:"a-link-button", id:"create-program-serverprofiler", innerText:Programs.ServerProfiler,
tooltip:"This program is used to display hacking and Netscript-related information about servers"
});
createProgramList.appendChild(servProfilerALink);
bitFlumeALink = createElement("a", {
class:"a-link-button", id:"create-program-bitflume", innerText:Programs.BitFlume,
tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)"
});
createProgramList.appendChild(bitFlumeALink);
autolinkALink = createElement("a", {
class:"a-link-button", id:"create-program-autolink", innerText:"AutoLink.exe",
tooltip:"This program allows you to directly connect to other servers through the 'scan-analyze' command"
});
createProgramList.appendChild(autolinkALink);
nukeALink.addEventListener("click", function() {
Player.startCreateProgramWork(Programs.NukeProgram, CONSTANTS.MillisecondsPerFiveMinutes, 1);
@ -195,6 +251,10 @@ function initCreateProgramButtons() {
Player.startCreateProgramWork(Programs.AutoLink, CONSTANTS.MillisecondsPerQuarterHour, 25);
return false;
});
bitFlumeALink.addEventListener("click", function() {
Player.startCreateProgramWork(Programs.BitFlume, CONSTANTS.MillisecondsPerFiveMinutes / 5, 5);
return false;
});
}
export {Programs, displayCreateProgramContent, getNumAvailableCreateProgram,

@ -261,7 +261,7 @@ function iTutorialEvaluateStep() {
//next step triggered by terminal commmand
break;
case iTutorialSteps.TerminalRunScript:
iTutorialSetText("We have 8GB of free RAM on this machine, which is enough to run our " +
iTutorialSetText("We have 16GB of free RAM on this machine, which is enough to run our " +
"script. Let's run our script using 'run foodnstuff.script'.");
//next step triggered by terminal commmand
break;

@ -64,12 +64,20 @@ import {yesNoBoxClose, yesNoBoxGetYesButton,
yesNoBoxGetNoButton, yesNoBoxCreate,
yesNoBoxOpen} from "../utils/YesNoBox.js";
var hasSingularitySF=false, hasAISF=false, hasBn11SF=false, hasWallStreetSF=false;
var hasSingularitySF=false, //Source-File 4
hasAISF=false, //Source-File 5
hasBn11SF=false,
hasWallStreetSF=false, //Source-File 8
hasCorporationSF=false; //Source-File 3
var singularitySFLvl=1, wallStreetSFLvl=1;
//Used to check and set flags for every Source File, despite the name of the function
function initSingularitySFFlags() {
for (var i = 0; i < Player.sourceFiles.length; ++i) {
if (Player.sourceFiles[i].n === 3) {
hasCorporationSF = true;
}
if (Player.sourceFiles[i].n === 4) {
hasSingularitySF = true;
singularitySFLvl = Player.sourceFiles[i].lvl;
@ -2421,5 +2429,5 @@ function NetscriptFunctions(workerScript) {
}
}
export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF, hasBn11SF, hasWallStreetSF,
export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF, hasBn11SF, hasWallStreetSF, hasCorporationSF,
wallStreetSFLvl};

@ -1768,6 +1768,7 @@ PlayerObject.prototype.getNextCompanyPosition = function(company, 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.isBusinessJob() && entryPosType.isBusinessJob()) ||
(this.companyPosition.isSecurityEngineerJob() && entryPosType.isSecurityEngineerJob()) ||
(this.companyPosition.isNetworkEngineerJob() && entryPosType.isNetworkEngineerJob()) ||
(this.companyPosition.isSecurityJob() && entryPosType.isSecurityJob()) ||

@ -7,7 +7,8 @@ import {SourceFiles, SourceFile,
import {Terminal} from "./Terminal.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {clearEventListeners,
removeChildrenFromElement} from "../utils/HelperFunctions.js";
import {yesNoBoxCreate, yesNoBoxGetYesButton,
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
@ -52,7 +53,7 @@ function writeRedPillLetter(pElem, line, i=0) {
}
let redPillFlag = false;
function hackWorldDaemon(currentNodeNumber) {
function hackWorldDaemon(currentNodeNumber, flume=false) {
redPillFlag = true;
Engine.loadRedPillContent();
return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() {
@ -84,7 +85,7 @@ function hackWorldDaemon(currentNodeNumber) {
}).then(function() {
return writeRedPillLine("..............................................")
}).then(function() {
return loadBitVerse(currentNodeNumber);
return loadBitVerse(currentNodeNumber, flume);
}).catch(function(e){
console.log("ERROR: " + e.toString());
});
@ -131,12 +132,10 @@ function giveSourceFile(bitNodeNumber) {
}
}
function loadBitVerse(destroyedBitNodeNum) {
function loadBitVerse(destroyedBitNodeNum, flume=false) {
//Clear the screen
var container = document.getElementById("red-pill-container");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
removeChildrenFromElement(container);
//Create the Bit Verse
var bitVerseImage = document.createElement("pre");
@ -218,7 +217,7 @@ function loadBitVerse(destroyedBitNodeNum) {
return;
}
yesNoBoxCreate("BitNode-" + i + ": " + bitNode.name + "<br><br>" + bitNode.info);
createBitNodeYesNoEventListeners(i, destroyedBitNodeNum);
createBitNodeYesNoEventListeners(i, destroyedBitNodeNum, flume);
});
} else {
elem.addEventListener("click", function() {
@ -289,16 +288,14 @@ function createBitNode(n) {
"</span></a>";
}
function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode) {
function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode, flume=false) {
var yesBtn = yesNoBoxGetYesButton();
yesBtn.innerHTML = "Enter BitNode-" + newBitNode;
yesBtn.addEventListener("click", function() {
giveSourceFile(destroyedBitNode);
if (!flume) {giveSourceFile(destroyedBitNode);}
redPillFlag = false;
var container = document.getElementById("red-pill-container");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
removeChildrenFromElement(container);
//Set new Bit Node
Player.bitNodeN = newBitNode;

@ -22,6 +22,7 @@ import {addWorkerScript, killWorkerScript} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
import {AllServers, processSingleServerGrowth} from "./Server.js";
import {Settings} from "./Settings.js";
import {post} from "./Terminal.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,

@ -1,3 +1,5 @@
import {Engine} from "./engine.js";
/* Settings.js */
let Settings = {
CodeInstructionRunTime: 50,
@ -5,6 +7,7 @@ let Settings = {
MaxPortCapacity: 50,
SuppressMessages: false,
SuppressFactionInvites: false,
AutosaveInterval: 60,
}
function loadSettings(saveString) {
@ -17,6 +20,7 @@ function initSettings() {
Settings.MaxPortCapacity = 50;
Settings.SuppressMessages = false;
Settings.SuppressFactionInvites = false;
Settings.AutosaveInterval = 60;
}
function setSettingsLabels() {
@ -25,6 +29,7 @@ function setSettingsLabels() {
var nsPortLimit = document.getElementById("settingsNSPortRangeValLabel");
var suppressMsgs = document.getElementById("settingsSuppressMessages");
var suppressFactionInv = document.getElementById("settingsSuppressFactionInvites")
var autosaveInterval = document.getElementById("settingsAutosaveIntervalValLabel");
//Initialize values on labels
nsExecTime.innerHTML = Settings.CodeInstructionRunTime + "ms";
@ -32,23 +37,43 @@ function setSettingsLabels() {
nsPortLimit.innerHTML = Settings.MaxPortCapacity;
suppressMsgs.checked = Settings.SuppressMessages;
suppressFactionInv.checked = Settings.SuppressFactionInvites;
autosaveInterval.innerHTML = Settings.AutosaveInterval;
//Set handlers for when input changes
document.getElementById("settingsNSExecTimeRangeVal").oninput = function() {
var nsExecTimeInput = document.getElementById("settingsNSExecTimeRangeVal");
var nsLogRangeInput = document.getElementById("settingsNSLogRangeVal");
var nsPortRangeInput = document.getElementById("settingsNSPortRangeVal");
var nsAutosaveIntervalInput = document.getElementById("settingsAutosaveIntervalVal");
nsExecTimeInput.value = Settings.CodeInstructionRunTime;
nsLogRangeInput.value = Settings.MaxLogCapacity;
nsPortRangeInput.value = Settings.MaxPortCapacity;
nsAutosaveIntervalInput.value = Settings.AutosaveInterval;
nsExecTimeInput.oninput = function() {
nsExecTime.innerHTML = this.value + 'ms';
Settings.CodeInstructionRunTime = this.value;
};
document.getElementById("settingsNSLogRangeVal").oninput = function() {
nsLogRangeInput.oninput = function() {
nsLogLimit.innerHTML = this.value;
Settings.MaxLogCapacity = this.value;
};
document.getElementById("settingsNSPortRangeVal").oninput = function() {
nsPortRangeInput.oninput = function() {
nsPortLimit.innerHTML = this.value;
Settings.MaxPortCapacity = this.value;
};
nsAutosaveIntervalInput.oninput = function() {
autosaveInterval.innerHTML = this.value;
Settings.AutosaveInterval = Number(this.value);
if (Number(this.value) === 0) {
Engine.Counters.autoSaveCounter = Infinity;
} else {
Engine.Counters.autoSaveCounter = Number(this.value) * 5;
}
};
document.getElementById("settingsSuppressMessages").onclick = function() {
Settings.SuppressMessages = this.checked;
};

@ -37,7 +37,7 @@ import {logBoxCreate} from "../utils/LogBox.js";
//If replace is true then spaces are replaced with "&nbsp;"
function post(input, replace=true) {
if (replace) {
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input.replace( / /g, "&nbsp;" ) + '</td></tr>');
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color); white-space:pre;">' + input.replace( / /g, "&nbsp;" ) + '</td></tr>');
} else {
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
}
@ -1634,6 +1634,9 @@ let Terminal = {
post("Defense: " + Player.defense + " / 1500");
post("Dexterity: " + Player.dexterity + " / 1500");
post("Agility: " + Player.agility + " / 1500");
break;
case Programs.BitFlume:
hackWorldDaemon(Player.bitNodeN, true);
break;
default:
post("Invalid executable. Cannot be run");

@ -1,6 +1,7 @@
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {gameOptionsBoxOpen, gameOptionsBoxClose}from "../utils/GameOptions.js";
import {clearEventListeners, createElement} from "../utils/HelperFunctions.js";
import {clearEventListeners, createElement,
removeChildrenFromElement} from "../utils/HelperFunctions.js";
import numeral from "../utils/numeral.min.js";
import {formatNumber,
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions.js";
@ -33,7 +34,7 @@ import {initLiterature} from "./Literature.js";
import {checkForMessagesToSend, initMessages} from "./Message.js";
import {inMission, currMission} from "./Missions.js";
import {initSingularitySFFlags,
hasSingularitySF} from "./NetscriptFunctions.js";
hasSingularitySF, hasCorporationSF} from "./NetscriptFunctions.js";
import {updateOnlineScriptTimes,
runScriptsLoop} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
@ -491,74 +492,88 @@ let Engine = {
/* Display character info */
displayCharacterInfo: function() {
removeChildrenFromElement(Engine.Display.characterInfo);
var companyPosition = "";
if (Player.companyPosition != "") {
companyPosition = Player.companyPosition.positionName;
}
var bnText = "";
if (Player.sourceFiles.length !== 0) {
bnText = "<br>Current BitNode: " + Player.bitNodeN;
}
var intText = "";
if (Player.intelligence > 0) {
intText = 'Intelligence: ' + (Player.intelligence).toLocaleString() + "<br><br><br>";
}
Engine.Display.characterInfo.innerHTML =
('<b>General</b><br><br>' +
'Current City: ' + Player.city + '<br><br>' +
'Employer: ' + Player.companyName + '<br>' +
'Job Title: ' + companyPosition + '<br><br>' +
'Money: $' + formatNumber(Player.money.toNumber(), 2)+ '<br><br><br>' +
'<b>Stats</b><br><br>' +
'Hacking Level: ' + (Player.hacking_skill).toLocaleString() +
" (" + numeral(Player.hacking_exp).format('(0.000a)') + ' experience)<br>' +
'Strength: ' + (Player.strength).toLocaleString() +
" (" + numeral(Player.strength_exp).format('(0.000a)') + ' experience)<br>' +
'Defense: ' + (Player.defense).toLocaleString() +
" (" + numeral(Player.defense_exp).format('(0.000a)')+ ' experience)<br>' +
'Dexterity: ' + (Player.dexterity).toLocaleString() +
" (" + numeral(Player.dexterity_exp).format('(0.000a)') + ' experience)<br>' +
'Agility: ' + (Player.agility).toLocaleString() +
" (" + numeral(Player.agility_exp).format('(0.000a)') + ' experience)<br>' +
'Charisma: ' + (Player.charisma).toLocaleString() +
" (" + numeral(Player.charisma_exp).format('(0.000a)') + ' experience)<br>' +
intText +
'<b>Multipliers</b><br><br>' +
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
'Hacking Money multiplier: ' + formatNumber(Player.hacking_money_mult * 100, 2) + '%<br>' +
'Hacking Growth multiplier: ' + formatNumber(Player.hacking_grow_mult * 100, 2) + '%<br><br>' +
'Hacking Level multiplier: ' + formatNumber(Player.hacking_mult * 100, 2) + '%<br>' +
'Hacking Experience multiplier: ' + formatNumber(Player.hacking_exp_mult * 100, 2) + '%<br><br>' +
'Strength Level multiplier: ' + formatNumber(Player.strength_mult * 100, 2) + '%<br>' +
'Strength Experience multiplier: ' + formatNumber(Player.strength_exp_mult * 100, 2) + '%<br><br>' +
'Defense Level multiplier: ' + formatNumber(Player.defense_mult * 100, 2) + '%<br>' +
'Defense Experience multiplier: ' + formatNumber(Player.defense_exp_mult * 100, 2) + '%<br><br>' +
'Dexterity Level multiplier: ' + formatNumber(Player.dexterity_mult * 100, 2) + '%<br>' +
'Dexterity Experience multiplier: ' + formatNumber(Player.dexterity_exp_mult * 100, 2) + '%<br><br>' +
'Agility Level multiplier: ' + formatNumber(Player.agility_mult * 100, 2) + '%<br>' +
'Agility Experience multiplier: ' + formatNumber(Player.agility_exp_mult * 100, 2) + '%<br><br>' +
'Charisma Level multiplier: ' + formatNumber(Player.charisma_mult * 100, 2) + '%<br>' +
'Charisma Experience multiplier: ' + formatNumber(Player.charisma_exp_mult * 100, 2) + '%<br><br>' +
'Hacknet Node production multiplier: ' + formatNumber(Player.hacknet_node_money_mult * 100, 2) + '%<br>' +
'Hacknet Node purchase cost multiplier: ' + formatNumber(Player.hacknet_node_purchase_cost_mult * 100, 2) + '%<br>' +
'Hacknet Node RAM upgrade cost multiplier: ' + formatNumber(Player.hacknet_node_ram_cost_mult * 100, 2) + '%<br>' +
'Hacknet Node Core purchase cost multiplier: ' + formatNumber(Player.hacknet_node_core_cost_mult * 100, 2) + '%<br>' +
'Hacknet Node level upgrade cost multiplier: ' + formatNumber(Player.hacknet_node_level_cost_mult * 100, 2) + '%<br><br>' +
'Company reputation gain multiplier: ' + formatNumber(Player.company_rep_mult * 100, 2) + '%<br>' +
'Faction reputation gain multiplier: ' + formatNumber(Player.faction_rep_mult * 100, 2) + '%<br>' +
'Salary multiplier: ' + formatNumber(Player.work_money_mult * 100, 2) + '%<br>' +
'Crime success multiplier: ' + formatNumber(Player.crime_success_mult * 100, 2) + '%<br>' +
'Crime money multiplier: ' + formatNumber(Player.crime_money_mult * 100, 2) + '%<br><br><br>' +
'<b>Misc</b><br><br>' +
'Servers owned: ' + Player.purchasedServers.length + '<br>' +
'Hacknet Nodes owned: ' + Player.hacknetNodes.length + '<br>' +
'Augmentations installed: ' + Player.augmentations.length + '<br>' +
'Time played since last Augmentation: ' + convertTimeMsToTimeElapsedString(Player.playtimeSinceLastAug) + '<br>' +
'Time played: ' + convertTimeMsToTimeElapsedString(Player.totalPlaytime) +
bnText + '<br><br><br>').replace( / /g, "&nbsp;" );
Engine.Display.characterInfo.appendChild(createElement("pre", {
innerHTML:
'<b>General</b><br><br>' +
'Current City: ' + Player.city + '<br><br>' +
'Employer: ' + Player.companyName + '<br>' +
'Job Title: ' + companyPosition + '<br><br>' +
'Money: $' + formatNumber(Player.money.toNumber(), 2)+ '<br><br><br>' +
'<b>Stats</b><br><br>' +
'Hacking Level: ' + (Player.hacking_skill).toLocaleString() +
" (" + numeral(Player.hacking_exp).format('(0.000a)') + ' experience)<br>' +
'Strength: ' + (Player.strength).toLocaleString() +
" (" + numeral(Player.strength_exp).format('(0.000a)') + ' experience)<br>' +
'Defense: ' + (Player.defense).toLocaleString() +
" (" + numeral(Player.defense_exp).format('(0.000a)')+ ' experience)<br>' +
'Dexterity: ' + (Player.dexterity).toLocaleString() +
" (" + numeral(Player.dexterity_exp).format('(0.000a)') + ' experience)<br>' +
'Agility: ' + (Player.agility).toLocaleString() +
" (" + numeral(Player.agility_exp).format('(0.000a)') + ' experience)<br>' +
'Charisma: ' + (Player.charisma).toLocaleString() +
" (" + numeral(Player.charisma_exp).format('(0.000a)') + ' experience)<br>' +
intText +
'<b>Multipliers</b><br><br>' +
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
'Hacking Money multiplier: ' + formatNumber(Player.hacking_money_mult * 100, 2) + '%<br>' +
'Hacking Growth multiplier: ' + formatNumber(Player.hacking_grow_mult * 100, 2) + '%<br><br>' +
'Hacking Level multiplier: ' + formatNumber(Player.hacking_mult * 100, 2) + '%<br>' +
'Hacking Experience multiplier: ' + formatNumber(Player.hacking_exp_mult * 100, 2) + '%<br><br>' +
'Strength Level multiplier: ' + formatNumber(Player.strength_mult * 100, 2) + '%<br>' +
'Strength Experience multiplier: ' + formatNumber(Player.strength_exp_mult * 100, 2) + '%<br><br>' +
'Defense Level multiplier: ' + formatNumber(Player.defense_mult * 100, 2) + '%<br>' +
'Defense Experience multiplier: ' + formatNumber(Player.defense_exp_mult * 100, 2) + '%<br><br>' +
'Dexterity Level multiplier: ' + formatNumber(Player.dexterity_mult * 100, 2) + '%<br>' +
'Dexterity Experience multiplier: ' + formatNumber(Player.dexterity_exp_mult * 100, 2) + '%<br><br>' +
'Agility Level multiplier: ' + formatNumber(Player.agility_mult * 100, 2) + '%<br>' +
'Agility Experience multiplier: ' + formatNumber(Player.agility_exp_mult * 100, 2) + '%<br><br>' +
'Charisma Level multiplier: ' + formatNumber(Player.charisma_mult * 100, 2) + '%<br>' +
'Charisma Experience multiplier: ' + formatNumber(Player.charisma_exp_mult * 100, 2) + '%<br><br>' +
'Hacknet Node production multiplier: ' + formatNumber(Player.hacknet_node_money_mult * 100, 2) + '%<br>' +
'Hacknet Node purchase cost multiplier: ' + formatNumber(Player.hacknet_node_purchase_cost_mult * 100, 2) + '%<br>' +
'Hacknet Node RAM upgrade cost multiplier: ' + formatNumber(Player.hacknet_node_ram_cost_mult * 100, 2) + '%<br>' +
'Hacknet Node Core purchase cost multiplier: ' + formatNumber(Player.hacknet_node_core_cost_mult * 100, 2) + '%<br>' +
'Hacknet Node level upgrade cost multiplier: ' + formatNumber(Player.hacknet_node_level_cost_mult * 100, 2) + '%<br><br>' +
'Company reputation gain multiplier: ' + formatNumber(Player.company_rep_mult * 100, 2) + '%<br>' +
'Faction reputation gain multiplier: ' + formatNumber(Player.faction_rep_mult * 100, 2) + '%<br>' +
'Salary multiplier: ' + formatNumber(Player.work_money_mult * 100, 2) + '%<br>' +
'Crime success multiplier: ' + formatNumber(Player.crime_success_mult * 100, 2) + '%<br>' +
'Crime money multiplier: ' + formatNumber(Player.crime_money_mult * 100, 2) + '%<br><br><br>' +
'<b>Misc</b><br><br>' +
'Servers owned: ' + Player.purchasedServers.length + '<br>' +
'Hacknet Nodes owned: ' + Player.hacknetNodes.length + '<br>' +
'Augmentations installed: ' + Player.augmentations.length + '<br>' +
'Time played since last Augmentation: ' + convertTimeMsToTimeElapsedString(Player.playtimeSinceLastAug) + '<br>' +
'Time played: ' + convertTimeMsToTimeElapsedString(Player.totalPlaytime),
}));
if (Player.sourceFiles.length !== 0) {
var index = "BitNode" + Player.bitNodeN;
Engine.Display.characterInfo.appendChild(createElement("p", {
width:"60%",
innerHTML:
"<br>Current BitNode: " + Player.bitNodeN + " (" + BitNodes[index].name + ")<br><br>",
}));
Engine.Display.characterInfo.appendChild(createElement("p", {
width:"60%", fontSize: "13px", marginLeft:"4%",
innerHTML:BitNodes[index].info,
}))
}
},
/* Display locations in the world*/
@ -589,8 +604,8 @@ let Engine = {
case Locations.Sector12:
Engine.sector12LocationsList.style.display = "inline";
//City hall only in BitNode-3
if (Player.bitNodeN === 3) {
//City hall only in BitNode-3/with Source-File 3
if (Player.bitNodeN === 3 || hasCorporationSF) {
document.getElementById("sector12-cityhall-li").style.display = "block";
} else {
document.getElementById("sector12-cityhall-li").style.display = "none";
@ -938,7 +953,14 @@ let Engine = {
checkCounters: function() {
if (Engine.Counters.autoSaveCounter <= 0) {
saveObject.saveGame(indexedDb);
Engine.Counters.autoSaveCounter = 300;
if (Settings.AutosaveInterval == null) {
Settings.AutosaveInterval = 60;
}
if (Settings.AutosaveInterval === 0) {
Engine.Counters.autoSaveCounter = Infinity;
} else {
Engine.Counters.autoSaveCounter = Settings.AutosaveInterval * 5;
}
}
if (Engine.Counters.updateSkillLevelsCounter <= 0) {
@ -1370,7 +1392,7 @@ let Engine = {
Engine.Display.missionContent.style.display = "none";
//Character info
Engine.Display.characterInfo = document.getElementById("character-info");
Engine.Display.characterInfo = document.getElementById("character-content");
//Location lists
Engine.aevumLocationsList = document.getElementById("aevum-locations-list");

@ -70,10 +70,13 @@ function createElement(type, params) {
if (params.display) {el.style.display = params.display;}
if (params.visibility) {el.style.visibility = params.visibility;}
if (params.margin) {el.style.margin = params.margin;}
if (params.marginLeft) {el.style.marginLeft = params.marginLeft;}
if (params.padding) {el.style.padding = params.padding;}
if (params.color) {el.style.color = params.color;}
if (params.border) {el.style.border = params.border;}
if (params.float) {el.style.cssFloat = params.float;}
if (params.fontSize) {el.style.fontSize = params.fontSize;}
if (params.width) {el.style.width = params.width;}
if (params.backgroundColor) {
el.style.backgroundColor = params.backgroundColor
}