diff --git a/src/endWeek/saServeThePublic.js b/src/endWeek/saServeThePublic.js index 31c680d7ee87c868648cf9f71726173da2951092..0374d5bf3e8ace382e3a2016fce06907fc9b9c5e 100644 --- a/src/endWeek/saServeThePublic.js +++ b/src/endWeek/saServeThePublic.js @@ -532,6 +532,10 @@ window.saServeThePublic = (function saServeThePublic() { skillIncrease = (10 + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)); r += ` ${SkillIncrease.Entertain(slave, skillIncrease)}`; } + if (slave.skill.entertainment > jsRandom(50, 99) && slave.skill.whore < 50) { + r += ` ${His} ability to entertain gave ${him} a better understanding of ${his} <span class="green">body's worth as a sexual object.</span>`; + slave.skill.whore += (2.5 + Math.floor((slave.intelligence + slave.intelligenceImplant) / 64)); + } } } } diff --git a/src/endWeek/saWhore.js b/src/endWeek/saWhore.js index c94e2d1f96cd3d84fee98f6b640e3a4edfb311cb..791cbf53f4458854a8447b4684da4b49081ca79d 100644 --- a/src/endWeek/saWhore.js +++ b/src/endWeek/saWhore.js @@ -245,7 +245,24 @@ window.saWhore = (function saWhore() { * @param {App.Entity.SlaveState} slave */ function usageCountDescriptions(slave) { - r += ` ${His} appearance attracted ${beauty} ${customers} members of the public (${Math.trunc(beauty / 7)} a day)`; + r += ` ${His} appearance`; + if (slave.maxWhoreClass > slave.effectiveWhoreClass) { + let customers2; + if (slave.maxWhoreClass === 4) { + customers2 = "extremely wealthy"; + } else if (slave.maxWhoreClass === 3) { + customers2 = "upper class"; + } else if (slave.maxWhoreClass === 2) { + customers2 = "middle class"; + } else { + customers2 = "ERROR"; + } + r += ` can attract the ${customers2}, but they already had plenty slaves to fuck so she `; + } + r += ` attracted ${beauty} ${customers} members of the public (${Math.trunc(beauty / 7)} a day)`; + if (slave.maxWhoreClass > slave.effectiveWhoreClass) { + ` instead`; + } if (beauty > 160) { r += `, so many that `; if (canDoVaginal(slave) && canDoAnal(slave)) { @@ -511,6 +528,10 @@ window.saWhore = (function saWhore() { r += `squeezing johns for every penny.`; } } + if (slave.skill.entertainment < 50 && slave.effectiveWhoreClass > 2) { + slave.skill.entertainment += Math.floor(2.5 + (slave.intelligence + slave.intelligenceImplant) / 64); + r += ` ${He} learns a little about how to better <span class="green">entertain</span> ${his} classy clients.`; + } } if (slave.aphrodisiacs > 1 || slave.inflationType === "aphrodisiac") { @@ -569,14 +590,7 @@ window.saWhore = (function saWhore() { } else { r += ` pleasing the masses with ${his} chest,`; } - r += ` ${he} works social gatherings and high society`; - if (slave.skill.entertainment < 50) { - r += `, where ${he} learns how to captivate ${his} audience.`; - skillIncrease = Math.floor(2.5 + (slave.intelligence + slave.intelligenceImplant) / 32); - r += ` ${SkillIncrease.Entertain(slave, skillIncrease)}`; - } else { - r += `.`; - } + r += ` ${he} works social gatherings and high society.`; } else { r += ` ${He} shows diligence, and ${his} <span class="green">sexual skills improve,</span> according to what the customers demand`; if (!canDoVaginal(slave)) { diff --git a/src/js/datatypeCleanupJS.js b/src/js/datatypeCleanupJS.js index f85228f52b8e70c3725a5f50d34be999b9a8aece..6545021cee0979ab38bcf8ff3b992447b84d8ea8 100644 --- a/src/js/datatypeCleanupJS.js +++ b/src/js/datatypeCleanupJS.js @@ -1749,10 +1749,10 @@ window.EconomyDatatypeCleanup = function EconomyDatatypeCleanup() { V.sexSupplyBarriers.middleClass = Math.clamp(+V.sexSupplyBarriers.middleClass, 0, 4) || 0; V.sexSupplyBarriers.upperClass = Math.clamp(+V.sexSupplyBarriers.upperClass, 0, 4) || 0; V.sexSupplyBarriers.topClass = Math.clamp(+V.sexSupplyBarriers.topClass, 0, 4) || 0; - V.NPCSexSupply.lowerClass = Math.max(+V.NPCSexSupply.lowerClass, 0) || 0; - V.NPCSexSupply.middleClass = Math.max(+V.NPCSexSupply.middleClass, 0) || 0; - V.NPCSexSupply.upperClass = Math.max(+V.NPCSexSupply.upperClass, 0) || 0; - V.NPCSexSupply.topClass = Math.max(+V.NPCSexSupply.topClass, 0) || 0; + V.NPCSexSupply.lowerClass = Math.max(+V.NPCSexSupply.lowerClass, 500) || 3000; + V.NPCSexSupply.middleClass = Math.max(+V.NPCSexSupply.middleClass, 500) || 3000; + V.NPCSexSupply.upperClass = Math.max(+V.NPCSexSupply.upperClass, 500) || 3000; + V.NPCSexSupply.topClass = Math.max(+V.NPCSexSupply.topClass, 500) || 3000; V.rentDefaults.lowerClass = Math.max(+V.rentDefaults.lowerClass, 0) || 20; /* nowhere modified */ V.rentDefaults.middleClass = Math.max(+V.rentDefaults.middleClass, 0) || 50; /* nowhere modified */ @@ -1785,6 +1785,12 @@ window.EconomyDatatypeCleanup = function EconomyDatatypeCleanup() { if (!V.NPCMarketShare) { V.NPCMarketShare = {}; } + + // fixing potential massive oversupply + if (V.NPCSexSupply.lowerClass > V.lowerClass * V.whoreBudget.lowerClass) { + V.NPCSexSupply.lowerClass = V.lowerClass * V.whoreBudget.lowerClass; + } + V.NPCMarketShare.lowerClass = Math.clamp(+V.NPCMarketShare.lowerClass, 0, 1000) || 0; V.NPCMarketShare.middleClass = Math.clamp(+V.NPCMarketShare.middleClass, 0, 1000) || 0; V.NPCMarketShare.upperClass = Math.clamp(+V.NPCMarketShare.upperClass, 0, 1000) || 0; diff --git a/src/js/economyJS.js b/src/js/economyJS.js index c215a4f6789ce586472f6b66b2b4b82f8c932132..4a707dceb4b9ce00938651141c3ff4c369ab7799 100644 --- a/src/js/economyJS.js +++ b/src/js/economyJS.js @@ -904,8 +904,8 @@ window.NPCSexSupply = function(lowerDemandLeft, lowerTotalDemand, middleDemandLe } else { NPCSexSupply.lowerClass = Math.trunc(NPCSexSupply.lowerClass * (1 + normalRandInt(0, 20) / 1000)); // Some random fluxuations whenever the NPC supply is roughly on target. } - } else { // Increase NPC supply slightly if it drops below the standard minimum share of supply - NPCSexSupply.lowerClass = Math.trunc(NPCSexSupply.lowerClass * (1 + normalRandInt(30, 10) / 1000)); + } else { // Increase NPC supply if it drops below the standard minimum share of supply + NPCSexSupply.lowerClass += Math.max(Math.trunc(NPCSexSupply.lowerClass * (normalRandInt(150, 10) / 1000)), 500); } @@ -922,7 +922,7 @@ window.NPCSexSupply = function(lowerDemandLeft, lowerTotalDemand, middleDemandLe NPCSexSupply.middleClass = Math.trunc(NPCSexSupply.middleClass * (1 + normalRandInt(0, 20) / 1000)); } } else { - NPCSexSupply.middleClass = Math.trunc(NPCSexSupply.middleClass * (1 + normalRandInt(30, 10) / 1000)); + NPCSexSupply.middleClass += Math.max(Math.trunc(NPCSexSupply.middleClass * (normalRandInt(150, 10) / 1000)), 500); } // Upper class Calculations @@ -938,7 +938,7 @@ window.NPCSexSupply = function(lowerDemandLeft, lowerTotalDemand, middleDemandLe NPCSexSupply.upperClass = Math.trunc(NPCSexSupply.upperClass * (1 + normalRandInt(0, 20) / 1000)); } } else { - NPCSexSupply.upperClass = Math.trunc(NPCSexSupply.upperClass * (1 + normalRandInt(30, 10) / 1000)); + NPCSexSupply.upperClass += Math.max(Math.trunc(NPCSexSupply.upperClass * (normalRandInt(150, 10) / 1000)), 500); } // Top class calculations @@ -954,14 +954,14 @@ window.NPCSexSupply = function(lowerDemandLeft, lowerTotalDemand, middleDemandLe NPCSexSupply.topClass = Math.trunc(NPCSexSupply.topClass * (1 + normalRandInt(0, 20) / 1000)); } } else { - NPCSexSupply.topClass = Math.trunc(NPCSexSupply.topClass * (1 + normalRandInt(30, 10) / 1000)); + NPCSexSupply.topClass += Math.max(Math.trunc(NPCSexSupply.topClass * (normalRandInt(150, 10) / 1000)), 500); } return NPCSexSupply; }; // The function for calculating and storing a slave's sexual interaction with citizens/'the outside' -window.slaveJobValues = function() { +window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) { const slaveJobValues = { arcade: 0, club: 0, @@ -1198,6 +1198,11 @@ window.slaveJobValues = function() { SJVClub(V.slaves[V.slaveIndices[ID]]); }); + // Saturation penalty for public servants. Even the most beautiful slaves lose some of their shine if they have too much competition. + if (slaveJobValues.club > 0) { + slaveJobValues.clubSP = (Math.pow(slaveJobValues.club / 1000, 0.95) * 1000) / slaveJobValues.club; + } + // Street whores adding to 'brothel' V.JobIDArray["whore"].forEach(ID => { SJVBrothel(V.slaves[V.slaveIndices[ID]]); @@ -1205,7 +1210,7 @@ window.slaveJobValues = function() { // Brothel whores adding to 'brothel' V.BrothiIDs.forEach(ID => { - SJVBrothel(V.slaves[V.slaveIndices[ID]]); + SJVBrothel(V.slaves[V.slaveIndices[ID]], lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef); }); function SJVClub(s) { @@ -1400,7 +1405,7 @@ window.slaveJobValues = function() { } } - function SJVBrothel(s) { + function SJVBrothel(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) { let toTheBrothel = 0; let beautyMultiplier = 1; s.minorInjury = 0; @@ -1586,61 +1591,81 @@ window.slaveJobValues = function() { // 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). - function whoreScore(s) { + function whoreScore(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) { let income = s.sexAmount * s.sexQuality; - effectiveWhoreClass(s); + s.effectiveWhoreClass = effectiveWhoreClass(s); + s.maxWhoreClass = s.effectiveWhoreClass; + + // 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 + const topSDRatio = slaveJobValues.brothel.topClass / topClassSexDemandRef; + const upperSDRatio = slaveJobValues.brothel.upperClass / upperClassSexDemandRef; + const middleClubSupply = slaveJobValues.club * slaveJobValues.clubSP * (middleClassSexDemandRef / (lowerClassSexDemandRef + middleClassSexDemandRef)); + const middleSupply = slaveJobValues.brothel.middleClass + middleClubSupply; + const middleSDRatio = middleSupply / middleClassSexDemandRef; + const lowerClubSupply = slaveJobValues.club * slaveJobValues.clubSP * (lowerClassSexDemandRef / (lowerClassSexDemandRef + middleClassSexDemandRef)); + const lowerSupply = slaveJobValues.brothel.lowerClass + lowerClubSupply; + const lowerSDRatio = lowerSupply / lowerClassSexDemandRef; + if (s.effectiveWhoreClass === 4 && topSDRatio > 1 && topSDRatio > upperSDRatio) { + s.effectiveWhoreClass -= 1; + } + if (s.effectiveWhoreClass === 3 && upperSDRatio > 1 && upperSDRatio > middleSDRatio) { + s.effectiveWhoreClass -= 1; + } + if (s.effectiveWhoreClass === 2 && middleSDRatio > 1 && middleSDRatio > lowerSDRatio) { + s.effectiveWhoreClass -= 1; + } // Calculate the stats if (s.effectiveWhoreClass === 4) { s.sexAmount = normalRandInt(50, 4); // Bringing sex amount into the desired range s.sexQuality = Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier - slaveJobValues.brothel.topClass += Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.topClass * 0.2); // Registering the job value in the right slot + 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 = normalRandInt(60, 5); s.sexQuality = Math.min(Math.trunc((income * 1.05) / s.sexAmount), V.whoreBudget.upperClass * 0.5); // The upper class will pay a maximum of 60% of their weekly budget per service - slaveJobValues.brothel.upperClass += Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.upperClass * 0.6); + slaveJobValues.brothel.upperClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.upperClass * 0.6)); } else if (s.effectiveWhoreClass === 2) { s.sexAmount = normalRandInt(70, 6); s.sexQuality = Math.min(Math.trunc((income * 0.9) / s.sexAmount), V.whoreBudget.middleClass); // The middle class will pay a maximum of 125% of their weekly budget per service - slaveJobValues.brothel.middleClass += Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.middleClass * 1.25); + slaveJobValues.brothel.middleClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.middleClass * 1.25)); } else { s.sexAmount = normalRandInt(80, 7); - s.sexQuality = Math.clamp((income * 0.75) / s.sexAmount, 2, V.whoreBudget.lowerClass * 2); // The lower class will pay a maximum of 300% of their weekly budget per service and a minimum of 3 - slaveJobValues.brothel.lowerClass += Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.lowerClass * 3); + s.sexQuality = Math.clamp((income * 0.75) / s.sexAmount, 2, V.whoreBudget.lowerClass * 2); // The lower class will pay a maximum of 300% of their weekly budget per service and a minimum of 2 + slaveJobValues.brothel.lowerClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.lowerClass * 3)); } } if (typeof s.whoreClass === 'undefined') { s.whoreClass = 0; } - whoreScore(s); + whoreScore(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef); } - // Saturation penalty for public servants. Even the most beautiful slaves lose some of their shine if they have too much competition. - if (slaveJobValues.club > 0) { - slaveJobValues.clubSP = (Math.pow(slaveJobValues.club / 1000, 0.95) * 1000) / slaveJobValues.club; - } return slaveJobValues; }; window.effectiveWhoreClass = function(s) { let score = s.sexAmount * s.sexQuality; + let result; if (typeof s.whoreClass === 'undefined' || s.whoreClass === 0) { - s.effectiveWhoreClass = 4; + result = 4; } else { - s.effectiveWhoreClass = s.whoreClass; + result = s.whoreClass; } // Find maximum eligable class // these could be refined further if needed. - if (s.effectiveWhoreClass === 4 && !(score > 5000 && s.skill.whoring > 80 && s.skill.entertainment > 50)) { - s.effectiveWhoreClass -= 1; + if (result === 4 && !(score > 5000 && s.skill.whoring > 80 && s.skill.entertainment > 50)) { + result -= 1; } - if (s.effectiveWhoreClass === 3 && !(score > 2500 && s.skill.whoring > 50)) { - s.effectiveWhoreClass -= 1; + if (result === 3 && !(score > 2500 && s.skill.whoring > 50)) { + result -= 1; } - if (s.effectiveWhoreClass === 2 && (score <= 1000)) { - s.effectiveWhoreClass -= 1; + if (result === 2 && (score <= 1000)) { + result -= 1; } + return result; }; window.getSlaveStatisticData = function(s, facility) { diff --git a/src/uncategorized/slaveAssignmentsReport.tw b/src/uncategorized/slaveAssignmentsReport.tw index fa248c9daefd32d259782c21181ee8f7961eddbc..b8ec2375276066a5439e1146aec0d51a0756593a 100644 --- a/src/uncategorized/slaveAssignmentsReport.tw +++ b/src/uncategorized/slaveAssignmentsReport.tw @@ -31,14 +31,14 @@ _topClassSexDemandRef = Math.max(_topClassSexDemand, 1), $whorePriceAdjustment = {lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0}, $NPCMarketShare = {lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0}, $sexDemandResult = {lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0}, -$slaveJobValues = slaveJobValues()>> +$slaveJobValues = slaveJobValues(_lowerClassSexDemandRef, _middleClassSexDemandRef, _upperClassSexDemandRef, _topClassSexDemandRef)>> /*Supply of sexual services*/ <<if ($cheatMode == 1) || ($debugMode == 1)>> - <br>Lower Class SD: <<print _lowerClassSexDemand>> - <br>Middle Class SD: <<print _middleClassSexDemand>> - <br>Upper Class SD: <<print _upperClassSexDemand>> - <br>Top Class SD: <<print _topClassSexDemand>> + <br>Lower Class SD: <<print _lowerClassSexDemandRef>> + <br>Middle Class SD: <<print _middleClassSexDemandRef>> + <br>Upper Class SD: <<print _upperClassSexDemandRef>> + <br>Top Class SD: <<print _topClassSexDemandRef>> <br>Club SP: <<print Math.trunc($slaveJobValues.club * $slaveJobValues.clubSP)>> <br>Arcade SP: <<print $slaveJobValues.arcade>> <br>Brothel SP: <<print $slaveJobValues.brothel.lowerClass>>, <<print $slaveJobValues.brothel.middleClass>>, <<print $slaveJobValues.brothel.upperClass>>, <<print $slaveJobValues.brothel.topClass>>