Merge pull request #180 from danielyxie/dev

Bugfixes for Corporations. hacknetnodes now accounts for RAM usage. S…
This commit is contained in:
danielyxie 2018-01-29 23:21:00 -06:00 committed by GitHub
commit 49eeeeec52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 628 additions and 1661 deletions

2168
dist/bundle.js vendored

File diff suppressed because it is too large Load Diff

@ -353,7 +353,7 @@ Product.prototype.finishProduct = function(employeeProd, industry) {
var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100); var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100);
console.log("advMult: " + advMult); console.log("advMult: " + advMult);
this.mku = 100 / (advMult * this.qlt * (busRatio + mgmtRatio)); this.mku = 100 / (advMult * this.qlt * (busRatio + mgmtRatio));
this.dmd = industry.awareness === 0 ? 100 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness))); this.dmd = industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness)));
this.cmp = getRandomInt(0, 70); this.cmp = getRandomInt(0, 70);
//Calculate the product's required materials //Calculate the product's required materials
@ -880,10 +880,18 @@ Industry.prototype.process = function(marketCycles=1, state, company) {
//At the start of a cycle, store and reset revenue/expenses //At the start of a cycle, store and reset revenue/expenses
//Then calculate salaries and processs the markets //Then calculate salaries and processs the markets
if (state === "START") { if (state === "START") {
if (this.thisCycleRevenue.isNaN() || this.thisCycleExpenses.isNaN()) {
console.log("ERROR: NaN in Corporation's computed revenue/expenses");
console.log(this.thisCycleRevenue.toString());
console.log(this.thisCycleExpenses.toString());
dialogBoxCreate("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer");
this.thisCycleRevenue = new Decimal(0);
this.thisCycleExpenses = new Decimal(0);
}
this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * SecsPerMarketCycle); this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * SecsPerMarketCycle);
this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * SecsPerMarketCycle); this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * SecsPerMarketCycle);
this.thisCycleRevenue = this.thisCycleRevenue.times(0); this.thisCycleRevenue = new Decimal(0);
this.thisCycleExpenses = this.thisCycleExpenses.times(0); this.thisCycleExpenses = new Decimal(0);
//Process offices (and the employees in them) //Process offices (and the employees in them)
var employeeSalary = 0; var employeeSalary = 0;
@ -922,6 +930,7 @@ Industry.prototype.process = function(marketCycles=1, state, company) {
res = this.processProducts(marketCycles, company); res = this.processProducts(marketCycles, company);
this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]); this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]); this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
} }
//Process change in demand and competition for this industry's materials //Process change in demand and competition for this industry's materials
@ -961,14 +970,16 @@ Industry.prototype.processProductMarket = function(marketCycles=1) {
for (var name in this.products) { for (var name in this.products) {
if (this.products.hasOwnProperty(name)) { if (this.products.hasOwnProperty(name)) {
var product = this.products[name]; var product = this.products[name];
var change = getRandomInt(1, 5) * 0.001; var change = getRandomInt(1, 4) * 0.0005;
if (this.type === Industries.Pharmaceutical || this.type === Industries.Software || if (this.type === Industries.Pharmaceutical || this.type === Industries.Software ||
this.type === Industries.Robotics) { this.type === Industries.Robotics) {
change *= 2.5; change *= 3;
} }
change *= marketCycles; change *= marketCycles;
product.dmd -= change; product.dmd -= change;
product.cmp += change; product.cmp += change;
product.cmp = Math.min(product.cmp, 99.99);
product.dmd = Math.max(product.dmd, 0.001);
} }
} }
} }
@ -1062,6 +1073,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
} }
} }
} }
if (producableFrac <= 0) {producableFrac = 0; prod = 0;}
//Make our materials if they are producable //Make our materials if they are producable
if (producableFrac > 0 && prod > 0) { if (producableFrac > 0 && prod > 0) {
@ -1080,7 +1092,14 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
Math.pow(this.sciResearch.qty, this.sciFac) + Math.pow(this.sciResearch.qty, this.sciFac) +
Math.pow(warehouse.materials["AICores"].qty, this.aiFac) / 10e3); Math.pow(warehouse.materials["AICores"].qty, this.aiFac) / 10e3);
} }
} else {
for (var reqMatName in this.reqMats) {
if (this.reqMats.hasOwnProperty(reqMatName)) {
warehouse.materials[reqMatName].prd = 0;
}
}
} }
//Per second //Per second
var fooProd = prod * producableFrac / (SecsPerMarketCycle * marketCycles); var fooProd = prod * producableFrac / (SecsPerMarketCycle * marketCycles);
for (var fooI = 0; fooI < this.prodMats.length; ++fooI) { for (var fooI = 0; fooI < this.prodMats.length; ++fooI) {
@ -1125,7 +1144,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
} }
var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]); var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
var maxSell = (mat.qlt + .001) * mat.dmd * (100 - mat.cmp)/100 * markup * businessFactor * var maxSell = (mat.qlt + .001) * mat.dmd * (100 - mat.cmp)/100 * markup * businessFactor *
Math.pow(this.awareness + 1, 0.05) * Math.pow(this.popularity + 1, 0.07) * Math.pow(this.awareness + 1, 0.05) * Math.pow(this.popularity + 1, 0.07) * company.getSalesMultiplier() *
(this.awareness === 0 ? 0.01 : Math.max((this.popularity + .001) / this.awareness, 0.01)); (this.awareness === 0 ? 0.01 : Math.max((this.popularity + .001) / this.awareness, 0.01));
var sellAmt; var sellAmt;
@ -1135,7 +1154,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
} else { } else {
sellAmt = maxSell; sellAmt = maxSell;
} }
sellAmt = (sellAmt * company.getSalesMultiplier() * SecsPerMarketCycle * marketCycles); sellAmt = (sellAmt * SecsPerMarketCycle * marketCycles);
sellAmt = Math.min(mat.qty, sellAmt); sellAmt = Math.min(mat.qty, sellAmt);
if (sellAmt < 0) { if (sellAmt < 0) {
console.log("ERROR: sellAmt is negative"); console.log("ERROR: sellAmt is negative");
@ -1254,15 +1273,21 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio
switch(this.state) { switch(this.state) {
case "PRODUCTION": case "PRODUCTION":
//Calculate the maximum production of this Product based on //Calculate the maximum production of this material based
//office's productivity, materials, etc. //on the office's productivity
var total = office.employeeProd[EmployeePositions.Operations] + var total = office.employeeProd[EmployeePositions.Operations] +
office.employeeProd[EmployeePositions.Engineer] + office.employeeProd[EmployeePositions.Engineer] +
office.employeeProd[EmployeePositions.Management]; office.employeeProd[EmployeePositions.Management], ratio;
var ratio = (office.employeeProd[EmployeePositions.Operations] / total) * if (total === 0) {
ratio = 0;
} else {
ratio = (office.employeeProd[EmployeePositions.Operations] / total) *
(office.employeeProd[EmployeePositions.Engineer] / total) * (office.employeeProd[EmployeePositions.Engineer] / total) *
(office.employeeProd[EmployeePositions.Management] / total); (office.employeeProd[EmployeePositions.Management] / total);
var maxProd = ratio * Math.pow(total, 0.2), prod; ratio = Math.max(0.01, ratio); //Minimum ratio value if you have employees
}
var maxProd = ratio * Math.pow(total, 0.2) *
corporation.getProductionMultiplier() * this.prodMult, prod;
//Account for whether production is manually limited //Account for whether production is manually limited
if (product.prdman[city][0]) { if (product.prdman[city][0]) {
@ -1270,7 +1295,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio
} else { } else {
prod = maxProd; prod = maxProd;
} }
prod *= (this.prodMult * corporation.getProductionMultiplier() * SecsPerMarketCycle * marketCycles); prod *= (SecsPerMarketCycle * marketCycles);
//Calculate net change in warehouse storage making the Products will cost //Calculate net change in warehouse storage making the Products will cost
@ -1300,7 +1325,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio
} }
//Make our Products if they are producable //Make our Products if they are producable
if (producableFrac > 0) { if (producableFrac > 0 && prod > 0) {
for (var reqMatName in product.reqMats) { for (var reqMatName in product.reqMats) {
if (product.reqMats.hasOwnProperty(reqMatName)) { if (product.reqMats.hasOwnProperty(reqMatName)) {
var reqMatQtyNeeded = (product.reqMats[reqMatName] * prod * producableFrac); var reqMatQtyNeeded = (product.reqMats[reqMatName] * prod * producableFrac);
@ -1335,9 +1360,9 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio
} }
} }
var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]); var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
var maxSell = Math.pow(product.rat, 0.95) * product.dmd * (1-(product.cmp/100)) * var maxSell = Math.pow(product.rat, 0.95) * product.dmd * (1-(product.cmp/100)) * corporation.getSalesMultiplier() *
markup * businessFactor * Math.pow(this.awareness + 1, 0.05) * Math.pow(this.popularity + 1, 0.07) * markup * businessFactor * Math.pow(this.awareness + 1, 0.05) * Math.pow(this.popularity + 1, 0.07) *
(this.awareness === 0 ? 0.01 : Math.max((this.popularity + .001) / this.awareness, 0.01)); (this.awareness === 0 ? 0.01 : Math.max((this.popularity + .001) / this.awareness, 0.01)) ;
var sellAmt; var sellAmt;
if (product.sllman[city][0] && product.sllman[city][1] > 0) { if (product.sllman[city][0] && product.sllman[city][1] > 0) {
//Sell amount is manually limited //Sell amount is manually limited
@ -1345,7 +1370,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio
} else { } else {
sellAmt = maxSell; sellAmt = maxSell;
} }
sellAmt = sellAmt * corporation.getSalesMultiplier() * SecsPerMarketCycle * marketCycles; sellAmt = sellAmt * SecsPerMarketCycle * marketCycles;
sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty
if (sellAmt && product.sCost) { if (sellAmt && product.sCost) {
product.data[city][0] -= sellAmt; //data[0] is qty product.data[city][0] -= sellAmt; //data[0] is qty
@ -2305,6 +2330,13 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
} }
//Completed products //Completed products
var cmpAndDmdText = "";
if (company.unlockUpgrades[2] === 1) {
cmpAndDmdText += "<br>Competition: " + formatNumber(product.cmp, 3);
}
if (company.unlockUpgrades[3] === 1) {
cmpAndDmdText += "<br>Demand: " + formatNumber(product.dmd, 3);
}
var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale
div.appendChild(createElement("p", { div.appendChild(createElement("p", {
innerHTML: "<p class='tooltip'>" + product.name + ": " + formatNumber(product.data[city][0], 3) + //Quantity innerHTML: "<p class='tooltip'>" + product.name + ": " + formatNumber(product.data[city][0], 3) + //Quantity
@ -2317,7 +2349,8 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
"Durability: " + formatNumber(product.dur, 3) + "<br>" + "Durability: " + formatNumber(product.dur, 3) + "<br>" +
"Reliability: " + formatNumber(product.rel, 3) + "<br>" + "Reliability: " + formatNumber(product.rel, 3) + "<br>" +
"Aesthetics: " + formatNumber(product.aes, 3) + "<br>" + "Aesthetics: " + formatNumber(product.aes, 3) + "<br>" +
"Features: " + formatNumber(product.fea, 3) + "</span></p><br>" + "Features: " + formatNumber(product.fea, 3) +
cmpAndDmdText + "</span></p><br>" +
"<p class='tooltip'>Est. Production Cost: " + numeral(product.pCost).format("$0.000a") + "<p class='tooltip'>Est. Production Cost: " + numeral(product.pCost).format("$0.000a") +
"<span class='tooltiptext'>An estimate of how much it costs to produce one unit of this product. " + "<span class='tooltiptext'>An estimate of how much it costs to produce one unit of this product. " +
"If your sell price exceeds this by too much, people won't buy your product. The better your " + "If your sell price exceeds this by too much, people won't buy your product. The better your " +
@ -2523,9 +2556,9 @@ var CorporationUnlockUpgrades = {
// name, desc] // name, desc]
var CorporationUpgrades = { var CorporationUpgrades = {
//Smart factories, increases production //Smart factories, increases production
"0": [0, 2e9, 1.07, 0.02, "0": [0, 2e9, 1.07, 0.03,
"Smart Factories", "Advanced AI automatically optimizes the operation and productivity " + "Smart Factories", "Advanced AI automatically optimizes the operation and productivity " +
"of factories. Each level of this upgrade increases your global production by 2% (additive)."], "of factories. Each level of this upgrade increases your global production by 3% (additive)."],
//Smart warehouses, increases storage size //Smart warehouses, increases storage size
"1": [1, 2e9, 1.07, .1, "1": [1, 2e9, 1.07, .1,
@ -2569,7 +2602,7 @@ var CorporationUpgrades = {
"of this upgrade globally increases the efficiency of your employees by 10% (additive)."], "of this upgrade globally increases the efficiency of your employees by 10% (additive)."],
//Improves sales of materials/products //Improves sales of materials/products
"8": [8, 1e9, 1.09, 0.01, "8": [8, 1e9, 1.08, 0.01,
"ABC SalesBots", "Always Be Closing. Purchase these robotic salesmen to increase the amount of " + "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 " + "materials and products you sell. Each level of this upgrade globally increases your sales " +
"by 1% (additive)."], "by 1% (additive)."],
@ -2624,14 +2657,20 @@ Corporation.prototype.process = function(numCycles=1) {
//At the start of a new cycle, calculate profits from previous cycle //At the start of a new cycle, calculate profits from previous cycle
if (state === "START") { if (state === "START") {
this.revenue = this.revenue.times(0); this.revenue = new Decimal(0);
this.expenses = this.expenses.times(0); this.expenses = new Decimal(0);
this.divisions.forEach((ind)=>{ this.divisions.forEach((ind)=>{
this.revenue = this.revenue.plus(ind.lastCycleRevenue); this.revenue = this.revenue.plus(ind.lastCycleRevenue);
this.expenses = this.expenses.plus(ind.lastCycleExpenses); this.expenses = this.expenses.plus(ind.lastCycleExpenses);
}); });
var profit = this.revenue.minus(this.expenses); var profit = this.revenue.minus(this.expenses);
var cycleProfit = profit.times(marketCycles * SecsPerMarketCycle); var cycleProfit = profit.times(marketCycles * SecsPerMarketCycle);
if (this.funds.isNaN()) {
dialogBoxCreate("There was an error calculating your Corporations funds and they got reset to 0. " +
"This is a bug. Please report to game developer.<br><br>" +
"(Your funds have been set to $150b for the inconvenience)");
this.funds = new Decimal(150e9);
}
this.funds = this.funds.plus(cycleProfit); this.funds = this.funds.plus(cycleProfit);
this.updateSharePrice(); this.updateSharePrice();
} }
@ -2678,7 +2717,7 @@ Corporation.prototype.getInvestment = function() {
case 4: case 4:
return; return;
} }
var funding = val * percShares * 2, var funding = val * percShares * 4,
investShares = Math.floor(TOTALSHARES * percShares), investShares = Math.floor(TOTALSHARES * percShares),
yesBtn = yesNoBoxGetYesButton(), yesBtn = yesNoBoxGetYesButton(),
noBtn = yesNoBoxGetNoButton(); noBtn = yesNoBoxGetNoButton();

@ -59,7 +59,7 @@ let CONSTANTS = {
ScriptFileExistsRamCost: 0.1, ScriptFileExistsRamCost: 0.1,
ScriptIsRunningRamCost: 0.1, ScriptIsRunningRamCost: 0.1,
ScriptPurchaseHacknetRamCost: 1.5, ScriptPurchaseHacknetRamCost: 1.5,
ScriptHacknetNodesRamCost: 1.0, //Base cost for accessing hacknet nodes array ScriptHacknetNodesRamCost: 4.0, //Base cost for accessing hacknet nodes array
ScriptHNUpgLevelRamCost: 0.4, ScriptHNUpgLevelRamCost: 0.4,
ScriptHNUpgRamRamCost: 0.6, ScriptHNUpgRamRamCost: 0.6,
ScriptHNUpgCoreRamCost: 0.8, ScriptHNUpgCoreRamCost: 0.8,
@ -1121,24 +1121,24 @@ let CONSTANTS = {
"---Rebalancing: Made many upgrades/purchases cheaper. Receive more money from investors in early stage. Company valuation is higher after going public<br>" + "---Rebalancing: Made many upgrades/purchases cheaper. Receive more money from investors in early stage. Company valuation is higher after going public<br>" +
"---Multiple bug fixes<br>" + "---Multiple bug fixes<br>" +
"-Added rm() Netscript function<br>" + "-Added rm() Netscript function<br>" +
"-Updated the way script RAM usage is calculated. Now, a function only increases RAM usage the " + "-Updated the way script RAM usage is calculated. Now, a function only increases RAM usage the first time it is called. i.e. even if you call hack() multiple times in a script, it only counts against RAM usage once. The same change applies for while/for loops and if conditionals.<br>" +
"first time it is called. i.e. even if you call hack() multiple times in a script, it only counts " +
"against RAM usage once. The same change applies for while/for loops and if conditionals.<br>" +
"-The RAM cost of the following were increased:<br>" + "-The RAM cost of the following were increased:<br>" +
"---If statements: increased by 0.05GB<br>" + "---If statements: increased by 0.05GB<br>" +
"---run() and exec(): increased by 0.2GB<br>" + "---run() and exec(): increased by 0.2GB<br>" +
"---scp(): increased by 0.1GB<br>" + "---scp(): increased by 0.1GB<br>" +
"---purchaseServer(): increased by 0.25GB<br>" + "---purchaseServer(): increased by 0.25GB<br>" +
"-Note: You may need to re-save all of your scripts in order to re-calculate their RAM usages. Otherwise, " + "-Note: You may need to re-save all of your scripts in order to re-calculate their RAM usages. Otherwise, it should automatically be re-calculated when you reset/prestige<br>" +
"it should automatically be re-calculated when you reset/prestige<br>" +
"-The cost to upgrade your home computer's RAM has been increased (both the base cost and the exponential upgrade multiplier)<br>" + "-The cost to upgrade your home computer's RAM has been increased (both the base cost and the exponential upgrade multiplier)<br>" +
"-The cost of purchasing a server was increased by 10% (it is now $55k per RAM)<br>" + "-The cost of purchasing a server was increased by 10% (it is now $55k per RAM)<br>" +
"-Bug fix: (Hopefully) removed an exploit where you could avoid RAM usage for Netscript function calls " + "-Bug fix: (Hopefully) removed an exploit where you could avoid RAM usage for Netscript function calls by assigning functions to a variable (foo = hack(); foo('helios');)<br>" +
"by assigning functions to a variable (foo = hack(); foo('helios');)<br>" + "-Bug fix: (Hopefully) removed an exploit where you could run arbitrary Javascript code using the constructor() method<br>" +
"-Bug fix: (Hopefully) removed an exploit where you could run arbitrary Javascript code using the constructor() " +
"method<br>" +
"-Thanks to Github user mateon1 and Reddit users havoc_mayhem and spaceglace for notifying me of the above exploits<br>" + "-Thanks to Github user mateon1 and Reddit users havoc_mayhem and spaceglace for notifying me of the above exploits<br>" +
"-The fileExists() Netscript function now works on text files (.txt). Thanks to Github user devoidfury for this<br>" "-The fileExists() Netscript function now works on text files (.txt). Thanks to Github user devoidfury for this<br><br>" +
"v0.34.3<br>" +
"-Minor balance changes to Corporation. Upgrades are generally cheaper and/or have more powerful effects. " +
"You will receive more funding while your are a private company. "
"-Accessing the hacknetnodes array in Netscript now costs 4.0GB of RAM (only counts against RAM usage once)<br>"
} }
export {CONSTANTS}; export {CONSTANTS};

@ -1164,7 +1164,7 @@ function NetscriptFunctions(workerScript) {
return CONSTANTS.ScriptPurchaseHacknetRamCost; return CONSTANTS.ScriptPurchaseHacknetRamCost;
} }
} }
purchaseHacknet(); return purchaseHacknet();
}, },
getStockPrice : function(symbol) { getStockPrice : function(symbol) {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {

@ -296,7 +296,6 @@ function calculateRamUsage(codeCopy) {
try { try {
var ast = parse(codeCopy); var ast = parse(codeCopy);
} catch(e) { } catch(e) {
console.log("returning -1 bc parsing error: " + e.toString());
return -1; return -1;
} }
@ -339,7 +338,9 @@ function calculateRamUsage(codeCopy) {
if (typeof func === "function") { if (typeof func === "function") {
try { try {
var res = func.apply(null, []); var res = func.apply(null, []);
if (!isNaN(res)) {ramUsage += res;} if (typeof res === "number") {
ramUsage += res;
}
} catch(e) { } catch(e) {
console.log("ERROR applying function: " + e); console.log("ERROR applying function: " + e);
} }
@ -358,6 +359,11 @@ function calculateRamUsage(codeCopy) {
} }
} }
} }
//Special case: hacknetnodes array
if (codeCopy.includes("hacknetnodes")) {
ramUsage += CONSTANTS.ScriptHacknetNodesRamCost;
}
return ramUsage; return ramUsage;
} }