diff --git a/src/js/economyJS.js b/src/js/economyJS.js index ac469bcb3f6e185b26111c9a110e3d97f0ccd518..08dbf711dbe67868cb43218f70f6f1e9597c3d2c 100644 --- a/src/js/economyJS.js +++ b/src/js/economyJS.js @@ -534,9 +534,12 @@ window.calculateCosts = (function() { return costs; } - // The amount of slaves served by a servant + /** + * The amount of slaves served by a servant + * @param {App.Entity.SlaveState} slave + */ function getSlaveMinorCosts(slave) { - let effectiveness; + let effectiveness = 0; if (slave.trust < -20) { effectiveness = 80; } else if (slave.devotion < -20) { @@ -1166,7 +1169,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef } else { V.Madam.skill.madam += jsRandom(1, Math.ceil((V.Madam.intelligence + V.Madam.intelligenceImplant) / 15) + 8); } - if (V.Madam.intelligence+V.Madam.intelligenceImplant > 15) { + if (V.Madam.intelligence + V.Madam.intelligenceImplant > 15) { // $He is a clever manager. V.MadamCashBonus += 0.05 * Math.floor((V.Madam.intelligence + V.Madam.intelligenceImplant) / 32); } @@ -1180,7 +1183,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef V.MadamCashBonus -= 0.05; } else if (V.familyTesting === 1 && areRelated(V.Madam, V.slaves[i]) > 0) { V.MadamCashBonus += 0.05; - } else if ( V.Madam.relationTarget === V.slaves[i].ID && $familyTesting === 0) { + } else if (V.Madam.relationTarget === V.slaves[i].ID && V.familyTesting === 0) { V.MadamCashBonus += 0.05; } if (V.slaves[i].prestigeDesc === "$He is a famed Free Cities whore, and commands top prices.") { @@ -1188,11 +1191,11 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef } else if (V.slaves[i].prestigeDesc === "$He is a famed Free Cities slut, and can please anyone.") { V.MadamCashBonus += 0.15; } else if (V.slaves[i].prestigeDesc === "$He is remembered for winning best in show as a dairy cow.") { - if ($arcologies[0].FSPhysicalIdealist !== "unset") { - if (V.slaves[i].muscles > 60 && V.slaves[i].weight < 30 && V.slaves[i].lactation > 0 && V.slaves[i].boobs-V.slaves[i].boobsImplant > 6000) { + if (V.arcologies[0].FSPhysicalIdealist !== "unset") { + if (V.slaves[i].muscles > 60 && V.slaves[i].weight < 30 && V.slaves[i].lactation > 0 && V.slaves[i].boobs - V.slaves[i].boobsImplant > 6000) { V.MadamCashBonus += 0.15; } - } else if (V.slaves[i].lactation > 0 && V.slaves[i].boobs-V.slaves[i].boobsImplant > 6000) { + } else if (V.slaves[i].lactation > 0 && V.slaves[i].boobs - V.slaves[i].boobsImplant > 6000) { V.MadamCashBonus += 0.10; } } else if (V.slaves[i].prestigeDesc === "$He is remembered for winning best in show as a cockmilker.") { @@ -1382,7 +1385,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef } else { let canA = canDoAnal(s); let canV = canDoVaginal(s); - let skilltarget = (100 + ((s.skill.anal - 100)*canA*(1.5 - 0.5*canV) + (s.skill.vaginal - 100)*canV*(1.5 - 0.5*canA) + (s.skill.oral - 100)*(3 - 1.5*canA - 1.5*canV + canA*canV))*3/10); + let skilltarget = (100 + ((s.skill.anal - 100) * canA * (1.5 - 0.5 * canV) + (s.skill.vaginal - 100) * canV * (1.5 - 0.5 * canA) + (s.skill.oral - 100) * (3 - 1.5 * canA - 1.5 * canV + canA * canV)) * 3 / 10); // Complicated, I know - but it should automatically account for what acts are possible to scale the injury risk smoothly between 90% when totally unskilled // and 0% when perfectly skilled in the relevant method or methods. @@ -1458,6 +1461,13 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef } } + /** + * @param {App.Entity.SlaveState} s + * @param {number} lowerClassSexDemandRef + * @param {number} middleClassSexDemandRef + * @param {number} upperClassSexDemandRef + * @param {number} topClassSexDemandRef + */ function SJVBrothel(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) { let toTheBrothel = 0; let beautyMultiplier = 1; @@ -1467,7 +1477,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef if (s.sexualFlaw === "neglectful") { beautyMultiplier += 0.1; } - if ((s.hears === -1 && s.earwear !== "hearing aids") || (s.hears === 0 && s.earwear === "muffling ear plugs") ||(s.hears === -2)) { + if ((s.hears === -1 && s.earwear !== "hearing aids") || (s.hears === 0 && s.earwear === "muffling ear plugs") || (s.hears === -2)) { if (!canHear(s)) { beautyMultiplier -= 0.25; } else { @@ -1570,7 +1580,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef } else { let canA = canDoAnal(s); let canV = canDoVaginal(s); - let skilltarget = (100 + ((s.skill.anal - 100)*canA*(1.5 - 0.5*canV) + (s.skill.vaginal - 100)*canV*(1.5 - 0.5*canA) + (s.skill.oral - 100)*(3 - 1.5*canA - 1.5*canV + canA*canV))*3/10); + let skilltarget = (100 + ((s.skill.anal - 100) * canA * (1.5 - 0.5 * canV) + (s.skill.vaginal - 100) * canV * (1.5 - 0.5 * canA) + (s.skill.oral - 100) * (3 - 1.5 * canA - 1.5 * canV + canA * canV)) * 3 / 10); // Complicated, I know - but it should automatically account for what acts are possible to scale the injury risk smoothly between 90% when totally unskilled // and 0% when perfectly skilled in the relevant method or methods. @@ -1635,8 +1645,15 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef s.sexQuality = 2; } - // The whoreScore function finds the appropriate customer class and then calculates the whore income stats associated with that class and adds to the class supply. - // whoreClass is the MAXIMUM player set class the whore is allowed to service, if the whore is not eligable it will service the highest it is capable of servicing properly. A whoreClass of 0 means it is on auto (always service the highest possible class). + /** + * The whoreScore function finds the appropriate customer class and then calculates the whore income stats associated with that class and adds to the class supply. + * whoreClass is the MAXIMUM player set class the whore is allowed to service, if the whore is not eligable it will service the highest it is capable of servicing properly. A whoreClass of 0 means it is on auto (always service the highest possible class). + * @param {App.Entity.SlaveState} s + * @param {number} lowerClassSexDemandRef + * @param {number} middleClassSexDemandRef + * @param {number} upperClassSexDemandRef + * @param {number} topClassSexDemandRef + */ function whoreScore(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) { let income = s.sexAmount * s.sexQuality; const initialHealthPenalty = healthPenalty(s); @@ -1644,8 +1661,6 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef s.maxWhoreClass = s.effectiveWhoreClass; income *= initialHealthPenalty; - - // Automatically changing effectiveWhoreClass // what is the initial effective whore class? Are we providing more sex than overal demand? Is the ratio of supply/demand for this tier higher than the one below it? // This also takes into consideration public sluts and ignores the NPC market and arcades @@ -1669,15 +1684,15 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef // Calculate the stats if (s.effectiveWhoreClass === 4) { - s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (1/3)), normalRandInt(30, 2), normalRandInt(60, 3)); // Bringing sex amount into the desired range. Beauty improves use amount between values of aprox. 90 and 180. + s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (1 / 3)), normalRandInt(30, 2), normalRandInt(60, 3)); // Bringing sex amount into the desired range. Beauty improves use amount between values of aprox. 90 and 180. tiredFucks(s); // adding tiredness based on number of fucks and then adjusting income in case the tiredness penalty changed as a result. if (healthPenalty(s) < initialHealthPenalty) { income *= healthPenalty(s) / initialHealthPenalty; } - s.sexQuality = Math.min(Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)), Math.trunc(V.whoreBudget.topClass * (1/3))); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier. The top class will pay a maximum of 33% of their weekly budget per service. + s.sexQuality = Math.min(Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)), Math.trunc(V.whoreBudget.topClass * (1 / 3))); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier. The top class will pay a maximum of 33% of their weekly budget per service. slaveJobValues.brothel.topClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.topClass * 0.2)); // Registering the job value in the right slot } else if (s.effectiveWhoreClass === 3) { - s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (2/3)), normalRandInt(40, 3), normalRandInt(80, 3)); // Beauty improves use amount between values of aprox. 60 and 120. + s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (2 / 3)), normalRandInt(40, 3), normalRandInt(80, 3)); // Beauty improves use amount between values of aprox. 60 and 120. tiredFucks(s); if (healthPenalty(s) < initialHealthPenalty) { income *= healthPenalty(s) / initialHealthPenalty; @@ -1719,6 +1734,10 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef return slaveJobValues; }; +/** + * @param {App.Entity.SlaveState} s + * @returns {number} + */ window.effectiveWhoreClass = function(s) { let score = s.sexAmount * s.sexQuality; let result; @@ -1741,6 +1760,11 @@ window.effectiveWhoreClass = function(s) { return result; }; +/** + * @param {App.Entity.SlaveState} s + * @param {Object|undefined} facility + * @returns {Object} + */ window.getSlaveStatisticData = function(s, facility) { if (!facility) { // Base data, even without facility return { @@ -1928,29 +1952,29 @@ Number.prototype.toFixedHTML = function() { }; window.SectorCounts = function() { - V.Sweatshops = 0; // Ternaries: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator - V.AProsperityCapModified = V.AProsperityCapModified > 0 ? V.AProsperityCapModified : 0; - const caps = [ - {upgrade: "drones", cap: 10}, - {upgrade: "hydro", cap: 30}, - {upgrade: "apron", cap: 60}, - {upgrade: "grid", cap: 100}, - {upgrade: "spire", cap: 150}]; - - V.AProsperityCap = 0; - caps.forEach(cap => { + V.Sweatshops = 0; // Ternaries: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator + V.AProsperityCapModified = V.AProsperityCapModified > 0 ? V.AProsperityCapModified : 0; + const caps = [ + {upgrade: "drones", cap: 10}, + {upgrade: "hydro", cap: 30}, + {upgrade: "apron", cap: 60}, + {upgrade: "grid", cap: 100}, + {upgrade: "spire", cap: 150}]; + + V.AProsperityCap = 0; + caps.forEach(cap => { if (V.arcologyUpgrade[cap.upgrade] > 0) { V.AProsperityCap = cap.cap; } - }); + }); - for (let i = 0; i < V.sectors.length; i++) { + for (let i = 0; i < V.sectors.length; i++) { if (V.sectors[i].type.includes("Apartments")) { V.AProsperityCap += V.sectors[i].type.includes("Luxury") ? 15 : 10; } else if (V.sectors[i].type.includes("Sweatshops")) { V.Sweatshops++; } - } + } - V.AProsperityCap += V.AProsperityCapModified; + V.AProsperityCap += V.AProsperityCapModified; }; diff --git a/src/js/generateGenetics.js b/src/js/generateGenetics.js index 7e4993b7b1fe3c00d3987e9fe60597800da01513..548d119fb77dd6a6e779fdefc0974dda29ee7e32 100644 --- a/src/js/generateGenetics.js +++ b/src/js/generateGenetics.js @@ -12,8 +12,14 @@ window.generateGenetics = (function() { // intelligence and face parameters are the same so we can use the same distribution for both values // clamping makes edge values (-100, 100) more likely; this is expected behavior // please see https://gitgud.io/pregmodfan/fc-pregmod/issues/852 - const fuzzy = (a, b) => Math.clamp(normalRandInt((a+b)/2, 20), -100, 100); + const fuzzy = (a, b) => Math.clamp(normalRandInt((a + b) / 2, 20), -100, 100); + /** + * @param {App.Entity.SlaveState} actor1 + * @param {number} actor2 Slave ID of actor 2 + * @param {number} x + * @returns + */ function generateGenetics(actor1, actor2, x) { genes = { gender: "XX", @@ -38,7 +44,8 @@ window.generateGenetics = (function() { underArmHStyle: "bushy", clone: 0, cloneID: 0, - geneticQuirks: 0 + geneticQuirks: {}, + fetish: "none" }; if (actor1.ID > 0) { mother = V.genePool.find(s => s.ID === actor1.ID); @@ -658,7 +665,13 @@ window.generateGenetics = (function() { return shape; } - // genetic quirks + /** + * Genetic quirks + * @param {App.Entity.SlaveState|number} father + * @param {App.Entity.SlaveState} mother + * @param {string} sex + * @returns {Object} + */ function setGeneticQuirks(father, mother, sex) { let quirks = { macromastia: 0, @@ -852,7 +865,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.pFace = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.pFace = 1; } } @@ -866,7 +879,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.uFace = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.uFace = 1; } } @@ -880,7 +893,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.gigantism = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.gigantism = 1; } } @@ -894,7 +907,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.dwarfism = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.dwarfism = 1; } } @@ -908,7 +921,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.albinism = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.albinism = 1; } } @@ -922,7 +935,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.heterochromia = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.heterochromia = 1; } } @@ -936,7 +949,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.rearLipedema = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.rearLipedema = 1; } } @@ -950,7 +963,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.gigantomastia = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.gigantomastia = 1; } } @@ -964,7 +977,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.macromastia = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.macromastia = 1; } } @@ -978,7 +991,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.mGain = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.mGain = 1; } } @@ -992,7 +1005,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.mLoss = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.mLoss = 1; } } @@ -1006,7 +1019,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.wGain = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.wGain = 1; } } @@ -1020,7 +1033,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.wLoss = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.wLoss = 1; } } @@ -1034,7 +1047,7 @@ window.generateGenetics = (function() { chance = jsRandom(1, 16); if (chance <= genetarget) { quirks.androgyny = 2; - } else if (chance <= 3*genetarget) { + } else if (chance <= 3 * genetarget) { quirks.androgyny = 1; } } @@ -1045,6 +1058,9 @@ window.generateGenetics = (function() { return generateGenetics; })(); +/** + * @param {App.Entity.SlaveState} mother + */ window.generateChild = function(mother, ova, destination) { let genes = ova.genetics; // maybe just argument this? We'll see. let pregUpgrade = V.pregnancyMonitoringUpgrade;