diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index b91b7c0be7f55b610331272697f8dea67fdc56a2..3e89a95ab323572ffbbd88581a766a7d5ac23dde 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -362,7 +362,6 @@ App.Data.resetOnNGPlus = { rivalID: 0, eliteAuctioned: 0, slavesSacrificedThisWeek: 0, - subSlaves: 0, HGtraining: "", mercenariesTitle: "", diff --git a/src/endWeek/endWeek.js b/src/endWeek/endWeek.js index d266db86c95b08f89345541b6887b72da0bedaea..871f5566d3a35ffc8af09754bcaea386d50e724d 100644 --- a/src/endWeek/endWeek.js +++ b/src/endWeek/endWeek.js @@ -9,7 +9,6 @@ globalThis.endWeek = (function() { // globals setup resetSlaveMarkets(); - resetSlaveCounters(); for (const s of V.slaves) { slavePrep(s); } @@ -17,7 +16,7 @@ globalThis.endWeek = (function() { saveWeekTotals(); // pass time for objects that need it - weather (); + weather(); organs(); prosthetics(); nursery(); @@ -37,14 +36,7 @@ globalThis.endWeek = (function() { } } - function resetSlaveCounters() { - V.subSlaves = 0; - } - function slavePrep(s) { - if (s.assignment === Job.SUBORDINATE && s.subTarget === 0) { - V.subSlaves++; - } s.lastWeeksCashIncome = 0; s.lastWeeksRepIncome = 0; s.lastWeeksRepExpenses = 0; diff --git a/src/endWeek/healthFunctions.js b/src/endWeek/healthFunctions.js index 987282793953e8edc998ad73efd733674ac78d0a..a23337026450cb4e5142f1e84334322c2398e682 100644 --- a/src/endWeek/healthFunctions.js +++ b/src/endWeek/healthFunctions.js @@ -443,13 +443,12 @@ globalThis.tired = function(slave) { assignment += 5; } } else if (slave.subTarget === 0) { - const workload = ((V.dormitoryPopulation + V.roomsPopulation - V.subSlaves) > 5) ? (V.subSlaves / (V.dormitoryPopulation + V.roomsPopulation - V.subSlaves)) : 1; if (slave.devotion > 20) { assignment += 7; } else { assignment += 10; } - assignment = Math.ceil(assignment / workload); // 50 if very overloaded, make sure to have enough girls serving! + assignment = Math.min(Math.ceil(assignment / App.EndWeek.saVars.subSlaveRatio), 50); // up to 50 if very overloaded, make sure to have enough girls serving! } else { if (slave.relationshipTarget === slave.subTarget && slave.health.tired > 60) { assignment += 2; diff --git a/src/endWeek/saReleaseRules.js b/src/endWeek/saReleaseRules.js index 412f87c23ba8382da77b18b2c630768aba47b665..dd9c02069df06bd6402faab016b460841bf3e7d6 100644 --- a/src/endWeek/saReleaseRules.js +++ b/src/endWeek/saReleaseRules.js @@ -7,7 +7,23 @@ App.SlaveAssignment.nonAssignmentRelease = function(slave) { const release = slave.rules.release; const {he, his, him, himself} = getPronouns(slave); - if (!App.Utils.hasNonassignmentSex(slave) && release.masturbation === 0) { + const subSlaves = App.EndWeek.saVars.subSlaveMap.get(slave.ID); + if (subSlaves && subSlaves.length > 0) { + // if a slave has been assigned a specific personal subslave, or several, go to them first for relief + // there is no check for release rules in this case...permission is implicit in the assignment (saServeYourOtherSlaves also does not check) + const whom = subSlaves.length > 1 ? "several slaves" : getSlave(subSlaves[0]).slaveName; + r.push(`is <span class="devotion inc">delighted</span> that you've assigned ${whom} to ${him} for ${his} personal use, and <span class="trust inc">relishes</span> the feeling of being served.`); + // note rapid trust increase...power is dangerous if the target isn't devoted yet! + if (subSlaves.length > 1) { + slave.devotion += 2; + slave.trust += 6; + } else { + slave.devotion += 1; + slave.trust += 4; + } + // no fetish effects/discovery here...saServeYourOtherSlaves' subLife will take care of that + slave.need = 0; + } else if (!App.Utils.hasNonassignmentSex(slave) && release.masturbation === 0) { if (release.master === 1) { const toYou = assignmentVisible(slave) ? `to you` : `up to the penthouse`; if ((slave.devotion <= 20) && (slave.trust >= -20)) { diff --git a/src/endWeek/saRules.js b/src/endWeek/saRules.js index da97998755f8fbe9b62d088fbda8af5be1dfb509..4ecf3c17775b2b33ae8311b97596fc420751be74 100644 --- a/src/endWeek/saRules.js +++ b/src/endWeek/saRules.js @@ -1,7 +1,7 @@ /** * * @param {App.Entity.SlaveState} slave - * @returns {Node} + * @returns {DocumentFragment} */ App.SlaveAssignment.rules = function(slave) { const el = new DocumentFragment(); @@ -1918,7 +1918,7 @@ App.SlaveAssignment.rules = function(slave) { slave.trust -= 1; } slave.need -= 20; - } else if ((release.masturbation === 0)) { + } else if (release.masturbation === 0) { r.push(`gets off from being milked, so being forbidden to masturbate doesn't affect ${him} seriously.`); slave.need -= 20; } else { @@ -2209,7 +2209,7 @@ App.SlaveAssignment.rules = function(slave) { slave.trust -= 1; } slave.need -= 20; - } else if ((release.masturbation === 0)) { + } else if (release.masturbation === 0) { r.push(`gets off from working as a farmhand, so being forbidden to masturbate doesn't affect ${him} seriously.`); slave.need -= 20; } else { @@ -2415,7 +2415,7 @@ App.SlaveAssignment.rules = function(slave) { slave.trust -= 1; } slave.need -= 20; - } else if ((release.masturbation === 0)) { + } else if (release.masturbation === 0) { r.push(`gets off regularly, so being forbidden to masturbate doesn't affect ${him} seriously.`); slave.need -= 20; } else { @@ -2492,7 +2492,7 @@ App.SlaveAssignment.rules = function(slave) { slave.trust -= 1; } slave.need -= 20; - } else if ((release.masturbation === 0)) { + } else if (release.masturbation === 0) { r.push(`gets off with ${S.HeadGirl.slaveName}, so being forbidden to masturbate doesn't affect ${him} seriously.`); slave.need -= 20; } else { @@ -2557,14 +2557,26 @@ App.SlaveAssignment.rules = function(slave) { r.push(`${He} hates ${himself} for climaxing, and knows the mild aphrodisiacs in the food are forcing ${his} arousal, <span class="gold">frightening ${him}.</span>`); slave.trust -= 1; } - } else if ((release.masturbation === 0)) { + } else if (release.masturbation === 0) { r.push(`gets off at work, so being forbidden to masturbate doesn't affect ${him} seriously.`); } else { r.push(`gets off at work, so ${he} doesn't feel the need to masturbate frequently.`); } slave.need -= 20; } else { - r.push(App.SlaveAssignment.nonAssignmentRelease(slave)); + // allowed to get off with other slaves, but not given a specific subslave...try to use the shared ones before going further + if (release.slaves === 1 && slave.assignment !== Job.SUBORDINATE && !App.EndWeek.saVars.subSlaveMap.get(slave.ID)) { + slave.need -= Math.min(50 * App.EndWeek.saVars.subSlaveRatio, slave.need); + r.push(`often uses the penthouse subordinate slaves to satisfy ${his}`); + if (slave.need > 0) { + r.push(`sexual need, but it's just not enough; ${he}`); + } else { + r.push(`sexual need.`); + } + } + if (slave.need > 0) { + r.push(App.SlaveAssignment.nonAssignmentRelease(slave)); + } } r.push(App.EndWeek.Rules.speechRules(slave)); @@ -2753,7 +2765,7 @@ App.SlaveAssignment.rules = function(slave) { if (slave.lactation === 1) { slave.rules.lactation = "maintain"; } - } else if (slave.rules.lactation === "maintain" && (V.servantMilkers !== 1 || !setup.servantMilkersJobs.includes(slave.assignment))) { + } else if (slave.rules.lactation === "maintain" && (V.servantMilkers !== 1 || !App.Data.misc.servantMilkersJobs.includes(slave.assignment))) { r.push(`${He} utilizes ${his} lactation during ${his} daily tasks as needed, and when ${he} isn't drained well enough, spends the evenings with a pair of automatic breast pumps.`); slave.lactationDuration = 2; slave.boobs -= slave.boobsMilk; @@ -2761,10 +2773,6 @@ App.SlaveAssignment.rules = function(slave) { } r.push(App.SlaveAssignment.rewardAndPunishment(slave)); - if (V.subSlaves > 0 && release.slaves === 1 && slave.assignment !== "serve your other slaves") { - slave.need -= (20 * V.subSlaves); - /* make those serve your other slaves do some work for once */ - } } } } diff --git a/src/endWeek/saServeYourOtherSlaves.js b/src/endWeek/saServeYourOtherSlaves.js index 10cd5d2480c6f0c64fc859e09bd12535a1cc3fda..3dd3ed3f4cd02b4efb8478aca1fac259f2041472 100644 --- a/src/endWeek/saServeYourOtherSlaves.js +++ b/src/endWeek/saServeYourOtherSlaves.js @@ -17,7 +17,6 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { let mammaryUse; let penetrativeUse; let fuckCount; - let load; let cervixPump; let domSlave; @@ -55,7 +54,6 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { penetrativeUse = 0; cervixPump = 0; fuckCount = 0; - load = 0; subName = slave.slaveName; subSlaveLikedFetish = 0; @@ -233,11 +231,9 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { } else if (!canMove(slave)) { r.push(`Since ${he}'s completely immobile, ${he}'s especially vulnerable.`); } - if (V.subSlaves <= 0) { - V.subSlaves = 1; - } - if ((V.dormitoryPopulation + V.roomsPopulation - V.subSlaves) > 5) { - load = (V.subSlaves / (V.dormitoryPopulation + V.roomsPopulation - V.subSlaves)); + const subSlaves = App.EndWeek.saVars.subSlaveMap.get(0) || []; + if ((V.dormitoryPopulation + V.roomsPopulation - subSlaves.length) > 5) { + const load = App.EndWeek.saVars.subSlaveRatio; if (load > 0.8) { r.push(`Since there are enough other slaves servicing your stock alongside ${him}, ${he} sees limited action.`); } else if (load > 0.5) { @@ -263,7 +259,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { } } else { r.push(`Since`); - if (V.subSlaves === 1) { + if (subSlaves.length === 1) { r.push(`${he} is the only slave`); } else { r.push(`there are so few other slaves`); @@ -307,8 +303,8 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { } else { r.push(`Since you have so few slaves in need of release, ${he} sees little action.`); } - // added a min - fuckCount = Math.min(300, Math.ceil((((V.dormitoryPopulation + V.roomsPopulation) + jsRandom(((V.dormitoryPopulation + V.roomsPopulation) * 1), (V.dormitoryPopulation + V.roomsPopulation) * 7)) / V.subSlaves) * healthPenalty(slave))); + // service the fraction of the eligible slave population that's not served by another subslave between 1 and 5 times per day + fuckCount = Math.ceil((jsRandom(7, 35) / App.EndWeek.saVars.subSlaveRatio) * healthPenalty(slave)); SimpleSexAct.Slave(slave, fuckCount); } @@ -1452,16 +1448,15 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { if (slave.fetishStrength < 100) { slave.fetishStrength++; } - } else if (fetishChange > jsRandom(0, 100) && slave.fetish !== "masochist" && slave.fetish !== "submissive" && load <= 0.8) { + } else if (fetishChange > jsRandom(0, 100) && slave.fetish !== "masochist" && slave.fetish !== "submissive" && App.EndWeek.saVars.subSlaveRatio <= 0.8) { r.push(`Being used as much as ${he} is starts to take a toll on ${him} sexuality; <span class="lightcoral">${he} begins to enjoy being your chattel's fucktoy.</span>`); slave.fetish = "submissive"; slave.fetishStrength = 65; slave.fetishKnown = 1; } } else if (jobType === "sub") { - domSlave.need = 0; if (domSlaveUsedFetish) { - Math.clamp(domSlave.fetishStrength += 3, 0, 100); + domSlave.fetishStrength = Math.clamp(domSlave.fetishStrength + 3, 0, 100); } if (subSlaveLikedFetish) { slave.need = 0; @@ -1787,7 +1782,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() { } } } else if (jobType === "cumdump") { - if ((V.dormitoryPopulation + V.roomsPopulation - V.subSlaves) > 5 && load <= 0.8) { + if (App.EndWeek.saVars.subSlaveRatio <= 0.8) { if (slave.sexualFlaw === "repressed") { if (slave.devotion > 20 && jsRandom(1, 100) > (100 - fuckCount)) { r.push(`After being brought to orgasm so many times, <span class="green">${he} begins to enjoy having sex.</span>`); diff --git a/src/endWeek/saSharedVariables.js b/src/endWeek/saSharedVariables.js index ac9ef5fcfbdc0a800be970692e085740d6ed7299..8fc356b65590ba174514ca70dc37f606a8d39e32 100644 --- a/src/endWeek/saSharedVariables.js +++ b/src/endWeek/saSharedVariables.js @@ -30,6 +30,10 @@ App.EndWeek.SASharedVariables = class { this.unMadam = 0; /** Why was the DJ fired this week? */ this.unDJ = 0; + /** Who are your subordinate slaves actually assigned to? + * @type {Map<number, Array<number>>} - key is sub target, value is list of sub slaves (by ID) assigned to that target + */ + this.subSlaveMap = new Map(); } /** @@ -45,4 +49,14 @@ App.EndWeek.SASharedVariables = class { this.inappropriateLactation = 0; /** TODO: move $slaveUsedRest here after saRules is converted, and find others */ } + + /** Compute shared subslave ratio (subslaves per ordinary slave) */ + get subSlaveRatio() { + const subSlaves = this.subSlaveMap.get(0); + const subCount = subSlaves ? subSlaves.length : 0; + if (V.dormitoryPopulation + V.roomsPopulation <= subCount) { + return subCount; // avoid negative result or divide by zero + } + return subCount / (V.dormitoryPopulation + V.roomsPopulation - subCount); + } }; diff --git a/src/endWeek/slaveAssignmentReport.js b/src/endWeek/slaveAssignmentReport.js index 48a33a764a154481f40ecda0ed9624b5b90395c4..6e2c5ba860109411a735b2d8b68d9feb4e9a7e2f 100644 --- a/src/endWeek/slaveAssignmentReport.js +++ b/src/endWeek/slaveAssignmentReport.js @@ -73,6 +73,16 @@ App.EndWeek.slaveAssignmentReport = function() { case Job.FUCKTOY: V.fuckSlaves++; break; + case Job.SUBORDINATE: { + const map = App.EndWeek.saVars.subSlaveMap; + const curSubs = map.get(slave.subTarget); + if (curSubs) { + curSubs.push(slave.ID); + } else { + map.set(slave.subTarget, [slave.ID]); + } + break; + } } if (slave.bellyPain !== 0) { diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js index 8a34958763da290a0ab2a73110b8ec0a6bd3e942..9bf380863a1e3f51be99fd54840e2279666edded 100644 --- a/src/js/SlaveState.js +++ b/src/js/SlaveState.js @@ -537,7 +537,7 @@ App.Entity.SlaveState = class SlaveState { this.rivalry = 0; /** target of rival (ID) */ this.rivalryTarget = 0; - /** slave will serve subTarget (ID) */ + /** slave will serve subTarget (ID - 0 is all slaves, -1 is stud) */ this.subTarget = 0; /** ID of father */ this.father = 0; diff --git a/src/uncategorized/nextWeek.tw b/src/uncategorized/nextWeek.tw index 4ce25632e4ee77e3e9ae5536109346081d4a617d..4eed4de160a64d291e08944d483d862562a19854 100644 --- a/src/uncategorized/nextWeek.tw +++ b/src/uncategorized/nextWeek.tw @@ -287,7 +287,7 @@ <<set $thisWeeksIllegalWares = $merchantIllegalWares.randomMany(1)>> <<set $prisonCircuitIndex++>><<if $prisonCircuitIndex >= $prisonCircuit.length>><<set $prisonCircuitIndex = 0>><</if>> -<<set $coursed = 0, $prestigeAuctioned = 0, $eliteAuctioned = 0, $shelterSlave = 0, $shelterSlaveBought = 0, $slaveMarketLimit = 10 + ($rep / 1000), $slavesSeen = 0, $slavesSacrificedThisWeek = 0, $subSlaves = 0>> +<<set $coursed = 0, $prestigeAuctioned = 0, $eliteAuctioned = 0, $shelterSlave = 0, $shelterSlaveBought = 0, $slaveMarketLimit = 10 + ($rep / 1000), $slavesSeen = 0, $slavesSacrificedThisWeek = 0>> <<if $pit>> <<set $pit.fought = false>>