diff --git a/CHANGELOG.md b/CHANGELOG.md index b477f4b8f94bd4bc674fd095f3dac62261880ed2..f9cefc4a4e71f1d2d26723dafbd65964fc647871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## Unreleased +* added isVirile() function +* added isHorny() function (check for sources of constant arousal) +* added aggrosperm, livestock, and progenitor gene mods +* added potency genetic quirk +* vasectomies cut sperm release +* fixes + ## 0.10.7.1-4.0.0-alpha.23 - 2023-01-15 * Fix issue related to function names not being camalCase. diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index 6ef37118fd0bf2b21e0a2da7865e1a836e7bc63e..0a961c6e2c795278665da1a6499559c08f5c360c 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -343,6 +343,8 @@ App.Data.illegalWares = [ "childhoodFertilityInducedNCS", "PGHack", "RapidCellGrowthFormula", + "optimizedSpermFormula", + "optimizedBreedingFormula", "sympatheticOvaries", "UterineRestraintMesh", ]; @@ -627,6 +629,7 @@ App.Data.resetOnNGPlus = { spaSpots: 0, spaUpgrade: 0, spaFix: 0, + spaAggroSpermBan: 1, spaName: "the Spa", incubator: {capacity: 0, tanks: []}, @@ -1292,15 +1295,21 @@ App.Data.resetOnNGPlus = { /* prosthetics: {research: int, amount: int} */ prosthetics: {}, + /* Black Market */ merchantFSWares: App.Data.FSWares, merchantIllegalWares: App.Data.illegalWares, - RapidCellGrowthFormula: 0, - immortalityFormula: 0, - bioEngineeredFlavoringResearch: 0, UterineRestraintMesh: 0, PGHack: 0, BlackmarketPregAdaptation: 0, + /* Gene Mods */ + RapidCellGrowthFormula: 0, + immortalityFormula: 0, + bioEngineeredFlavoringResearch: 0, + optimizedSpermFormula: 0, + enhancedProductionFormula: 0, + optimizedBreedingFormula: 0, + /* Medical Pavilion */ doctor: { state: 0, // controls introduction diff --git a/js/003-data/slaveGeneData.js b/js/003-data/slaveGeneData.js index 63603d59db84021215e3678b161d813bfb5fc543..93218cbc58a3415cb76e8289c8cb54a3ad1453a4 100644 --- a/js/003-data/slaveGeneData.js +++ b/js/003-data/slaveGeneData.js @@ -83,6 +83,14 @@ App.Data.geneticQuirks = new Map([ restricted: true } ], + ["potent", + { + title: "potency", + abbreviation: "ptnt", + goodTrait: true, + description: "a heightened impregnation rate" + } + ], ["fertility", { title: "fertility", @@ -121,6 +129,7 @@ App.Data.geneticQuirks = new Map([ description: "pleasurable pregnancy and orgasmic birth" } ], + ["macromastia", { title: "macromastia", @@ -188,6 +197,14 @@ App.Data.geneticQuirks = new Map([ description: "constant muscle loss" } ], + ["twinning", + { + title: "twinning", + abbreviation: "twns", + description: "ova split when space permits", + restricted: true + } + ], ["girlsOnly", { title: "girls only", @@ -224,6 +241,38 @@ App.Data.geneticMods = new Map([ description: "slave stops aging. Can still die of other causes." }, ], + ["flavoring", + { + title: "flavored milk", + abbreviation: "fmilk", + goodTrait: true, + description: "altered milk flavor" + }, + ], + ["aggressiveSperm", + { + title: "enhanced potency", + abbreviation: "pot", + goodTrait: true, + description: "sperm optimization treatment" + }, + ], + ["livestock", + { + title: "production optimization", + abbreviation: "lvstck", + goodTrait: true, + description: "production optimization treatment" + }, + ], + ["progenitor", + { + title: "progenitor", + abbreviation: "prgntr", + goodTrait: true, + description: "breeding optimization treatment" + }, + ], ]); App.Data.milk = { diff --git a/js/medicine/surgery/exotic/treatment.js b/js/medicine/surgery/exotic/treatment.js index c0ed5c9ae41c02d3e27f2b403a1462be7477af70..5e408ce8ac93fa569d67f17a86694ee2d0eb6134 100644 --- a/js/medicine/surgery/exotic/treatment.js +++ b/js/medicine/surgery/exotic/treatment.js @@ -87,7 +87,7 @@ App.Medicine.Surgery.Procedures.milkFlavoring = class extends App.Medicine.Surge get description() { const {his} = getPronouns(this.originalSlave); - return `This will alter ${his} genetics to allow flavored milk`; + return `this will alter ${his} genetics to allow flavored milk`; } get cost() { @@ -99,12 +99,88 @@ App.Medicine.Surgery.Procedures.milkFlavoring = class extends App.Medicine.Surge } apply(cheat) { + this._slave.geneMods.flavoring = 1; this._slave.milkFlavor = "natural"; this._slave.chem += 100; return this._assemble(new App.Medicine.Surgery.Reactions.GeneTreatment()); } }; +App.Medicine.Surgery.Procedures.OptimizedSpermTreatment = class extends App.Medicine.Surgery.Procedure { + get name() { + return "Optimized sperm treatment"; + } + + get description() { + const {his} = getPronouns(this.originalSlave); + return `this will alter ${his} genetic code to encourage ${his} body to produce far more aggressive sperm cells`; + } + + get cost() { + return super.cost * 4; + } + + get healthCost() { + return 40; + } + + apply(cheat) { + this._slave.geneMods.aggressiveSperm = 1; + this._slave.chem += 100; + return this._assemble(new App.Medicine.Surgery.Reactions.GeneTreatment()); + } +}; + +App.Medicine.Surgery.Procedures.EnhancedProductionTreatment = class extends App.Medicine.Surgery.Procedure { + get name() { + return "Enhanced production treatment"; + } + + get description() { + const {his} = getPronouns(this.originalSlave); + return `this will alter ${his} genetic code to encourage ${his} body to produce larger volumes of sellable resources`; + } + + get cost() { + return super.cost * 4; + } + + get healthCost() { + return 40; + } + + apply(cheat) { + this._slave.geneMods.livestock = 1; + this._slave.chem += 100; + return this._assemble(new App.Medicine.Surgery.Reactions.GeneTreatment()); + } +}; + +App.Medicine.Surgery.Procedures.OptimizedBreedingTreatment = class extends App.Medicine.Surgery.Procedure { + get name() { + return "Optimized breeding treatment"; + } + + get description() { + const {his} = getPronouns(this.originalSlave); + return `this will alter ${his} genetic code to encourage ${his} body to be far more efficient at bearing children`; + } + + get cost() { + return super.cost * 4; + } + + get healthCost() { + return 40; + } + + apply(cheat) { + this._slave.geneMods.progenitor = 1; + this._slave.chem += 100; + return this._assemble(new App.Medicine.Surgery.Reactions.GeneTreatment()); + } +}; + App.Medicine.Surgery.Procedures.RemoveGene = class extends App.Medicine.Surgery.Procedure { /** diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js index 280c912d397a7847454559973e7d947796272360..5e322c743b7c1ed3499e6d0791b1d98647f9af49 100644 --- a/src/002-config/fc-version.js +++ b/src/002-config/fc-version.js @@ -2,5 +2,5 @@ App.Version = { base: "0.10.7.1", // The vanilla version the mod is based off of, this should never be changed. pmod: "4.0.0-alpha.23", commitHash: null, - release: 1185, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. + release: 1186, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. }; diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js index 54848cc5fba57f9c39981e12f17fe1919ad4a596..eb155928a0f0d97565feabf185eb828255034371 100644 --- a/src/data/backwardsCompatibility/datatypeCleanup.js +++ b/src/data/backwardsCompatibility/datatypeCleanup.js @@ -582,7 +582,7 @@ globalThis.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() { // should never get here, but if it does, just immediately abort! slave.boobsMilk = 0; } - slave.lactationAdaptation = Math.clamp(+slave.lactationAdaptation, 0, 100) || 0; + slave.lactationAdaptation = Math.clamp(+slave.lactationAdaptation, 0, 200) || 0; } /** @@ -1325,7 +1325,7 @@ globalThis.PCDatatypeCleanup = (function PCDatatypeCleanup() { // should never get here, but if it does, just immediately abort! PC.boobsMilk = 0; } - PC.lactationAdaptation = Math.clamp(+PC.lactationAdaptation, 0, 100) || 0; + PC.lactationAdaptation = Math.clamp(+PC.lactationAdaptation, 0, 200) || 0; } /** diff --git a/src/data/backwardsCompatibility/updateSlaveObject.js b/src/data/backwardsCompatibility/updateSlaveObject.js index 0cc826e3bd5ac5f5f74d981b97a3081f094f3cb0..23cfd18dde559a74cb2e38f67e768b5ae82c8b04 100644 --- a/src/data/backwardsCompatibility/updateSlaveObject.js +++ b/src/data/backwardsCompatibility/updateSlaveObject.js @@ -100,11 +100,14 @@ App.Update.Slave = function(slave, genepool = false) { } } if (slave.genetics !== undefined) { delete slave.genetics; } - slave.geneMods = Object.assign({NCS: 0, rapidCellGrowth: 0, immortality: 0, bioEngineeredMilkFlavoring: 0}, slave.geneMods); + slave.geneMods = Object.assign({NCS: 0, rapidCellGrowth: 0, immortality: 0, flavoring: 0, aggressiveSperm: 0, livestock: 0, progenitor: 0}, slave.geneMods); if (slave.inducedNCS !== undefined) { slave.geneMods.NCS = slave.inducedNCS; delete slave.inducedNCS; } + if (slave.geneMods.bioEngineeredMilkFlavoring !== undefined) { + delete slave.geneMods.bioEngineeredMilkFlavoring; + } if (slave.milkFlavor === undefined) { slave.milkFlavor = "none"; } if (slave.PCSlutContacts !== undefined) { delete slave.PCSlutContacts; } if (slave.superfetation !== undefined) { delete slave.superfetation; } diff --git a/src/endWeek/economics/persBusiness.js b/src/endWeek/economics/persBusiness.js index 63d37a6902422f05ef609363b04e4d817a5eb983..f7ec3e8407727ce3d5f7a50e15549a152a0ec83c 100644 --- a/src/endWeek/economics/persBusiness.js +++ b/src/endWeek/economics/persBusiness.js @@ -14,7 +14,7 @@ App.EndWeek.personalBusiness = function() { let upgradeCount; let dataGain; let hindranceMod = isHinderedDegree(V.PC); - const nymphoMod = isPlayerHorny(V.PC) ? .75 : 1; + const nymphoMod = isHorny(V.PC) ? .75 : 1; const {girlP} = getPronouns(V.PC).appendSuffix("P"); if (V.useTabs === 0) { App.UI.DOM.appendNewElement("h2", el, `Personal Business`); @@ -95,6 +95,8 @@ App.EndWeek.personalBusiness = function() { r.push(`You focus on getting ready to give birth this week; when it happens, you want to be prepared.`); } else if (isInduced(V.PC)) { r.push(`This week, you focus on your labor and the impending birth of your ${V.PC.pregType > 1 ? "children" : "child"}.`); + } else if (PC.geneMods.rapidCellGrowth !== 1 && PC.bellyPreg >= 100000 && PC.belly > (PC.pregAdaptation * 3200) && (PC.bellyPreg >= 500000 || PC.wombImplant !== "restraint")) { + r.push(`You're stuck in bed waiting to pop. Hopefully this means giving birth, and not the alternative.`); } } else if (V.personalAttention.task === PersonalAttention.WHORING) { whoring(); @@ -675,7 +677,7 @@ App.EndWeek.personalBusiness = function() { let soldVirginity = false; let clients = random(2, 4); // This could probably be replaced by .need? - if (isPlayerHorny(V.PC)) { + if (isHorny(V.PC)) { clients *= 3; } else { clients += (Math.round(V.PC.energy / 20) - 1); diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js index 9d68d1148397592a22d74d8e750e7ebd0337ce1a..f4d433d5478147dc3868e7261e0fe92a1724c891 100644 --- a/src/endWeek/nextWeek/nextWeek.js +++ b/src/endWeek/nextWeek/nextWeek.js @@ -46,6 +46,13 @@ App.EndWeek.nextWeek = function() { } } } + if (V.PC.geneMods.progenitor === 1 && canGetPregnant(V.PC)) { // Progenitor mod causes ovarian burnout if not put to use. + if (V.PC.geneticQuirks.superfetation === 2 && V.PC.womb.length > 0) { + V.PC.ovaryAge += 0.1; + } else { + V.PC.ovaryAge += 0.4; + } + } if (V.PC.majorInjury > 0) { V.PC.majorInjury--; } @@ -54,7 +61,8 @@ App.EndWeek.nextWeek = function() { } if (V.PC.lactation === 1) { if (V.PC.lactationDuration === 1) { - V.PC.boobsMilk = Math.round(10 * V.PC.lactationAdaptation); + V.PC.boobsMilk = Math.round(milkAmount(V.PC)); + // V.PC.boobsMilk = Math.round(10 * V.PC.lactationAdaptation); V.PC.boobs += V.PC.boobsMilk; } } @@ -68,6 +76,16 @@ App.EndWeek.nextWeek = function() { } else if (V.PC.fertPeak !== 0) { V.PC.fertPeak = 0; } + /* irregular leptin production weight gain/loss setter */ + if (V.PC.geneticQuirks.wGain === 2 && V.PC.geneticQuirks.wLoss === 2) { + V.PC.weightDirection = either(-1, 1); + } else if (V.PC.geneticQuirks.wLoss === 2) { + V.PC.weightDirection = -1; + } else if (V.PC.geneticQuirks.wGain === 2 || V.PC.geneMods.livestock === 1) { + V.PC.weightDirection = 1; + } else { + V.PC.weightDirection = 0; + } // Adding random changes to the economy if (V.difficultySwitch === 1) { @@ -156,7 +174,8 @@ App.EndWeek.nextWeek = function() { } if (slave.lactation === 1) { if (slave.lactationDuration === 1) { - slave.boobsMilk = Math.round(10 * slave.lactationAdaptation); + slave.boobsMilk = Math.round(milkAmount(slave)); + // slave.boobsMilk = Math.round(10 * slave.lactationAdaptation); slave.boobs += slave.boobsMilk; } } @@ -221,10 +240,10 @@ App.EndWeek.nextWeek = function() { /* irregular leptin production weight gain/loss setter */ if (slave.geneticQuirks.wGain === 2 && slave.geneticQuirks.wLoss === 2) { slave.weightDirection = either(-1, 1); - } else if (slave.geneticQuirks.wGain === 2) { - slave.weightDirection = 1; } else if (slave.geneticQuirks.wLoss === 2) { slave.weightDirection = -1; + } else if (slave.geneticQuirks.wGain === 2 || slave.geneMods.livestock === 1) { + slave.weightDirection = 1; } else { slave.weightDirection = 0; } @@ -249,7 +268,7 @@ App.EndWeek.nextWeek = function() { slave.skill.whoring = Math.clamp(slave.skill.whoring.toFixed(1), 0, 100); slave.skill.entertainment = Math.clamp(slave.skill.entertainment.toFixed(1), 0, 100); slave.skill.combat = Math.clamp(slave.skill.combat.toFixed(1), 0, 100); - slave.lactationAdaptation = Math.clamp(slave.lactationAdaptation.toFixed(1), 0, 100); + slave.lactationAdaptation = Math.clamp(slave.lactationAdaptation.toFixed(1), 0, 200); slave.intelligenceImplant = Math.clamp(slave.intelligenceImplant.toFixed(1), -15, 30); slave.prematureBirth = 0; if (V.HGSuiteEquality === 1 && V.HeadGirlID !== 0 && slave.devotion > 50) { diff --git a/src/endWeek/player/prDiet.js b/src/endWeek/player/prDiet.js index ce01e0b917e6d082cb0525233b268e80a1814bdb..094cf8a9f4d59be193a1b9ccf15113e616053ceb 100644 --- a/src/endWeek/player/prDiet.js +++ b/src/endWeek/player/prDiet.js @@ -890,7 +890,7 @@ App.EndWeek.Player.diet = function(PC = V.PC) { } } PC.weight = Math.clamp(PC.weight - 3, -100, 200); - } else if (PC.weightDirection === 1 && PC.weight < 200) { + } else if (PC.weightDirection === 1 && PC.geneticQuirks.wGain === 2 && PC.weight < 200) { if (V.geneticMappingUpgrade >= 1) { r.push(`Your body <span class="lime">aggressively stores fat</span> due to your`); if (PC.geneticQuirks.wGain === 2 && PC.geneticQuirks.wLoss === 2) { @@ -905,5 +905,12 @@ App.EndWeek.Player.diet = function(PC = V.PC) { PC.weight++; } } + if (PC.geneMods.livestock === 1) { + if (["fattening", "restricted", "slimming", "corrective", "XX", "XXY"].includes(PC.diet)) { + r.push(`The gene therapy to boost your productivity has a side effect of weight gain, but it really feels like it's just trying to <class="lime">fatten you up for wholesale.</span>`); + } else if (["restricted", "slimming"].includes(PC.diet)) { + r.push(`The gene therapy to boost your productivity has a side effect of weight gain, but it really feels like it's just trying to <class="orange">keep you fat for wholesale.</span>`); + } + } } }; diff --git a/src/endWeek/player/prLongTermEffects.js b/src/endWeek/player/prLongTermEffects.js index 94e00fbd876ed64c344bd7c0cd3826d2ab009ade..82e369baf31d3293e3b83794813bd3fd216e2d24 100644 --- a/src/endWeek/player/prLongTermEffects.js +++ b/src/endWeek/player/prLongTermEffects.js @@ -16,6 +16,7 @@ App.EndWeek.Player.longTermEffects = function(PC = V.PC) { if (PC.pubertyXX === 0 || PC.pubertyXY === 0) { puberty(); } + // Period stuff will go here, remember progenitor mod causes periods to be heavy. r.push(App.EndWeek.Player.pregnancy()); if (PC.bellyFluid >= 100) { r.push(App.EndWeek.Player.inflation()); @@ -788,7 +789,7 @@ App.EndWeek.Player.longTermEffects = function(PC = V.PC) { } else if (WombBirthReady(PC, PC.pregData.normalBirth) > 0 && (random(1, 100) > 50)) { // check for really ready fetuses - 40 weeks - normal startLabor(PC); - } else if (WombBirthReady(PC, PC.pregData.normalBirth / 1.1111) > 0 && (random(1, 100) > 90)) { + } else if (WombBirthReady(PC, PC.pregData.normalBirth / 1.1111) > 0 && (random(1, 100) > 90) && PC.geneMods.progenitor !== 1) { // check for really ready fetuses - 36 weeks minimum startLabor(PC); } @@ -833,7 +834,7 @@ App.EndWeek.Player.longTermEffects = function(PC = V.PC) { } } miscarriageChance = Math.round(miscarriageChance); - if (miscarriageChance > random(0, 100)) { + if (miscarriageChance > random(0, 100) && slave.geneMods.progenitor !== 1) { const chance = random(1, 100); if (PC.preg >= PC.pregData.normalBirth / 1.33) { startLabor(PC); diff --git a/src/endWeek/player/prLongTermPhysicalEffects.js b/src/endWeek/player/prLongTermPhysicalEffects.js index 86337259774c77747e274dc4248b689a16739f66..85635ff42bf26a8caa5db0b3461c4b02563a1df7 100644 --- a/src/endWeek/player/prLongTermPhysicalEffects.js +++ b/src/endWeek/player/prLongTermPhysicalEffects.js @@ -868,6 +868,9 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) { } } } + if (PC.lactation > 0 && PC.geneMods.livestock === 1 && PC.lactationAdaptation < 200) { + PC.lactationAdaptation = Math.min(PC.lactationAdaptation + 4, 200); + } } function boobsEffects() { @@ -927,7 +930,7 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) { } function bellyEffects() { - if (PC.pregAdaptation > 40 && (PC.belly < 5000 && PC.preg < 1 && PC.pregWeek === 0) && PC.geneticQuirks.uterineHypersensitivity !== 2) { + if (PC.pregAdaptation > 40 && (PC.belly < 5000 && PC.preg < 1 && PC.pregWeek === 0) && PC.geneticQuirks.uterineHypersensitivity !== 2 && PC.geneMods.livestock !== 1 && PC.geneMods.progenitor !== 1) { if (PC.pregAdaptation > 1001) { // TODO: Compact, or expand useless branches below PC.pregAdaptation--; } else if (PC.pregAdaptation >= 751 && PC.pregAdaptation < 1000) { diff --git a/src/endWeek/player/prMobility.js b/src/endWeek/player/prMobility.js index a982cdca9ee423882ccde79745f2c2f9727b0e69..dfbef99b90a51eb2bb39b2cdae4f1b7a8070487d 100644 --- a/src/endWeek/player/prMobility.js +++ b/src/endWeek/player/prMobility.js @@ -110,6 +110,8 @@ App.EndWeek.Player.mobility = function(PC = V.PC) { r.push(`<span class="hindrance high">You are on mandatory bed rest due to serious injury.</span> You won't be able to do much until your body recovers.`); } else if (PC.health.condition < -90) { r.push(`<span class="hindrance high">You are on mandatory bed rest due to your poor health.</span> You won't be doing much other than sleeping until you recover.`); + } else if (PC.geneMods.rapidCellGrowth !== 1 && PC.bellyPreg >= 100000 && PC.belly > (PC.pregAdaptation * 3200) && (PC.bellyPreg >= 500000 || PC.wombImplant !== "restraint")) { + r.push(`<span class="hindrance high">You are on mandatory bed rest</span> in the hope that staying relatively still will keep ${V.seeExtreme === 1 && V.dangerousPregnancy === 1 ? "your strained belly from bursting open" : "the dam holding back the flood waters from breaking."}.`); } else if ((PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20)) || (PC.bellyPreg >= PC.pregAdaptation * 2200)) { r.push(`<span class="hindrance high">You are on bed rest</span> in an attempt to not further complicate your already troublesome pregnancy. While it is not compulsory, it does cut into both your work and play time.`); } @@ -369,6 +371,12 @@ App.EndWeek.Player.mobility = function(PC = V.PC) { PC.pregAdaptation += .1 * RCGmod; } } + if (PC.geneMods.progenitor === 1 && PC.belly > (PC.pregAdaptation * 750)) { + if (PC.belly > (PC.pregAdaptation * 1000)) { + r.push(`At least your genetically treated body is raipidly adjusting to your gravidity.`); + } + PC.pregAdaptation += 1; + } if (PC.wombImplant === "restraint" && PC.belly >= 400000) { r.push(`The mesh implanted into the walls of your uterus is nearing its limit and <span class="health dec">beginning to strangle</span> the organ it is meant to support. While it is still structurally sound, it may fail on you if it is forced to stretch much more.`); healthDamage(PC, 15, 2); diff --git a/src/endWeek/player/prPregnancy.js b/src/endWeek/player/prPregnancy.js index ddfd2ed5eb8354b6a64c9f7d9854fa11e92ba68f..d64b59e3fccabaaeb7f1e69995c2805c263dbdf7 100644 --- a/src/endWeek/player/prPregnancy.js +++ b/src/endWeek/player/prPregnancy.js @@ -471,6 +471,12 @@ App.EndWeek.Player.pregnancy = function(PC = V.PC) { function impregnation() { if (PC.vagina === 0 || (PC.anus === 0 && PC.mpreg > 0)) { // You aren't putting out. + if (isVirile(PC) && PC.geneMods.aggressiveSperm === 1 && canFemImpreg(PC, PC)) { + // But ejaculating with the sperm mod can result in splashback. More sex, more chances. + if (random(1, 100) > (99 - (PC.energy / 2))) { + knockMeUp(PC, 0, 2, -1); // 0% chance is correct. Gene mod adds 75% in knockMeUp(). + } + } } else if (random(1, 100) > (70 - (V.reproductionFormula * 10))) { /** @type {Map<FC.Assignment, number>} */ const assignmentWeight = new Map([ @@ -502,6 +508,10 @@ App.EndWeek.Player.pregnancy = function(PC = V.PC) { if (onBedRest(PC) && weight < 3) { weight = 0; } + if (s.geneMods.aggressiveSperm === 1) { // Doing it with someone with the sperm mod is pretty much going to have them knock you up. + weight *= 20; + } + return weight; }; @@ -517,6 +527,13 @@ App.EndWeek.Player.pregnancy = function(PC = V.PC) { knockMeUp(PC, 100, 2, chosenDadID); } } + if (canGetPregnant(PC) && !onBedRest(PC, true) && !isPCCareerInCategory("servant")) { + // Sperm mod leavings around the penthouse. Gives servants more of a point too. + let slobs = V.slaves.filter(s => canFemImpreg(PC, s) && isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === "mindbroken" || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10))); + if (slobs.length > (totalServantCapacity() / 5)) { + knockMeUp(PC, -50, 2, slobs.random()); + } + } } function autoImpregnation() { diff --git a/src/endWeek/reports/clinicReport.js b/src/endWeek/reports/clinicReport.js index 8f1b20dc11ffdd365bd22b3671e8da4859cdb377..c8c53acf6c2866239846f5981f5dba82453ed83f 100644 --- a/src/endWeek/reports/clinicReport.js +++ b/src/endWeek/reports/clinicReport.js @@ -367,7 +367,7 @@ App.EndWeek.clinicReport = function() { remainReasons.push(`to hurry ${his} pregnancy along safely`); } if (V.clinicObservePregnancy !== 0) { - const highRisk = slave.pregAdaptation * 1000 < slave.bellyPreg; + const highRisk = (slave.pregAdaptation * 1000 < slave.bellyPreg && slave.geneMods.progenitor !== 1) || (slave.geneMods.rapidCellGrowth !== 1 && slave.bellyPreg >= 100000 && slave.belly > (slave.pregAdaptation * 3200) && (slave.bellyPreg >= 500000 || slave.wombImplant !== "restraint")); const closeToGivingBirth = slave.preg > slave.pregData.normalBirth / 1.33; if (highRisk || (V.clinicObservePregnancy === 1 && closeToGivingBirth)) { remainReasons.push(`to wait for childbirth`); diff --git a/src/endWeek/reports/personalAttention.js b/src/endWeek/reports/personalAttention.js index 250182d354a7fc5421f61ae19e93700c470e81a1..872108b692a8bd7c98e7d80b602a245e0fd7288f 100644 --- a/src/endWeek/reports/personalAttention.js +++ b/src/endWeek/reports/personalAttention.js @@ -76,7 +76,7 @@ App.PersonalAttention.slaveReport = function(slave) { let milkTotal = 0; let oldSkill; const hindranceMod = isHinderedDegree(V.PC); - const nymphoMod = isPlayerHorny(V.PC) ? .75 : 1; + const nymphoMod = isHorny(V.PC) ? .75 : 1; if (pa.objective === "health") { r.push(App.UI.DOM.makeElement("span", `You care for`, ["bold"])); } else if (pa.objective === "spar") { diff --git a/src/endWeek/reports/spaReport.js b/src/endWeek/reports/spaReport.js index e98640a80dad5a6504c53b7be419a0ff71ac3585..804768e12af2eb22c834d054b5a6fed9c0b26a53 100644 --- a/src/endWeek/reports/spaReport.js +++ b/src/endWeek/reports/spaReport.js @@ -294,9 +294,23 @@ App.EndWeek.spaReport = function() { App.Events.addNode(el, r, "p", ["indent", "bold"]); } + if (App.EndWeek.saVars.poolJizz > ((S.Attendant && canSee(S.Attendant)) ? 5000 : 1000)) { + r.push(`The filters${S.Attendant ? ` and ${S.Attendant.slaveName}` : ""} have been overwhelmed by the sheer quantity of resilient sperm swimming around in the pool.`); + if (V.seePreg) { + r.push(`Any woman that enters these fertile waters is liable to be gifted with new life.`); + } + App.Events.addNode(el, r, "div", "indent"); + } + if (S.Attendant) { const slave = App.SlaveAssignment.reportSlave(S.Attendant); tired(slave); + if (isFertile(slave) && slave.preg !== -1 && App.EndWeek.saVars.poolJizz > (canSee(S.Attendant) ? 5000 : 1000)) { // Free swimming sperm do not respect chastity and the Attendant can not avoid going in the pool. + const spermAtt = weightedRandom(App.EndWeek.saVars.poolJizzers); + if (canBreed(slave, getSlave(spermAtt.ID))) { + knockMeUp(slave, 25, 2, spermAtt.ID); + } + } /* apply following SA passages to facility leader */ if (V.showEWD !== 0) { const attendantEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report"); @@ -310,7 +324,7 @@ App.EndWeek.spaReport = function() { } for (const slave of App.SlaveAssignment.reportSlaves(slaves)) { - const {He, he, his} = getPronouns(slave); + const {He, he, his, him} = getPronouns(slave); slave.devotion += devBonus; improveCondition(slave, 5 + healthBonus); if (slave.health.condition < -80) { @@ -327,9 +341,31 @@ App.EndWeek.spaReport = function() { slave.devotion++; slave.trust++; } else if (slave.trust < 40) { - slave.trust += 10; + if (slave.geneMods.aggressiveSperm === 1 && isVirile(slave) && S.Attendant && V.spaAggroSpermBan === 1) { + slave.trust += 5; + } else { + slave.trust += 10; + } } else if (slave.devotion < 40) { - slave.devotion += 10; + if (slave.geneMods.aggressiveSperm === 1 && isVirile(slave) && S.Attendant && V.spaAggroSpermBan === 1) { + slave.devotion += 5; + } else { + slave.devotion += 10; + } + } + if (App.EndWeek.saVars.poolJizz > ((S.Attendant && canSee(S.Attendant)) ? 5000 : 1000) && (V.spaAggroSpermBan === 0 || slave.breedingMark === 0)) { // 0 breeds all, 1 doesn't reach here, and 2 fails if .breedingMark is 0. + if (slave.fetish === "cumslut" && (canSee(slave) || canTaste(slave) || canSmell(slave))) { + slave.devotion++; + } + if (isFertile(slave) && slave.preg !== -1) { // Free swimming sperm do not respect chastity. + const spermSlave = weightedRandom(App.EndWeek.saVars.poolJizzers); + if (canBreed(slave, getSlave(spermSlave.ID))) { + knockMeUp(slave, 25, 2, spermSlave.ID); + } + if (slave.sexualFlaw === "breeder" && (canSee(slave) || canTaste(slave) || canSmell(slave))) { + slave.devotion++; + } + } } switch (V.spaDecoration) { case "Chattel Religionist": @@ -392,6 +428,11 @@ App.EndWeek.spaReport = function() { r.push(`${He} remains in the Spa, stubborn in ${his} flaw.`); } else if (slave.trust < 60 || slave.devotion < 60) { r.push(`${He} remains in the Spa, as ${he} is still learning to accept life as a slave.`); + if (slave.geneMods.aggressiveSperm === 1 && isVirile(slave) && S.Attendant && V.spaAggroSpermBan === 1) { + if (slave.devotion < 40 || slave.trust < 40) { + r.push(`${He} wishes ${S.Attendant.slaveName} would allow ${him} to enjoy the main pool.`); + } + } } else if (slave.health.condition < 20) { r.push(`${He} remains in the Spa, as ${he} is benefiting from its healing properties.`); } else if (slave.health.tired > 30) { diff --git a/src/endWeek/saAgent.js b/src/endWeek/saAgent.js index f7031b142ec4f6e4776e0a366e09281b37ba34d9..35e2ab91b3eeb24665971cd370bbb90b814c8477 100644 --- a/src/endWeek/saAgent.js +++ b/src/endWeek/saAgent.js @@ -568,6 +568,9 @@ App.SlaveAssignment.agent = function(slave) { slave.lactation = 1; } } + if (slave.lactation > 0 && slave.geneMods.livestock === 1 && slave.lactationAdaptation < 200) { + slave.lactationAdaptation = Math.min(slave.lactationAdaptation + 4, 200); + } if (slave.lactation === 0 && slave.geneticQuirks.galactorrhea === 2 && random(1, 100) <= slave.hormoneBalance) { slave.lactationDuration = 2; slave.lactation = 1; diff --git a/src/endWeek/saDiet.js b/src/endWeek/saDiet.js index be8cab3982573d5aa13eaea6ff05e4443f0edee3..41f848b9018529df33d08e1da0fb4997e679b0c8 100644 --- a/src/endWeek/saDiet.js +++ b/src/endWeek/saDiet.js @@ -1504,7 +1504,7 @@ App.SlaveAssignment.diet = function saDiet(slave) { } } slave.weight = Math.clamp(slave.weight - 3, -100, 200); - } else if (slave.weightDirection === 1 && slave.weight < 200) { + } else if (slave.weightDirection === 1 && slave.geneticQuirks.wGain === 2 && slave.weight < 200) { if (V.geneticMappingUpgrade >= 1) { r.push(`${His} body <span class="lime">aggressively stores fat</span> due to ${his}`); if (slave.geneticQuirks.wGain === 2 && slave.geneticQuirks.wLoss === 2) { @@ -1516,6 +1516,9 @@ App.SlaveAssignment.diet = function saDiet(slave) { slave.weight = Math.clamp(slave.weight + 3, -100, 200); } } + if (slave.geneMods.livestock === 1 && ["fattening", "restricted", "slimming", "corrective", "XX", "XXY"].includes(slave.diet)) { + r.push(`The gene therapy to boost ${his} productivity has a side effect of weight gain, and since it complicates weight loss in the process, it might as well be <class="lime">fattening ${him} up for wholesale.</span>`); + } } /** diff --git a/src/endWeek/saGetMilked.js b/src/endWeek/saGetMilked.js index 4e73732bb5970ef3278e1c3ae23d8f052a8ef064..6ce658d24e4c32aa9ff340f91dd47539685c6baa 100644 --- a/src/endWeek/saGetMilked.js +++ b/src/endWeek/saGetMilked.js @@ -259,7 +259,9 @@ } if (slave.lactationAdaptation > 10) { - if (slave.lactationAdaptation > 50) { + if (slave.lactationAdaptation > 150) { + r.text += ` ${His} body has completely redesigned itself around milk production, making ${him} a shining example of productivity.`; + } else if (slave.lactationAdaptation > 50) { r.text += ` ${His} body has adapted heavily to milk production, making ${him} extremely productive.`; } else { r.text += ` ${His} body has gotten used to producing milk, making ${him} very productive.`; @@ -477,8 +479,16 @@ r.text += ` balls.`; } - if (slave.diet === "cum production") { - r.text += ` ${His} diet is designed for cum production.`; + if (isVirile(slave)) { + if (slave.geneMods.aggressiveSperm === 1) { + r.text += ` ${His} testicles produce oversized, durable sperm cells that are not only difficult to ejaculate out en mass, but also tend to clog the tubing with their density, lowering ${his} overall productivity.`; + } + if (slave.geneMods.livestock === 1) { + r.text += ` ${He} has been genetically altered to overproduce sperm.`; + } + if (slave.diet === "cum production") { + r.text += ` ${His} diet is designed for cum production.`; + } } const cumHormones = (slave.hormoneBalance / 50); @@ -492,8 +502,10 @@ r.text += ` ${His} internal chemistry is poorly suited to cum production.`; } - if (slave.scrotum === 0) { - r.text += ` ${He} does produce cum despite ${his} apparent ballslessness, but less than ${he} would if they weren't hidden inside ${him}.`; + if (isVirile(slave)) { + if (slave.scrotum === 0) { + r.text += ` ${He} does produce cum despite ${his} apparent ballslessness, but less than ${he} would if they weren't hidden inside ${him}.`; + } } if (slave.prostate > 0) { @@ -526,6 +538,12 @@ } else if (slave.ballType === "sterile") { r.text += ` ${His} cum lacks vigor entirely, thanks to ${his} chemical castration, <span class="cash dec">considerably lowering the value</span> of ${his} ejaculate.`; qualityMultiplier *= 0.2; + } else if (!isVirile(slave)) { + r.text += ` ${His} cum lacks the primary ingredient, sperm, as ${he} has not yet become a man. While it is <span class="cash dec">valued less</span> than normal ejaculate, this unique fluid is still valuable to certain groups.`; + qualityMultiplier *= 0.8; + } else if (slave.geneMods.aggressiveSperm === 1) { + r.text += ` ${His} vigorous cum is considered exotic, <span class="cash inc">increasing its value</span> and helping to offset the losses from harvesting it.`; + qualityMultiplier *= 1.3; } if (slave.assignment === Job.DAIRY) { @@ -595,7 +613,7 @@ } } - if (slave.balls < 3 && slave.ballType !== "sterile") { + if (slave.balls < 3 && isVirile(slave)) { if (slave.balls < 2) { if (jsRandom(1, 100) > (70 + (slave.geneMods.NCS * 15))) { r.text += ` Constant semen production and continual emptying and refilling <span class="change positive">increases the size of ${his} tiny testicles.</span>`; @@ -622,6 +640,9 @@ r.text += ` ${His} natural vaginal secretions add to the mix.`; } } + if (slave.geneMods.livestock === 1) { + r.text += ` ${His} genetic alterations aid in increasing the volume.`; + } if (slave.energy > 10) { if (slave.health.condition > 50) { if (slave.energy > 90) { diff --git a/src/endWeek/saLongTermEffects.js b/src/endWeek/saLongTermEffects.js index 68b43ec5d58c992db559f05f9a9eaef88ae66ec9..c1cd74bb10a7a5121f603eb69737ecfde5e849e0 100644 --- a/src/endWeek/saLongTermEffects.js +++ b/src/endWeek/saLongTermEffects.js @@ -2283,7 +2283,7 @@ App.SlaveAssignment.longTermEffects = function saLongTermEffects(slave) { } else if (WombBirthReady(slave, slave.pregData.normalBirth) > 0 && (random(1, 100) > 50)) { // check for really ready fetuses - 40 weeks - normal startLabor(slave); - } else if (WombBirthReady(slave, slave.pregData.normalBirth / 1.1111) > 0 && (random(1, 100) > 90)) { + } else if (WombBirthReady(slave, slave.pregData.normalBirth / 1.1111) > 0 && (random(1, 100) > 90) && slave.geneMods.progenitor !== 1) { // check for really ready fetuses - 36 weeks minimum startLabor(slave); } @@ -2346,7 +2346,7 @@ App.SlaveAssignment.longTermEffects = function saLongTermEffects(slave) { } } miscarriageChance = Math.round(miscarriageChance); - if (miscarriageChance > random(0, 100)) { + if (miscarriageChance > random(0, 100) && slave.geneMods.progenitor !== 1) { // Progenitor refuses to miscarry or give birth early. const chance = random(1, 100); if (slave.preg >= slave.pregData.normalBirth / 1.33) { startLabor(slave); diff --git a/src/endWeek/saLongTermPhysicalEffects.js b/src/endWeek/saLongTermPhysicalEffects.js index d0119f3be1bde16bba25a267f03481df3151c5a2..bd824d82c785374fdc45717e90432a00707fa61c 100644 --- a/src/endWeek/saLongTermPhysicalEffects.js +++ b/src/endWeek/saLongTermPhysicalEffects.js @@ -534,7 +534,7 @@ App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects const pa = V.personalAttention.slaves.find((s) => s.ID === slave.ID); // This can probably be improved. if (pa.objective === "spar") { if (canWalk(V.PC) && canWalk(slave) && hasAnyArms(V.PC) && hasAnyArms(slave) && canSee(slave) && slave.fetish !== "mindbroken") { - if (isPlayerHorny(V.PC)) { + if (isHorny(V.PC)) { if (slave.energy > 95 || slave.aphrodisiacs > 0 || slave.inflationType === "aphrodisiac") { slave.need = 0; } @@ -1143,6 +1143,9 @@ App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects } } } + if (slave.lactation > 0 && slave.geneMods.livestock === 1 && slave.lactationAdaptation < 200) { + slave.lactationAdaptation = Math.min(slave.lactationAdaptation + 4, 200); + } if (slave.breastMesh !== 1) { if (slave.boobs - (slave.muscles * 30) > 5000 && slave.boobs <= 8000 && slave.boobsImplant / slave.boobs < .50) { // Check now requires breasts to be less than half implant to sag. if (slave.physicalAge < random(10, 200)) { @@ -1205,7 +1208,7 @@ App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects * */ function bellyEffects(slave) { - if (slave.pregAdaptation > 40 && (slave.belly < 5000 && slave.preg < 1 && slave.pregWeek === 0) && slave.geneticQuirks.uterineHypersensitivity !== 2) { + if (slave.pregAdaptation > 40 && (slave.belly < 5000 && slave.preg < 1 && slave.pregWeek === 0) && slave.geneticQuirks.uterineHypersensitivity !== 2 && slave.geneMods.livestock !== 1 && slave.geneMods.progenitor !== 1) { if (slave.pregAdaptation > 1001) { // TODO: Compact, or expand useless branches below slave.pregAdaptation--; } else if (slave.pregAdaptation >= 751 && slave.pregAdaptation < 1000) { @@ -2359,12 +2362,16 @@ App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects slave.pregAdaptation += .1; } } + if (slave.geneMods.progenitor === 1 && slave.belly > (slave.pregAdaptation * 750)) { + r.push(`${His} genetically altered body quickly adjusts to ${his} increased gravidity.`); + slave.pregAdaptation += 1; + } if (slave.wombImplant === "restraint" && slave.belly >= 400000) { r.push(`The mesh implanted into the walls of ${his} uterus is nearing its limit and <span class="health dec">beginning to strangle</span> the organ it is meant to support. While it is still structurally sound, it can only expand so much before failing.`); healthDamage(slave, 15); } - if (V.seeExtreme === 1 && V.dangerousPregnancy === 1 && ((slave.belly > (slave.pregAdaptation * 3200)) || slave.bellyPreg > 600000) && slave.bellyPreg >= 100000) { + if (V.seeExtreme === 1 && V.dangerousPregnancy === 1 && slave.geneMods.rapidCellGrowth !== 1 && slave.bellyPreg >= 100000 && slave.belly > (slave.pregAdaptation * 3200) && (slave.bellyPreg >= 500000 || slave.wombImplant !== "restraint")) { if (slave.assignment === Job.CLINIC) { if (S.Nurse) { r.push(`The fast actions of ${V.clinicName}'s nurse, ${S.Nurse.slaveName}, saved ${his} life a few times. <span class="health dec">${His} womb is breaking!</span>`); diff --git a/src/endWeek/saPregnancy.js b/src/endWeek/saPregnancy.js index fffee9a4371edb1a55e675d47a0c61becac78d42..20a2c114ea03a67e04ef1b8dd7fef860973d5479 100644 --- a/src/endWeek/saPregnancy.js +++ b/src/endWeek/saPregnancy.js @@ -938,6 +938,12 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { } } else if ((slave.vagina === 0 || (slave.anus === 0 && slave.mpreg > 0)) && !studIgnoresRules) { // Skip virgins. + if (isVirile(slave) && slave.geneMods.aggressiveSperm === 1 && canFemImpreg(slave, slave)) { + // Ejaculating with the sperm mod can result in splashback. More sex, more chances. + if (random(1, 100) > (99 - (slave.energy / 2))) { + knockMeUp(slave, 0, 2, slave.ID); // 0% chance is correct. Gene mod adds 75% in knockMeUp(). + } + } } else if (V.HeadGirlID !== 0 && slave.ID !== V.HeadGirlID && V.universalRulesImpregnation === "HG" && canPenetrate(S.HeadGirl) && (slave.pregKnown === 0 || (V.universalRulesSuperfetationImpregnation === 1 && slave.geneticQuirks.superfetation === 2 && (slave.pregKnown === 1 || V.geneticMappingUpgrade > 0 || slave.counter.birthsTotal > 0)))) { const { he2, His2, his2, him2, @@ -1757,6 +1763,13 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { knockMeUp(slave, 100, 2, pregSource); } } /* closes random chance and non-zero sex acts check */ + if (canGetPregnant(slave) && canWalk(slave) && isSlaveAvailable(slave) && (V.personalAttention.task !== PersonalAttention.MAID || onBedRest(V.PC))) { + // Sperm mod leavings around the penthouse. Gives servants more of a point too. + let slobs = V.slaves.filter(s => canFemImpreg(slave, s) && isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === "mindbroken" || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10))); + if (slobs.length > (totalServantCapacity() / 5)) { + knockMeUp(slave, -50, 2, slobs.random()); + } + } } /* closes assignment checks */ } /* closes all impregnation checks */ } diff --git a/src/endWeek/saRewardAndPunishment.js b/src/endWeek/saRewardAndPunishment.js index dce20eff661c3152d0e7ec6909050553013c49be..57bdef76992255e1f7c6a298db6b7232e8dc8b4e 100644 --- a/src/endWeek/saRewardAndPunishment.js +++ b/src/endWeek/saRewardAndPunishment.js @@ -73,15 +73,50 @@ App.SlaveAssignment.rewardAndPunishment = function rewardAndPunish(forSlave) { } else if (slave.assignment === Job.ATTENDANT) { r.push(`usually spends soaking in a hot bath or enjoying the amenities ${his} facility has to offer.`); } else if (slave.assignment === Job.CONCUBINE) { - if (V.spa !== 0) { + if (onBedRest(V.PC, true)) { + r.push(`usually spends in bed with you, helping to ease your worries.`); + } else if (V.spa !== 0) { r.push(`usually sets aside to spend with you in ${V.spaName}.`); + if (App.EndWeek.saVars.poolJizz > ((S.Attendant && canSee(S.Attendant)) ? 5000 : 1000)) { + if (V.PC.intelligence + V.PC.intelligenceImplant < 10 || !canSee(V.PC)) { // Free swimming sperm do not respect chastity. + let sperm; + if (isFertile(slave) && slave.preg !== -1) { + sperm = weightedRandom(App.EndWeek.saVars.poolJizzers); + if (canBreed(slave, getSlave(sperm.ID))) { + knockMeUp(slave, 25, 2, sperm.ID); + } + } + if (isFertile(V.PC) && V.PC.preg !== -1) { + sperm = weightedRandom(App.EndWeek.saVars.poolJizzers); + if (canBreed(V.PC, getSlave(sperm.ID))) { + knockMeUp(V.PC, 25, 2, sperm.ID); + } + } + } + } } else { r.push(`usually spends relaxing with you.`); } } else if (V.spa !== 0) { - const where = (slave.assignment !== Job.SPA) ? V.spaName : `a private bath`; + const where = (slave.assignment !== Job.SPA || slave.breedingMark) ? V.spaName : `a private bath`; const attendant = S.Attendant ? `, enjoying ${S.Attendant.slaveName}'s care` : ``; r.push(`usually spends in ${where}${attendant}.`); + if (slave.assignment !== Job.SPA && slave.breedingMark === 0 && App.EndWeek.saVars.poolJizz > ((S.Attendant && canSee(S.Attendant)) ? 5000 : 1000)) { + if (slave.fetish === "cumslut" && (canSee(slave) || canTaste(slave) || canSmell(slave))) { + r.push(`As an added bonus, ${he} gets to soak in a pool teeming with live sperm; <span class="hotpink">what luck!</span>`); + slave.devotion++; + } + if (isFertile(slave) && slave.preg !== -1) { // Free swimming sperm do not respect chastity. + const sperm = weightedRandom(App.EndWeek.saVars.poolJizzers); + if (canBreed(slave, getSlave(sperm.ID))) { + knockMeUp(slave, 25, 2, sperm.ID); + } + if (slave.sexualFlaw === "breeder" && (canSee(slave) || canTaste(slave) || canSmell(slave))) { + r.push(`${He} finds the ropes of cum swarming ${his} loins <span class="hotpink">a nice touch.</span>`); + slave.devotion++; + } + } + } } else if (slave.assignment === Job.MASTERSUITE) { r.push(`usually spends relaxing on ${his} favorite pillow.`); } else if (slave.assignment === Job.HEADGIRLSUITE) { diff --git a/src/endWeek/saSharedVariables.js b/src/endWeek/saSharedVariables.js index d4c7d2942ea2b35b34452bc6f74fa075ca644e8a..79c9462c8fac022ad9f7dd50355bbfcd99d3fe78 100644 --- a/src/endWeek/saSharedVariables.js +++ b/src/endWeek/saSharedVariables.js @@ -22,6 +22,10 @@ App.EndWeek.SASharedVariables = class { this.whorePriceAdjustment = {}; /** How many slaves can the designated stud still impregnate? */ this.StudCum = 0; + /** Are slaves with the agressive sperm gene mod jacking off or having sex in the spa pool? */ + this.poolJizz = 0; + /** Which agressive sperm slaves are knocking up the spa bathers? */ + this.poolJizzers = []; /** How much energy does the player have left to fuck slaves who need it? */ this.freeSexualEnergy = 0; /** How big is the average dick on a slave? */ diff --git a/src/endWeek/slaveAssignmentReport.js b/src/endWeek/slaveAssignmentReport.js index 67e489f2530cf11591cd384badff6b59b46132bf..54a996fc5d422123134e15195e45cd12ef9d3ee1 100644 --- a/src/endWeek/slaveAssignmentReport.js +++ b/src/endWeek/slaveAssignmentReport.js @@ -162,6 +162,18 @@ App.EndWeek.slaveAssignmentReport = function() { } } // for (const slave of V.slaves) + // Optimized sperm slaves cumming up the spa pool. + if (facilities.spa.established) { + let cum; + for (const slave of App.Utils.sortedEmployees(App.Entity.facilities.spa)) { + if (slave.geneMods.aggressiveSperm === 1 && isVirile(slave) && (slave.rules.release.masturbation || App.Utils.hasNonassignmentSex(slave) || slave.rules.release.facilityLeader) && slave.energy > 20 && (!S.Attendant || V.spaAggroSpermBan !== 1)) { + cum = Math.trunc(cumAmount(slave) / 2); + App.EndWeek.saVars.poolJizz += cum; + App.EndWeek.saVars.poolJizzers.push({ID: slave.ID, weight: cum}); + } + } + } + if (V.HeadGirlID !== 0) { App.EndWeek.saVars.HGEnergy++; const slave = slaveStateById(V.HeadGirlID); diff --git a/src/events/RESS/review/diet.js b/src/events/RESS/review/diet.js index 73a635c56a87be2e0e089ab3053e83e4906caf89..71e4fb79406ca718ca39c2933b8697a8e5014cf1 100644 --- a/src/events/RESS/review/diet.js +++ b/src/events/RESS/review/diet.js @@ -11,7 +11,7 @@ App.Events.RESSDiet = class RESSDiet extends App.Events.BaseEvent { hasAnyLegs, s => s.devotion <= 50, s => s.trust >= -50, - s => s.behavioralFlaw === "gluttonous", + s => (s.behavioralFlaw === "gluttonous" || s.geneMods.livestock === 1), s => s.diet === "restricted", ] ]; diff --git a/src/facilities/geneLab.js b/src/facilities/geneLab.js index bd24b876d80eb2a7aeffde9ca10974a105df7d27..b37b1b4ff7eac77e51ec0be2c0adab03bccda753 100644 --- a/src/facilities/geneLab.js +++ b/src/facilities/geneLab.js @@ -23,6 +23,7 @@ App.UI.geneLab = function() { App.UI.DOM.appendNewElement("h2", node, `Genetic Modification`); const immortalityCost = 50000000; const flavoringCost = 150000; + const enhancedProductionFormulaCost = 150000 * PCSkillCheck; if (V.dispensaryUpgrade === 0) { App.UI.DOM.appendNewElement("div", node, `The fabricator must be upgraded before it can produce treatments to alter genes`, "note"); } else { @@ -33,6 +34,19 @@ App.UI.geneLab = function() { if (V.RapidCellGrowthFormula === 1) { App.UI.DOM.appendNewElement("div", node, `The fabricator is capable of producing treatments to accelerate cellular reproduction.`); } + if (V.enhancedProductionFormula === 1) { + App.UI.DOM.appendNewElement("div", node, `The fabricator is capable of producing treatments to permanently enhance the production of harvestable resources from dairy slaves. Side effects include, but are not limited to, increased appetite, weight gain, dehydration, and other complications related to overproduction of fluids.`); + } else if (V.cash >= enhancedProductionFormulaCost) { + App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( + "Purchase designs for optimizing dairy slaves", + () => { + cashX(forceNeg(enhancedProductionFormulaCost), "capEx"); + V.enhancedProductionFormula = 1; + App.UI.reload(); + }, [], "", + `Costs ${cashFormat(enhancedProductionFormulaCost)}. Will boost production of harvestable slave resources` + )); + } if (V.immortalityFormula === 1) { App.UI.DOM.appendNewElement("div", node, `The fabricator is capable of producing treatments to permanently reverse aging.`); } else if (V.cash >= immortalityCost) { diff --git a/src/facilities/spa/spa.js b/src/facilities/spa/spa.js index f96267172171444d1cee72bcc8be3bbf987d0b6c..4aa53f535c1357ba8d388d68269e61b845c50942 100644 --- a/src/facilities/spa/spa.js +++ b/src/facilities/spa/spa.js @@ -155,6 +155,39 @@ App.Facilities.Spa.spa = class Spa extends App.Facilities.Facility { }, ], }, + { + property: "spaAggroSpermBan", + prereqs: [ + !!S.Attendant, + V.optimizedSpermFormula > 0, + ], + options: [ + { + get text() { + return `${S.Attendant.slaveName} is to allow all slaves into the main pool, regardless of genetic modifications.`; + }, + link: `Free reign`, + value: 0, + }, + { + get text() { + return `${S.Attendant.slaveName} has banned any slaves with the enhanced sperm treatment from entering the main pool ${V.seePreg ? "and causing random pregnancies" : "and clogging up the filters"}.`; + }, + link: `No optimized sperm`, + value: 1, + }, + { + get text() { + return `${S.Attendant.slaveName} will make sure that no enhanced sperm will ever reach your breeding harem.`; + }, + link: `Protect your harem`, + value: 2, + prereqs: [ + V.propOutcome === 1, + ], + }, + ], + }, ]; } }; diff --git a/src/facilities/surgery/surgeryPassageExotic.js b/src/facilities/surgery/surgeryPassageExotic.js index fb2d825ca317021c6f9a0190607fbe909be12872..517590180937fe700878188219bcc36d3ccb6d58 100644 --- a/src/facilities/surgery/surgeryPassageExotic.js +++ b/src/facilities/surgery/surgeryPassageExotic.js @@ -79,24 +79,56 @@ App.UI.surgeryPassageExotic = function(slave, refresh, cheat = false) { } } - if (V.immortalityFormula === 1) { - if (slave.geneMods.immortality === 0) { + if (V.bioEngineeredFlavoringResearch === 1){ + if (slave.geneMods.flavoring === 0) { linkArray.push(App.Medicine.Surgery.makeLink( - new App.Medicine.Surgery.Procedures.ImmortalityTreatment(slave), + new App.Medicine.Surgery.Procedures.milkFlavoring(slave), refresh, cheat)); } else { - App.UI.DOM.appendNewElement("div", el, `${He} is already immortal`, ["choices", "note"]); + App.UI.DOM.appendNewElement("div", el, `${His} milk can already be flavored`, ["choices", "note"]); } } - if (V.bioEngineeredFlavoringResearch === 1){ - if (slave.milkFlavor === "none") { + + if (V.optimizedSpermFormula === 1) { + if (slave.geneMods.aggressiveSperm === 0) { linkArray.push(App.Medicine.Surgery.makeLink( - new App.Medicine.Surgery.Procedures.milkFlavoring(slave), + new App.Medicine.Surgery.Procedures.OptimizedSpermTreatment(slave), refresh, cheat)); } else { - App.UI.DOM.appendNewElement("div", el, `${His} milk can already be flavored`, ["choices", "note"]); + App.UI.DOM.appendNewElement("div", el, `${His} body has already been altered to produce more aggressive sperm.`, ["choices", "note"]); + } + } + + if (V.enhancedProductionFormula === 1) { + if (slave.geneMods.livestock === 0) { + linkArray.push(App.Medicine.Surgery.makeLink( + new App.Medicine.Surgery.Procedures.EnhancedProductionTreatment(slave), + refresh, cheat)); + } else { + App.UI.DOM.appendNewElement("div", el, `${His} body has already been altered to produce more usable products.`, ["choices", "note"]); } } + + if (V.optimizedBreedingFormula === 1) { + if (slave.geneMods.progenitor === 0) { + linkArray.push(App.Medicine.Surgery.makeLink( + new App.Medicine.Surgery.Procedures.OptimizedBreedingTreatment(slave), + refresh, cheat)); + } else { + App.UI.DOM.appendNewElement("div", el, `${His} body has already been altered to better carry children.`, ["choices", "note"]); + } + } + + if (V.immortalityFormula === 1) { + if (slave.geneMods.immortality === 0) { + linkArray.push(App.Medicine.Surgery.makeLink( + new App.Medicine.Surgery.Procedures.ImmortalityTreatment(slave), + refresh, cheat)); + } else { + App.UI.DOM.appendNewElement("div", el, `${He} is already immortal`, ["choices", "note"]); + } + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); } el.append(retroVirus()); diff --git a/src/interaction/main/fcnn.js b/src/interaction/main/fcnn.js index 48d774bfedbce68938894122b3bd40b0e1e166fd..df83802e33a643695bfc37ed68983e253fe2e87b 100644 --- a/src/interaction/main/fcnn.js +++ b/src/interaction/main/fcnn.js @@ -120,6 +120,10 @@ App.FCNN = (function() { "...and Free Cities have definitely shaken up the stock market in recent..." ]; + const geneMods = [ + "...27 women confirmed pregnant after man masturbates in pool. Should gene therapy..." + ]; + const catgirlsPublic = [ "...Catgirl slaves: Fad, fluke, or fashion? Tune in for an exclusive FCNN interview with Doctor Radomir Nieskowitz later tonight..." ]; @@ -142,6 +146,7 @@ App.FCNN = (function() { {valid: () => V.TFS.schoolUpgrade === 3, text: () => TFSCompromise}, {valid: () => V.FCNNstation === 1, text: () => [`...is FCNN, broadcasting live from its international headquarters within ${V.arcologies[0].name}...`]}, {valid: () => V.corp.Announced === 1, text: () => corpAnnounced}, + {valid: () => V.geneticMappingUpgrade === 1, text: () => geneMods}, {valid: () => V.seeCats === 1 && V.projectN.public === 1, text: () => catgirlsPublic}, {valid: () => V.seeCats === 1 && V.projectN.status >= 5, text: () => projectNComplete}, // custom headlines can be stored in game state by events diff --git a/src/interaction/main/mainLinks.js b/src/interaction/main/mainLinks.js index b589aef0e599d59fe55a59949894a680e77eac87..d7387d58acb8f789d59d0b78a593b9157b67e7c4 100644 --- a/src/interaction/main/mainLinks.js +++ b/src/interaction/main/mainLinks.js @@ -15,6 +15,8 @@ App.UI.View.mainLinks = function() { fragment.append(`You plan to give birth this week.`); } else if (isInduced(V.PC)) { fragment.append(`You are giving birth this week.`); + } else if (V.PC.geneMods.rapidCellGrowth !== 1 && V.PC.bellyPreg >= 100000 && V.PC.belly > (V.PC.pregAdaptation * 3200) && (V.PC.bellyPreg >= 500000 || V.PC.wombImplant !== "restraint")) { + fragment.append(`You're laid up in bed until you pop.`); } } else { switch (V.personalAttention.task) { @@ -37,8 +39,8 @@ App.UI.View.mainLinks = function() { fragment.append(`You plan to make some easy (but dirty) money this week.`); break; case PersonalAttention.FIGHT: - text.push(`You plan to enter a fistfight for some quick (but hopefully not too bloody) money this week.`); - break; + text.push(`You plan to enter a fistfight for some quick (but hopefully not too bloody) money this week.`); + break; case PersonalAttention.SUPPORTHG: fragment.append(`You plan to support your Head Girl this week, `); if (S.HeadGirl) { diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js index 1b3d708fce9166f027cef6e15c3d71d33dceb1f9..2f4285e3dc4b9a598246d1d8d3db5628974b77fb 100644 --- a/src/js/SlaveState.js +++ b/src/js/SlaveState.js @@ -1402,10 +1402,11 @@ App.Entity.SlaveState = class SlaveState { */ this.pregType = 0; /** - * Number of ready to be impregnated ova (override normal cases), - * - * For delayed impregnations with multiples.Used onetime on next call of the SetPregType - * widget. After SetPregType use it to override .pregType, it set back to 0 automatically. + * For function compatibility. + */ + this.pregMood = 0; + /** + * How adapted a slave's body is to being pregnant. 1 pregAdaption supports 1000cc of pregnancy. A normal singleton pregnancy is about 15 pregAdaption. */ this.pregAdaptation = 50; /** @@ -2290,6 +2291,8 @@ App.Entity.SlaveState = class SlaveState { * * **macromastia + gigantomastia** - Breasts never stop growing. Increased growth rate, no shrink rate. */ gigantomastia: 0, + /** sperm is much more likely to knock someone up */ + potent: 0, /** is prone to having twins, shorter pregnancy recovery rate */ fertility: 0, /** is prone to having multiples, even shorter pregnancy recovery rate @@ -2337,6 +2340,9 @@ App.Entity.SlaveState = class SlaveState { mGain: 0, /** constantly loses muscle mass, easier to gain muscle. mGain + mLoss - muscle gain/loss amplified, passively lose muscle unless building */ mLoss: 0, + /** ova will split if room is available + * only affects fetuses */ + twinning: 0, /** slave can only ever birth girls */ girlsOnly: 0 }; @@ -2680,7 +2686,23 @@ App.Entity.SlaveState = class SlaveState { /** Is the slave immortal? * @type {FC.Bool} * 0: no; 1: yes */ - immortality: 0 + immortality: 0, + /** Has the slave been treated to produce flavored milk? + * @type {FC.Bool} + * 0: no; 1: yes */ + flavoring: 0, + /** Has the slave's sperm been optimized? + * @type {FC.Bool} + * 0: no; 1: yes */ + aggressiveSperm: 0, + /** Has the slave been optimized for production? + * @type {FC.Bool} + * 0: no; 1: yes */ + livestock: 0, + /** Has the slave been optimized for child bearing? + * @type {FC.Bool} + * 0: no; 1: yes */ + progenitor: 0 }; /** flavor of their milk*/ this.milkFlavor = "none"; diff --git a/src/js/birth/birth.js b/src/js/birth/birth.js index 50f9361544dcb2d86c5de2415576bcb46c3515ed..cada04583ae40a4437328aba74e97d8a771b850c 100644 --- a/src/js/birth/birth.js +++ b/src/js/birth/birth.js @@ -174,6 +174,9 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen } else if (slave.pregAdaptation >= 100) { suddenBirth += 1; } + if (slave.geneMods.progenitor === 1) { + suddenBirth += 20; // optimized, baby birthing machine + } if (slave.health.condition < 0) { suddenBirth += 2; } @@ -545,7 +548,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen birthDamage += 1; } } - if (slave.hips < 0) { + if (slave.hips < 0 && slave.geneMods.progenitor !== 1) { r.push([ `${His} narrow hips made birth`, App.UI.DOM.makeElement("span", `troublesome.`, ["health", "dec"]) @@ -785,6 +788,15 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen birthDamage -= 1; } + if (slave.geneMods.progenitor === 1) { + r.push([ + `${He} was`, + App.UI.DOM.makeElement("span", `genetically modified to be superior in child bearing;`, ["health", "inc"]), + `${his} body popped ${his} ${children} out like it was nothing.` + ]); + birthDamage -= 200; + } + if (slave.curatives > 0) { r.push([ `${His} `, @@ -1150,7 +1162,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen healthDamage(slave, 10); App.Events.addNode(el, r, "div"); } - if (slave.hips < -1) { + if (slave.hips < -1 && slave.geneMods.progenitor !== 1) { r = []; r.push(`${He} had exceedingly narrow hips, completely unsuitable for childbirth. As ${he} struggled on ${his}`); if (numBeingBorn > 1) { diff --git a/src/js/economyJS.js b/src/js/economyJS.js index 4a80f7f644cc379d490e849fca8fe1ca29e9e868..95886e2f86c4630d6d6eb4337697f7f260c0d67e 100644 --- a/src/js/economyJS.js +++ b/src/js/economyJS.js @@ -860,6 +860,15 @@ globalThis.calculateCosts = (function() { if (V.PC.geneticQuirks.wGain === 2 && V.PC.geneticQuirks.wLoss !== 2) { costs += Math.trunc(foodCost * 0.2); } + if (V.PC.geneMods.livestock === 1) { + costs += Math.trunc(foodCost * 0.2); + if (V.PC.lactation > 0) { + costs += Math.trunc(foodCost * (1 + V.PC.lactationAdaptation / 400)); + } + if (isVirile(V.PC)) { + costs += Math.trunc(foodCost * (1.1 + Math.trunc(V.PC.balls / 100))); + } + } if (V.PC.drugs === 'appetite suppressors') { costs -= foodCost; } @@ -1361,6 +1370,24 @@ globalThis.getSlaveCostArray = function(s) { value: Math.trunc(foodCost * s.lactation * (1 + (s.boobs / 10000))) }); } + if (s.geneMods.livestock === 1) { + retval.push({ + text: "Increased portion sizes for gene therapy induced appetite increase", + value: Math.trunc(foodCost * 0.2) + }); + if (s.lactation > 0) { + retval.push({ + text: "Extra feeding costs to support gene therapy enhanced milk production", + value: Math.trunc(foodCost * (1 + s.lactationAdaptation / 400)) + }); + } + if (isVirile(s)) { + retval.push({ + text: "Extra feeding costs to support gene therapy enhanced sperm production", + value: Math.trunc(foodCost * (1.1 + Math.trunc(s.balls / 100))) + }); + } + } if (s.preg > s.pregData.normalBirth / 8) { if (s.assignment === Job.DAIRY && V.dairyFeedersSetting > 0) { // Extra feeding costs to support pregnancy are covered by dairy feeders. diff --git a/src/js/personalAttentionFunctions.js b/src/js/personalAttentionFunctions.js index 765d5a9517612034a1d3a3c9b93eeb6d8f25ee4d..3eef3ea99d75f7206b88f8cb615287bd2b7253de 100644 --- a/src/js/personalAttentionFunctions.js +++ b/src/js/personalAttentionFunctions.js @@ -1,7 +1,7 @@ App.PersonalAttention.reset = function() { if (V.PC.health.condition < -20 || V.PC.health.illness > 1 || onBedRest(V.PC, true)) { V.personalAttention = {task: PersonalAttention.RELAX}; - } else if (isPlayerHorny(V.PC)) { + } else if (isHorny(V.PC)) { V.personalAttention = {task: PersonalAttention.SEX}; } else if (isPCCareerInCategory("escort")) { V.personalAttention = {task: PersonalAttention.WHORING}; diff --git a/src/js/pregJS.js b/src/js/pregJS.js index 730beb09091dc9ad85e0d4a44fb01beec6a0719b..1cdbb6d39d06412f751fd9d385b1cdd5e63dadd9 100644 --- a/src/js/pregJS.js +++ b/src/js/pregJS.js @@ -67,6 +67,8 @@ globalThis.setPregType = function(actor) { let ovum = jsRandom(actor.pregData.normalOvaMin, actor.pregData.normalOvaMax); // for default human profile it's always 1. let fertilityStack = 0; // adds an increasing bonus roll for stacked fertility drugs + let wombCapacity = Math.floor(actor.pregAdaptation / 15); // Used for a gene mod + let minFertStack = 0; /* Suggestion for better animal pregnancy support - usage of another variable then ovum for fertility drugs bonus, and then adding actor.pregData.drugsEffect multiplier to it before adding to ovum. Example: @@ -332,17 +334,24 @@ globalThis.setPregType = function(actor) { ovum += jsEither([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3]); fertilityStack++; } + if (actor.geneMods.livestock === 1) { + ovum += Math.max(0, ovum - wombCapacity); + } + if (actor.geneMods.progenitor === 1) { + minFertStack = fertilityStack; + fertilityStack += wombCapacity; + } if (V.seeHyperPreg === 1) { if (actor.drugs === "super fertility drugs") { - ovum += jsRandom(0, fertilityStack * 2); + ovum += jsRandom(minFertStack, fertilityStack * 2); } else { - ovum += jsRandom(0, fertilityStack); + ovum += jsRandom(minFertStack, fertilityStack); } if (actor.ovaImplant === "sympathy") { ovum *= 2; } } else { - ovum += jsRandom(0, fertilityStack); + ovum += jsRandom(minFertStack, fertilityStack); if (actor.ovaImplant === "sympathy") { ovum *= 2; if (ovum > 12) { @@ -406,6 +415,22 @@ globalThis.setPregType = function(actor) { globalThis.knockMeUp = function(target, chance, hole, fatherID) { let r = ``; if (V.seePreg !== 0) { + if (target.geneMods.progenitor === 1) { + chance += 20; + } + let father = findFather(fatherID); + if (father !== undefined) { + if (father.geneMods.aggressiveSperm === 1) { + chance += 75; + // While I would like to give a chance of self-impreg here, the risk of recursion seems high. + } + if (father.geneticQuirks.potent === 1) { + chance *= 1.5; + } + if (V.seeIncest === 0 && areRelated(target, father)) { + chance = -100; + } + } // eslint-disable-next-line no-nested-ternary if (jsRandom(0, 99) < (chance + (V.reproductionFormula * ((target.pregSource <= 0) ? ((target.ID === -1) ? 0 : 10) : 20)))) { if (target.mpreg === hole || hole === 2) { @@ -459,6 +484,9 @@ globalThis.getNurseryReserved = function( /* slaves */ ) { */ globalThis.findFather = function(fatherID) { let father = getSlave(fatherID); + if (fatherID === -1) { + father = V.PC; + } if (father === undefined) { if (V.incubator.capacity > 0) { father = V.incubator.tanks.find(s => s.ID === fatherID); @@ -491,7 +519,7 @@ globalThis.getBaseBoobs = function(slave) { globalThis.TerminatePregnancy = function(slave) { if (slave.bellyPreg > 1500) { // late term - highly fertile slaves spring back quicker - if (slave.geneticQuirks.fertility + slave.geneticQuirks.hyperFertility >= 4) { + if ((slave.geneticQuirks.fertility + slave.geneticQuirks.hyperFertility >= 4) || slave.geneMods.progenitor === 1) { slave.pregWeek = -2; } else if (slave.geneticQuirks.hyperFertility > 1) { slave.pregWeek = -3; diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js index 2f524397f361b88c59b05fe1b9e38b5216af13d1..00fb514fe546c4c25c495f1d057f7a770ed1018e 100644 --- a/src/js/statsChecker/statsChecker.js +++ b/src/js/statsChecker/statsChecker.js @@ -478,6 +478,14 @@ globalThis.isPure = function(slave) { return ((slave.boobsImplant === 0) && (slave.buttImplant === 0) && (slave.waist >= -95) && (slave.lipsImplant === 0) && (slave.faceImplant < 30) && (slave.bellyImplant === -1) && (Math.abs(slave.shouldersImplant) < 2) && (Math.abs(slave.hipsImplant) < 2)); }; +/** + * @param {App.Entity.SlaveState} slave + * @returns {boolean} + */ +globalThis.isVirile = function(slave) { + return (slave.balls > 0 && slave.pubertyXY === 1 && slave.vasectomy === 0 && slave.ballType !== "sterile"); +}; + /** * @param {App.Entity.SlaveState} slave * @returns {boolean} @@ -1167,3 +1175,23 @@ globalThis.milkFlavor = function(slave) { globalThis.canBeDeflowered = function(slave) { return (slave.vagina === 0 && canDoVaginal(slave)) || (slave.anus === 0 && canDoAnal(slave)); }; + +/** + * A consolidated function for checking if an actor is currently aroused. + * @param {App.Entity.HumanState} actor + * @returns {boolean} + */ +globalThis.isHorny = function(actor) { + return ((actor.prostate > 0 && actor.preg > 0 && actor.preg > actor.pregData.normalBirth * .75) || + (actor.preg > 0 && actor.preg > actor.pregData.normalBirth * .66 && actor.pregMood === 2) || + (actor.geneticQuirks.uterineHypersensitivity === 2 && + (actor.bellyPreg >= 10000) || + (actor.belly > (actor.pregAdaptation * 1000)) || + (actor.wombImplant === "restraint" && actor.belly >= 400000) + ) || + // (actor.need > 0) || + (actor.energy > 95) || + (actor.aphrodisiacs > 0) || + (actor.inflationType === "aphrodisiac") || + (actor.drugs === "priapism agents")); +}; diff --git a/src/js/storyJS.js b/src/js/storyJS.js index b65b3c4054000403a8cc7248d2807eff9697294f..b1872c2a74bf56642f6a8f93f57bcfde7ce4ea86 100644 --- a/src/js/storyJS.js +++ b/src/js/storyJS.js @@ -197,25 +197,36 @@ globalThis.milkAmount = function(slave) { * @returns {number} */ globalThis.cumAmount = function(slave) { - let cum = 0; - if (slave.drugs === "testicle enhancement") { - cum = ((slave.balls * 3.5) + 1); - } else if (slave.drugs === "hyper testicle enhancement") { - cum = ((slave.balls * 5) + 1); - } else { - cum = ((slave.balls * 2.5) + 1); - } - if (slave.ballType === "sterile") { - cum *= 0.8; - } - if (slave.diet === "cum production") { - cum *= 1.2; + let cum = 1; + if (slave.vasectomy !== 1) { + if (isVirile(slave)) { + if (slave.drugs === "testicle enhancement") { + cum += (slave.balls * 3.5); + } else if (slave.drugs === "hyper testicle enhancement") { + cum += (slave.balls * 5); + } else { + cum += (slave.balls * 2.5); + } + if (slave.scrotum === 0) { + cum *= 0.8; + } + if (slave.geneMods.livestock === 1) { + cum *= 1.5; + } + if (slave.diet === "cum production") { + cum *= 1.2; + } + } + if (slave.ballType === "sterile") { + cum *= 0.8; + } else if (slave.geneMods.aggressiveSperm === 1 && isVirile(slave)) { + cum *= 0.5; + } } + const calcs = (slave.hormoneBalance / 50); cum *= (1 - (calcs * 0.1)); - if (slave.scrotum === 0) { - cum *= 0.8; - } + if (slave.prostate === 0) { cum *= 0.2; // being generous here } else if (slave.prostate === 2) { @@ -223,6 +234,7 @@ globalThis.cumAmount = function(slave) { } else if (slave.prostate === 3) { cum *= 1.5; } + if (slave.devotion > 50) { cum += (cum * (slave.devotion / 100)); } else if (slave.devotion < -50) { @@ -260,6 +272,9 @@ globalThis.girlCumAmount = function(slave) { fluid *= (1 + (slave.health.condition / 50)); } } + if (slave.geneMods.livestock === 1) { + fluid *= 1.2; + } fluid = Math.trunc(fluid); if (fluid < 1) { fluid = 1; diff --git a/src/js/utilsPC.js b/src/js/utilsPC.js index f61f71f50e4241552e890705a421a66bafd223a4..abde58fc22dd39c962009274eb064924f1162061 100644 --- a/src/js/utilsPC.js +++ b/src/js/utilsPC.js @@ -641,10 +641,12 @@ globalThis.onBedRest = function(actor, workingFromBed = false) { return true; } else if (actor.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20) && !workingFromBed) { return true; - } else if (actor.bellyPreg >= actor.pregAdaptation * 2200 && !workingFromBed) { + } else if (actor.bellyPreg >= actor.pregAdaptation * 2200 && actor.geneMods.progenitor !== 1 && !workingFromBed) { return true; } else if (isInduced(actor)) { return true; + } else if (actor.geneMods.rapidCellGrowth !== 1 && actor.bellyPreg >= 100000 && actor.belly > (actor.pregAdaptation * 3200) && (actor.bellyPreg >= 500000 || actor.wombImplant !== "restraint")) { + return true; } return false; }; @@ -940,26 +942,6 @@ globalThis.canEatFood = function(actor) { return true; }; -/** - * A consolidated function for checking if the player is currently aroused. - * @param {App.Entity.PlayerState} actor - * @returns {boolean} - */ -globalThis.isPlayerHorny = function(actor) { - return ((actor.prostate > 0 && actor.preg > 0 && actor.preg > actor.pregData.normalBirth * .75) || - (actor.preg > 0 && actor.preg > actor.pregData.normalBirth * .66 && actor.pregMood === 2) || - (actor.geneticQuirks.uterineHypersensitivity === 2 && - (actor.bellyPreg >= 10000) || - (actor.belly > (actor.pregAdaptation * 1000)) || - (actor.wombImplant === "restraint" && actor.belly >= 400000) - ) || - // (actor.need > 0) || - (actor.energy > 95) || - (actor.aphrodisiacs > 0) || - (actor.inflationType === "aphrodisiac") || - (actor.drugs === "priapism agents")); -}; - /** * Param takes "classic" PC careers, and then function checks data to see if PC has that classic career or a 4.0 equivalent. * @param {"wealth"|"escort"|"servant"|"gang"|"BlackHat"|"capitalist"|"mercenary"|"engineer"|"medicine"|"slaver"|"celebrity"|"arcology owner"} category diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js index 85b74dbdada667da94236c228522674f8cd7174f..336c3ec997e80ef7ed4e14719942eb47fe7d8c63 100644 --- a/src/js/utilsSlave.js +++ b/src/js/utilsSlave.js @@ -2812,6 +2812,13 @@ globalThis.ageSlaveWeeks = function(slave, weeks = 1) { } } } + if (slave.geneMods.progenitor === 1 && canGetPregnant(slave)) { // Progenitor mod causes ovarian burnout if not put to use. + if (slave.geneticQuirks.superfetation === 2 && slave.womb.length > 0) { + slave.ovaryAge += 0.1; + } else { + slave.ovaryAge += 0.4; + } + } }; /** advances the age of a slave by one year, incurring all aging side effects diff --git a/src/js/wombJS.js b/src/js/wombJS.js index b772615478567254e030b2897aaf3f72dd1e2c9f..00b724f1be45b9a491221b746190508743bfe8eb 100644 --- a/src/js/wombJS.js +++ b/src/js/wombJS.js @@ -588,7 +588,7 @@ globalThis.WombSort = function(actor) { */ globalThis.fetalSplit = function(actor, chance) { for (const s of actor.womb) { - if (jsRandom(1, chance) >= chance) { + if (jsRandom(1, chance) >= chance || (actor.geneticQuirks.twinning === 2 && (actor.womb.length < Math.floor(actor.pregAdaptation / 32) || actor.womb.length === 1) && (s.twinID === "" || s.twinID === undefined))) { // if this fetus is not already an identical, generate a new twin ID before cloning it if (s.twinID === "" || s.twinID === undefined) { s.twinID = generateNewID(); diff --git a/src/npc/descriptions/boobs/boobs.js b/src/npc/descriptions/boobs/boobs.js index c2dd8a6c13300db4c6b0533ada96bd2c114c7821..2490c7498ff93c27966cbb239092af4678810732 100644 --- a/src/npc/descriptions/boobs/boobs.js +++ b/src/npc/descriptions/boobs/boobs.js @@ -1813,7 +1813,9 @@ App.Desc.nipples = function(slave, descType) { } } if (slave.lactationAdaptation > 10) { - if (slave.lactationAdaptation > 50) { + if (slave.lactationAdaptation > 150) { + r += ` ${He}'s produced such a vast amount of milk that ${his} body is now dedicated to copious production.`; + } else if (slave.lactationAdaptation > 50) { r += ` ${He}'s given so much milk that ${his} body is now well-adapted to copious production.`; } else { r += ` ${His} body has become used to milk production.`; diff --git a/src/npc/descriptions/crotch/dick.js b/src/npc/descriptions/crotch/dick.js index c48a3447559675004f4c987672d4a0f5ec2ebcc5..eeb08a21eb8d007d7d73f75d1f4c8173eaf6eee5 100644 --- a/src/npc/descriptions/crotch/dick.js +++ b/src/npc/descriptions/crotch/dick.js @@ -755,10 +755,14 @@ App.Desc.dick = function(slave, descType = DescType.NORMAL) { } } - if (slave.balls > 0 && slave.vasectomy === 1) { - r.push(`${He} shoots blanks thanks to ${his} vasectomy.`); - } else if (slave.balls > 0 && slave.ballType === "sterile") { - r.push(`${He} no longer produces sperm, so ${his} ejaculate lacks potency.`); + if (!isVirile(slave)) { + if (slave.vasectomy === 1) { + r.push(`${He} shoots blanks thanks to ${his} vasectomy.`); + } else if (slave.ballType === "sterile") { + r.push(`${He} no longer produces sperm, so ${his} ejaculate lacks potency.`); + } else if (slave.pubertyXY !== 1) { + r.push(`While ${he} does ejaculate, ${his} testicles aren't mature enough to add sperm to it.`); + } } if (slave.physicalAge <= 3) { @@ -858,6 +862,36 @@ App.Desc.dick = function(slave, descType = DescType.NORMAL) { if (slave.prostate > 2) { r.push(`${His} ejaculate has a distinct clearness to it from the sheer amount of prostate fluid produced by ${his} overstimulated prostate.`); } + if (isVirile(slave)) { + if (slave.geneMods.livestock === 1) { + r.push(`${His} loads are ${slave.prostate < 2 ? "incredibly thick" : "noticeably thicker"} thanks to ${his} genetic modifications.`); + if (slave.geneMods.aggressiveSperm === 1) { + r.push(`It also takes an effort to shoot it all out, which seems to make it more pleasurable than a typical cumshot. ${He} is required to be extra vigilant in cleaning up after ${himself} lest`); + if (!V.seePreg) { + r.push(`you get a nasty surprise should you sit down without looking.`); + } else if (canGetPregnant(V.PC) && canImpreg(V.PC, slave) && (V.PC.mpreg === 1 || V.PC.vagina >= 0)) { + r.push(`you take a seat somewhere ${he} came and suddenly find yourself in the family way.`); + } else { + r.push(`a wayward glob of ${his} cum somehow meets a fertile pussy and causes you a whole lot of problems.`); + } + if (V.seePreg && canGetPregnant(slave) && canImpreg(slave, slave) && (slave.mpreg === 1 || slave.vagina >= 0)) { + r.push(`Odds are some of ${his} sperm will eventually find its way to ${his} womb, so sooner or later ${he} will grow pregnant with ${his} own child.`); + } + } + } else if (slave.geneMods.aggressiveSperm === 1) { + r.push(`${His} gene therapy has reduced the density of ${his} loads, but the volume of it slowly working through ${his} urethra seems to make it more pleasurable than a typical cumshot. ${He} is required to be extra vigilant in cleaning up after ${himself} lest`); + if (!V.seePreg) { + r.push(`you get a nasty surprise should you sit down without looking.`); + } else if (canGetPregnant(V.PC) && canImpreg(V.PC, slave) && (V.PC.mpreg === 1 || V.PC.vagina >= 0)) { + r.push(`you take a seat somewhere ${he} came and suddenly find yourself in the family way.`); + } else { + r.push(`a wayward glob of ${his} cum somehow meets a fertile pussy and causes you a whole lot of problems.`); + } + if (V.seePreg && canGetPregnant(slave) && canImpreg(slave, slave) && (slave.mpreg === 1 || slave.vagina >= 0)) { + r.push(`Odds are some of ${his} sperm will eventually find its way to ${his} womb, so sooner or later ${he} will grow pregnant with ${his} own child.`); + } + } + } if (slave.physicalAge <= 3) { massiveTesticles1(); @@ -1300,10 +1334,44 @@ App.Desc.dick = function(slave, descType = DescType.NORMAL) { if (slave.prostate > 2) { r.push(`${His} ejaculate has a distinct clearness to it from the sheer amount of prostate fluid produced by ${his} overstimulated prostate.`); } - if (slave.balls > 0 && slave.vasectomy === 1) { - r.push(`${He} shoots blanks thanks to ${his} vasectomy.`); - } else if (slave.balls > 0 && slave.ballType === "sterile") { - r.push(`${He} no longer produces sperm, so ${his} cum lacks potency.`); + if (isVirile(slave)) { + if (slave.geneMods.livestock === 1) { + r.push(`${His} loads are ${slave.prostate < 2 ? "incredibly thick" : "noticeably thicker"} thanks to ${his} genetic modifications.`); + if (slave.geneMods.aggressiveSperm === 1) { + r.push(`It also takes an effort to shoot it all out, which seems to make it more pleasurable than a typical cumshot. ${He} is required to be extra vigilant in cleaning up after ${himself} lest`); + if (!V.seePreg) { + r.push(`you get a nasty surprise should you sit down without looking.`); + } else if (canGetPregnant(V.PC) && canImpreg(V.PC, slave) && (V.PC.mpreg === 1 || V.PC.vagina >= 0)) { + r.push(`you take a seat somewhere ${he} came and suddenly find yourself in the family way.`); + } else { + r.push(`a wayward glob of ${his} cum somehow meets a fertile pussy and causes you a whole lot of problems.`); + } + if (V.seePreg && canGetPregnant(slave) && canImpreg(slave, slave) && (slave.mpreg === 1 || slave.vagina >= 0)) { + r.push(`Odds are some of ${his} sperm will eventually find its way to ${his} womb, so sooner or later ${he} will grow pregnant with ${his} own child.`); + } + } + } else if (slave.geneMods.aggressiveSperm === 1) { + r.push(`${His} gene therapy has reduced the density of ${his} loads, but the volume of it slowly working through ${his} urethra seems to make it more pleasurable than a typical cumshot. ${He} is required to be extra vigilant in cleaning up after ${himself} lest`); + if (!V.seePreg) { + r.push(`you get a nasty surprise should you sit down without looking.`); + } else if (canGetPregnant(V.PC) && canImpreg(V.PC, slave) && (V.PC.mpreg === 1 || V.PC.vagina >= 0)) { + r.push(`you take a seat somewhere ${he} came and suddenly find yourself in the family way.`); + } else { + r.push(`a wayward glob of ${his} cum somehow meets a fertile pussy and causes you a whole lot of problems.`); + } + if (V.seePreg && canGetPregnant(slave) && canFemImpreg(slave, slave) && (slave.mpreg === 1 || slave.vagina >= 0)) { + r.push(`Odds are some of ${his} sperm will eventually find its way to ${his} womb, so sooner or later ${he} will grow pregnant with ${his} own child.`); + } + } + } + if (!isVirile(slave)) { + if (slave.vasectomy === 1) { + r.push(`${He} shoots blanks thanks to ${his} vasectomy.`); + } else if (slave.ballType === "sterile") { + r.push(`${He} no longer produces sperm, so ${his} ejaculate lacks potency.`); + } else if (slave.pubertyXY !== 1) { + r.push(`While ${he} does ejaculate, ${his} testicles aren't mature enough to add sperm to it.`); + } } } } else if (slave.balls > 0) { @@ -1484,6 +1552,36 @@ App.Desc.dick = function(slave, descType = DescType.NORMAL) { if (slave.prostate > 2) { r.push(`${His} ejaculate has a distinct clearness to it from the sheer amount of prostate fluid produced by ${his} overstimulated prostate.`); } + if (isVirile(slave)) { + if (slave.geneMods.livestock === 1) { + r.push(`${His} loads are ${slave.prostate < 2 ? "incredibly thick" : "noticeably thicker"} thanks to ${his} genetic modifications.`); + if (slave.geneMods.aggressiveSperm === 1) { + r.push(`It also takes an effort to shoot it all out, which seems to make it more pleasurable than a typical cumshot. ${He} is required to be extra vigilant in cleaning up after ${himself} lest`); + if (!V.seePreg) { + r.push(`you get a nasty surprise should you sit down without looking.`); + } else if (canGetPregnant(V.PC) && canImpreg(V.PC, slave) && (V.PC.mpreg === 1 || V.PC.vagina >= 0)) { + r.push(`you take a seat somewhere ${he} came and suddenly find yourself in the family way.`); + } else { + r.push(`a wayward glob of ${his} cum somehow meets a fertile pussy and causes you a whole lot of problems.`); + } + if (V.seePreg && canGetPregnant(slave) && canImpreg(slave, slave) && (slave.mpreg === 1 || slave.vagina >= 0)) { + r.push(`Odds are some of ${his} sperm will eventually find its way to ${his} womb, so sooner or later ${he} will grow pregnant with ${his} own child.`); + } + } + } else if (slave.geneMods.aggressiveSperm === 1) { + r.push(`${His} gene therapy has reduced the density of ${his} loads, but the volume of it slowly working through ${his} urethra seems to make it more pleasurable than a typical cumshot. ${He} is required to be extra vigilant in cleaning up after ${himself} lest`); + if (!V.seePreg) { + r.push(`you get a nasty surprise should you sit down without looking.`); + } else if (canGetPregnant(V.PC) && canImpreg(V.PC, slave) && (V.PC.mpreg === 1 || V.PC.vagina >= 0)) { + r.push(`you take a seat somewhere ${he} came and suddenly find yourself in the family way.`); + } else { + r.push(`a wayward glob of ${his} cum somehow meets a fertile pussy and causes you a whole lot of problems.`); + } + if (V.seePreg && canGetPregnant(slave) && canFemImpreg(slave, slave) && (slave.mpreg === 1 || slave.vagina >= 0)) { + r.push(`Since some of ${his} sperm leaks down into ${his} pussy whenever ${he} cums, sooner or later ${he} will grow pregnant with ${his} own child.`); + } + } + } } else { if (slave.prostate > 2) { r.push(`The area above ${his} crotch has a slight swell to it from ${his} prostate implant.`); diff --git a/src/npc/descriptions/crotch/vagina.js b/src/npc/descriptions/crotch/vagina.js index 424337c06591bb1ec92913477eb3886bab4994b0..3d2bbe3a17896d726f5ca655651fe7526543140f 100644 --- a/src/npc/descriptions/crotch/vagina.js +++ b/src/npc/descriptions/crotch/vagina.js @@ -273,6 +273,15 @@ App.Desc.vagina = function(slave) { } } + if (slave.geneMods.progenitor === 1) { + r.push(`${He} has been genetically treated to enhance ${his} ability to bear children.`); + if (canGetPregnant(slave)) { + r.push(`${His} body is very eager for that to happen, and at the rate it is keeping itself ready, early menopause is inevitable unless it is given what it wants.`); + } else if (slave.preg > 0 && slave.pregKnown) { + r.push(`Now that ${his} body has life growing within it, it is unlikely to let it go until it is fully ready.`); + } + } + if (slave.dick === 0 && slave.balls === 0 && slave.vagina < 0 && V.arcologies[0].FSRestart > 60) { r.push(`Society looks fondly on ${his} complete inability to reproduce.`); } diff --git a/src/npc/descriptions/descriptionWidgets.js b/src/npc/descriptions/descriptionWidgets.js index 047dcd6391a4f1a9fd08d81dcafab26ba57425f8..e940088c029498ea34c2bd1479fba797ced4537e 100644 --- a/src/npc/descriptions/descriptionWidgets.js +++ b/src/npc/descriptions/descriptionWidgets.js @@ -468,25 +468,22 @@ App.Desc.ageAndHealth = function(slave) { } age = slave.actualAge + 1; r += ` ${He} `; - if(slave.actualAge === V.idealAge || (slave.actualAge === V.idealAge - 1 && slave.birthWeek >= 52 && V.seeAge)) { - if(slave.birthWeek >= 52 && V.seeAge) { + if (slave.actualAge === V.idealAge || (slave.actualAge === V.idealAge - 1 && slave.birthWeek >= 52 && V.seeAge)) { + if (slave.birthWeek >= 52 && V.seeAge) { r += `is going to turn ${age} this week`; if (V.showAgeDetail && V.seeAge !== 0 && slave.actualAge !== V.idealAge) { r += `, and people are already beginning to eye ${him}.`; } else { r += `.`; } - } - else if(!slave.birthWeek && V.seeAge) { + } else if (!slave.birthWeek && V.seeAge) { r += `just turned ${num(slave.actualAge)} this week, which many citizens find especially appealing.`; - } - else if (slave.birthWeek < 4 && V.seeAge) { + } else if (slave.birthWeek < 4 && V.seeAge) { r += `only turned ${num(slave.actualAge)} this month. `; } else { r += `is ${num(slave.actualAge)} years old${birthday}. `; } - } - else if (slave.birthWeek >= 52 && V.seeAge) { + } else if (slave.birthWeek >= 52 && V.seeAge) { r += `is going to turn ${age} this week,`; } else if (slave.actualAge < 3) { r += `is an infant, only `; @@ -748,9 +745,6 @@ App.Desc.ageAndHealth = function(slave) { if (slave.geneMods.immortality === 1) { r += `Due to extensive genetic modification, ${he} is essentially immortal and will not die of old age. `; } - if (slave.geneMods.flavoring === 1) { - r += `Due to genetic modification ${his} milk tastes like ${slave.milkFlavor}. `; - } } } else { r += ` The Fuckdoll gives no external indication of ${his} health or age, but upon query ${his} systems reports that ${he} is `; @@ -1523,6 +1517,11 @@ App.Desc.geneticQuirkAssessment = function(slave) { if (slave.geneticQuirks.uFace === 1 && V.geneticMappingUpgrade >= 2) { r.push(`${He} is a carrier of a combination of traits that can result in raw ugliness.`); } + if (slave.geneticQuirks.potent === 2) { + r.push(`${He} is naturally potent${isVirile(slave) ? " and excels at impregnation" : ""}.`); + } else if (slave.geneticQuirks.potent === 1 && V.geneticMappingUpgrade >= 2) { + r.push(`${He} is a carrier of a genetic condition resulting in increased potency.`); + } if (slave.geneticQuirks.fertility === 2 && slave.geneticQuirks.hyperFertility === 2) { r.push(`${He} has a unique genetic condition resulting in inhumanly high`); if (slave.ovaries === 1 || slave.mpreg === 1) { diff --git a/src/npc/descriptions/style/hair.js b/src/npc/descriptions/style/hair.js index d3fb85f93fe6e084d9bdfc6b09fb706825e8e2b5..64232d2d66b903ac3d7f47f6ba528a01a6fea675 100644 --- a/src/npc/descriptions/style/hair.js +++ b/src/npc/descriptions/style/hair.js @@ -157,6 +157,26 @@ App.Desc.hair = function(slave) { r.push(`${slave.hColor} hair${slave.hEffect === "none" ? `` : ` that has ${slave.hEffect} to it,`}`); r.push(App.Desc.hairClothing(slave)); break; + case "unique": // For custom hair and really indescribable hairstyles. + if (hairLength > 0.9) { + r.push(`floor-length,`); + } else if (hairLength > 0.8) { + r.push(`calf-length,`); + } else if (hairLength > 0.7) { + r.push(`knee-length,`); + } else if (hairLength >= 0.6) { + r.push(`thigh-length,`); + } else if (hairLength >= 0.4) { + r.push(`ass-length,`); + } else if (hairLength >= 0.2) { + r.push(`long,`); + } else if (hairLength >= 15) { + r.push(`shoulder-length,`); + } else { + r.push(`short,`); + } + r.push(`${slave.hColor} hair${slave.hEffect === "none" ? `` : ` that is stylized with ${slave.hEffect},`} is truly unique to ${him}.`); + break; default: r.push(`${slave.hColor} hair${slave.hEffect === "none" ? `` : `, that is stylized with ${slave.hEffect},`} is ${slave.hStyle} and`); if (hairLength > 0.9) { diff --git a/src/npc/descriptions/womb/pregnancy.js b/src/npc/descriptions/womb/pregnancy.js index 1beb67819a43c2f375eef412e04e1e6febaa65cd..0f66527bce7263da69dde812134ae5ddceeba496 100644 --- a/src/npc/descriptions/womb/pregnancy.js +++ b/src/npc/descriptions/womb/pregnancy.js @@ -599,7 +599,9 @@ App.Desc.pregnancy = function(slave, descType = DescType.NORMAL) { } } } - if (slave.bellyPreg > (slave.pregAdaptation * 1000) || (slave.preg > slave.pregData.normalBirth / 2 && slave.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + if (slave.geneMods.rapidCellGrowth !== 1 && slave.bellyPreg >= 100000 && slave.belly > (slave.pregAdaptation * 3200) && (slave.bellyPreg >= 500000 || slave.wombImplant !== "restraint")) { + r.push(`${He} is undergoing a <span class="red">very high risk pregnancy${V.seeExtreme === 1 && V.dangerousPregnancy === 1 ? " and may burst" : ""}.</span>`); + } else if ((slave.bellyPreg > (slave.pregAdaptation * 1000) || (slave.preg > slave.pregData.normalBirth / 2 && slave.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) && slave.geneMods.progenitor !== 1) { r.push(`${He} is undergoing a <span class="red">high risk pregnancy.</span>`); } diff --git a/src/npc/generate/generateGenetics.js b/src/npc/generate/generateGenetics.js index 420d519c8cfcf5c9001eeffe806a083e34a32412..23cfcc48ee84e04852ca241c906600af580bfbbe 100644 --- a/src/npc/generate/generateGenetics.js +++ b/src/npc/generate/generateGenetics.js @@ -726,7 +726,45 @@ globalThis.generateGenetics = (function() { // Normal male, carrier female: 50% of daughters carriers, 50% of sons carriers geneTotal 1 // Carrier male, normal female: 100% of daughters carriers, sons normal geneTotal 1 - // Sex-linked traits (fertility-affecting, well-hung) left handled by the old method; latter made mirror image to former. + // Sex-linked traits (fertility-affecting, potent, well-hung) left handled by the old method; latter made mirror image to former. + + // potency + if (mother.geneticQuirks.potent === 2) { + if (sex === "XY") { + quirks.potent = 2; + } else { + quirks.potent = 1; + } + } else if (mother.geneticQuirks.potent === 1) { + chance = jsRandom(0, 1000); + if (father !== 0) { + if (father.geneticQuirks.potent >= 1) { + if (sex === "XY") { + if (chance > 500) { + quirks.potent = 2; + } else if (chance > 50) { + quirks.potent = 1; + } + } else { + if (chance > 500) { + quirks.potent = 1; + } + } + } + } else { + if (sex === "XY") { + if (chance > 950) { + quirks.potent = 2; + } else if (chance > 200) { + quirks.potent = 1; + } + } else { + if (chance > 500) { + quirks.potent = 1; + } + } + } + } // fertility if (mother.geneticQuirks.fertility === 2) { @@ -937,6 +975,15 @@ globalThis.generateGenetics = (function() { } } + // twinning + if (mother.geneticQuirks.twinning === 2) { + if (sex === "XX") { + quirks.twinning = 2; + } else { + quirks.twinning = 1; + } + } + // perfect face quirks.pFace = genes(father !== 0 ? father.geneticQuirks.pFace : 0, mother.geneticQuirks.pFace); diff --git a/src/npc/generate/generateNewSlaveJS.js b/src/npc/generate/generateNewSlaveJS.js index 504680174ad2a9dd9b998455894630d9c8981aee..771360302c3b98d907ea80a006f9073c03eb3f18 100644 --- a/src/npc/generate/generateNewSlaveJS.js +++ b/src/npc/generate/generateNewSlaveJS.js @@ -1177,6 +1177,9 @@ globalThis.GenerateNewSlave = (function() { } else if (chance >= 9900) { slave.geneticQuirks.hyperFertility = 1; } + if (jsRandom(1, 10000) >= 9900) { + slave.geneticQuirks.potent = 1; + } chance = jsRandom(1, 100000); if (chance < 3) { slave.geneticQuirks.superfetation = 2; @@ -1293,6 +1296,12 @@ globalThis.GenerateNewSlave = (function() { } else if (chance >= 9500) { slave.geneticQuirks.wellHung = 1; } + chance = jsRandom(1, 10000); + if (chance >= 9750) { + slave.geneticQuirks.potent = 2; + } else if (chance >= 9000) { + slave.geneticQuirks.potent = 1; + } chance = jsRandom(1, 1000); if (chance >= 950) { slave.geneticQuirks.fertility = 1; diff --git a/src/npc/generate/heroCreator.js b/src/npc/generate/heroCreator.js index 2f821c29c9e139d788cf4354e69d1bfc48e6919a..8ebe65004b82ad359a02823b5714ce7a977c845b 100644 --- a/src/npc/generate/heroCreator.js +++ b/src/npc/generate/heroCreator.js @@ -88,19 +88,9 @@ App.Utils.getHeroSlave = function(heroSlave) { } generatePronouns(heroSlave); if (heroSlave.geneMods === undefined) { - heroSlave.geneMods = {NCS: 0, rapidCellGrowth: 0, immortality: 0, bioEngineeredMilkFlavoring: 0}; - } - if (heroSlave.geneMods.NCS === undefined) { - heroSlave.geneMods.NCS = 0; - } - if (heroSlave.geneMods.rapidCellGrowth === undefined) { - heroSlave.geneMods.rapidCellGrowth = 0; - } - if (heroSlave.geneMods.immortality === undefined) { - heroSlave.geneMods.immortality = 0; - } - if (heroSlave.geneMods.flavoring === undefined) { - heroSlave.geneMods.flavoring = 0; + heroSlave.geneMods = {NCS: 0, rapidCellGrowth: 0, immortality: 0, flavoring: 0, aggressiveSperm: 0, livestock: 0, progenitor: 0}; + } else { + heroSlave.geneMods = Object.assign({NCS: 0, rapidCellGrowth: 0, immortality: 0, flavoring: 0, aggressiveSperm: 0, livestock: 0, progenitor: 0}, heroSlave.geneMods); } // WombInit(heroSlave); diff --git a/src/npc/interaction/fFeelings.js b/src/npc/interaction/fFeelings.js index da675d4fb2e0e762541b71ed9a992b8f1aadffee..b8a2590c988ad9f2466b06fd1fb2dd7ba1e9513c 100644 --- a/src/npc/interaction/fFeelings.js +++ b/src/npc/interaction/fFeelings.js @@ -1380,6 +1380,12 @@ App.Interact.fFeelings = function(slave) { } break; } + if (slave.geneMods.livestock === 1) { + text.push(`Ah! You heard my stomach rumble just now, didn't you? I've been so hungry lately, I'm not sure why.`); + if (canGetPregnant(slave)) { + text.push(`Am I pregnant?`); + } + } return text.join(' '); } diff --git a/src/player/desc/pLongBelly.js b/src/player/desc/pLongBelly.js index aac178a8266578f5d3fcbc2ceeaccb8b6ab5e10c..32c1b91fcc9060e84740291de59836fae51f9540 100644 --- a/src/player/desc/pLongBelly.js +++ b/src/player/desc/pLongBelly.js @@ -1608,12 +1608,14 @@ App.Desc.Player.belly = function(PC = V.PC) { if (onBedRest(PC)) { if (isInduced(PC)) { r.push(`You've taken drugs to induce labor and are already feeling the effects. The birth is coming up fast!`); - } else if ((PC.bellyPreg >= PC.pregAdaptation * 2200) || (PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + } else if (((PC.bellyPreg >= PC.pregAdaptation * 2200) || (PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) && PC.geneMods.progenitor !== 1) { r.push(`You are undergoing a <span class="red">very high risk pregnancy,</span> so to avoid giving birth prematurely, you have been placed on medical bed rest.`); } else if (PC.preg > PC.pregData.normalBirth / 1.05) { r.push(`You're far enough along at this point that it's in your best interest to stay in the nest and wait things out instead of risking going to labor at an inopportune time.`); } - if (PC.bellyPreg > PC.pregAdaptation * 1000 && PC.bellyPreg < PC.pregAdaptation * 2200) { + if (PC.geneMods.rapidCellGrowth !== 1 && PC.bellyPreg >= 100000 && PC.belly > (PC.pregAdaptation * 3200) && (PC.bellyPreg >= 500000 || PC.wombImplant !== "restraint")) { + r.push(`You are undergoing a <span class="red">very high risk pregnancy,</span> so to decrease the likelyhood of ${V.seeExtreme === 1 && V.dangerousPregnancy === 1 ? "abdominal rupture" : "your water breaking early"}, you have been placed on medical bed rest.`); + } else if (PC.bellyPreg > PC.pregAdaptation * 1000 && PC.bellyPreg < PC.pregAdaptation * 2200 && slave.geneMods.progenitor !== 1) { r.push(`You are undergoing a <span class="red">high risk pregnancy,</span> so taking things easy is probably a good idea.`); } } diff --git a/src/player/desc/pLongBoobs.js b/src/player/desc/pLongBoobs.js index 74281dcbd63d26e779169a2c732502a4158f23aa..753223aa33d0ec620cde130d6fd7ff61af121fb4 100644 --- a/src/player/desc/pLongBoobs.js +++ b/src/player/desc/pLongBoobs.js @@ -183,7 +183,7 @@ App.Desc.Player.boobs = function(PC = V.PC) { function nipples() { const r = []; - if (isPlayerHorny(PC)) { + if (isHorny(PC)) { switch (PC.nipples) { case "tiny": r.push(`You have stiff little nubs ${areolae()}.`); @@ -337,7 +337,9 @@ App.Desc.Player.boobs = function(PC = V.PC) { } if (PC.lactationAdaptation > 10) { r.push(`As if on demand, your milk starts to dribble down your tits.`); - if (PC.lactationAdaptation > 50) { + if (PC.lactationAdaptation > 150) { + r.push(`Your body is so dedicated to producing milk that these breaks are a luxury.`); + } else if (PC.lactationAdaptation > 50) { r.push(`Your body is so well-adapted to milk production that this is a regular affair now.`); } else { r.push(`Your body has become accustomed to milk production.`); @@ -354,7 +356,9 @@ App.Desc.Player.boobs = function(PC = V.PC) { r.push(`Your nipples cap a pair of painfully swollen bumps; milk constantly trickles from them unless you regularly milk yourself.`); } if (PC.lactationAdaptation > 10) { - if (PC.lactationAdaptation > 50) { + if (PC.lactationAdaptation > 150) { + r.push(`Your body is so dedicated to producing milk that this break only lasts minutes. You have to stay attached to a milking machine to truly relieve the stress.`); + } else if (PC.lactationAdaptation > 50) { r.push(`Your body is so well-adapted to milk production that this only results in fleeting relief.`); } else { r.push(`Your body has become accustomed to milk production that this is become annoyingly frequent.`); diff --git a/src/player/desc/pLongButt.js b/src/player/desc/pLongButt.js index 70caba5619dd62e104ed0ef5400ed81eb45c668e..1b885dcc24f42682de41222a0b3b2319d8c197c0 100644 --- a/src/player/desc/pLongButt.js +++ b/src/player/desc/pLongButt.js @@ -373,6 +373,14 @@ App.Desc.Player.butt = function(PC = V.PC) { r.push(`pregnancies.`); } } + if (PC.geneMods.progenitor === 1) { + r.push(`You've undergone gene therapy to better carry children.`); + if (canGetPregnant(PC)) { + r.push(`Your body is just wasting eggs at this point; menopause will be upon you before you realize it unless you get yourself pregnant.`); + } else if (PC.preg > 0 && PC.pregKnown && V.dangerousPregnancy === 1) { + r.push(`According to the data, it shouldn't be possible for you to prematurely give birth.`); + } + } if (PC.ovaImplant !== 0) { if (PC.wombImplant === "restraint") { r.push(`You ovaries are modified as well;`); diff --git a/src/player/desc/pLongCrotch.js b/src/player/desc/pLongCrotch.js index 68928031e4a529c5dbfcfb71b324a1abeb10e66d..64e17f6304daa1023af925bd20e564fe2597bb75 100644 --- a/src/player/desc/pLongCrotch.js +++ b/src/player/desc/pLongCrotch.js @@ -3,8 +3,8 @@ App.Desc.Player.crotch = function(PC = V.PC) { const {girlP} = getPronouns(PC).appendSuffix('P'); const legs = hasBothLegs(PC) ? "legs" : "leg"; const hands = hasBothArms(PC) ? "hands" : "hand"; - const isAroused = isPlayerHorny(PC); - const isVirile = (PC.balls > 0 && PC.pubertyXY === 1 && PC.vasectomy === 0 && PC.ballType !== "sterile"); + const isAroused = isHorny(PC); + const virile = isVirile(PC); const cumTotal = (cumAmount(PC) / 70) || 0; const foreskinRatio = (PC.foreskin - PC.dick); const bigBelly = (PC.belly >= 100000 || PC.weight > 130); @@ -556,7 +556,23 @@ App.Desc.Player.crotch = function(PC = V.PC) { ballThoughts(), scrotumDesc() ); - if (!isVirile) { + if (virile) { + if (PC.geneMods.livestock === 1) { + r.push(`Your loads are thick and enormous thanks to your gene therapy.`); + if (PC.geneMods.aggressiveSperm === 1) { + r.push(`It's also really difficult to shoot it all out.`); + if (canGetPregnant(PC) && canImpreg(PC, PC) && (PC.mpreg === 1 || PC.vagina >= 0) && V.seePreg) { + r.push(`You have to be mindful of where your loads land too; one bad angle is all it would take for your belly to start rounding out with your own child.`); + } + } + } else if (PC.geneMods.aggressiveSperm === 1) { + r.push(`Your gene therapy has reduced the density of your loads, but the volume of it slowly working through your urethra feels magical.`); + if (canGetPregnant(PC) && canImpreg(PC, PC) && (PC.mpreg === 1 || PC.vagina >= 0) && V.seePreg) { + r.push(`You have to be mindful of where your loads go, however, as one bad shot is all it would take for your belly to start rounding out with your own child.`); + } + } + } + if (!virile) { if (PC.vasectomy === 1) { r.push(`You're had a vasectomy`); if (PC.pubertyXY !== 1) { @@ -769,7 +785,23 @@ App.Desc.Player.crotch = function(PC = V.PC) { } else { r.push(`internal testicles.</span>`); } - if (!isVirile) { + if (virile && PC.geneMods.livestock === 1) { + if (PC.geneMods.livestock === 1) { + r.push(`Your loads are thick and enormous thanks to your gene therapy.`); + if (PC.geneMods.aggressiveSperm === 1) { + r.push(`It's also really difficult to shoot it all out.`); + if (canGetPregnant(PC) && canImpreg(PC, PC) && (PC.mpreg === 1 || PC.vagina >= 0) && V.seePreg) { + r.push(`You have to be mindful of where your loads land too; one bad angle is all it would take for your belly to start rounding out with your own child.`); + } + } + } else if (PC.geneMods.aggressiveSperm === 1) { + r.push(`Your gene therapy has reduced the density of your loads, but the volume of it slowly working through your urethra feels magical.`); + if (canGetPregnant(PC) && canImpreg(PC, PC) && (PC.mpreg === 1 || PC.vagina >= 0) && V.seePreg) { + r.push(`You have to be mindful of where your loads go, however, as one bad shot is all it would take for your belly to start rounding out with your own child.`); + } + } + } + if (!virile) { if (PC.vasectomy === 1) { r.push(`They're not connected to anything at the moment, but you can always get your vasectomy reversed if you wanted.`); } else if (PC.ballType === "sterile") { @@ -1186,7 +1218,7 @@ App.Desc.Player.crotch = function(PC = V.PC) { r.push(`This hole is normally almost invisible, so it's`); if (PC.prostate > 2 || cumTotal >= 1) { r.push(`absolutely shocking to new partners when you climax and fire a massive cumshot out of it.`); - } else if (PC.balls > 0 && isVirile) { + } else if (PC.balls > 0 && virile) { r.push(`quite surprising to new partners when you climax and shoot cum out of it.`); } else if (PC.prostate > 0) { r.push(`quite surprising to new partners when you climax and squirt from it.`); @@ -1196,15 +1228,15 @@ App.Desc.Player.crotch = function(PC = V.PC) { if (PC.prostate > 0 && PC.balls > 0) { r.push(`a functional prostate gland attached to your urethra and <span class="orange">a pair of ${ballSize} internal testicles</span> to go with it, you`); if (PC.prostate > 2 || cumTotal >= 1) { - r.push(`soak yourself and your surroundings with ${isVirile ? "semen and " : ""}sexual fluids every time you cum.`); + r.push(`soak yourself and your surroundings with ${virile ? "semen and " : ""}sexual fluids every time you cum.`); } else { - r.push(`squirt copious amounts of fluid ${isVirile ? "and semen " : ""}with each orgasm.`); + r.push(`squirt copious amounts of fluid ${virile ? "and semen " : ""}with each orgasm.`); } } else if (PC.balls > 0) { if (cumTotal >= 1) { - r.push(`<span class="orange">an overproductive pair of ${ballSize} internal testicles</span> hooked up to your urethra, you release a flood of ${isVirile ? "semen" : "ejaculate"} every time you cum.`); + r.push(`<span class="orange">an overproductive pair of ${ballSize} internal testicles</span> hooked up to your urethra, you release a flood of ${virile ? "semen" : "ejaculate"} every time you cum.`); } else { - r.push(`<span class="orange">a pair of ${ballSize} internal testicles</span> hooked up to your urethra, you squirt a little ${isVirile ? "semen" : "ejaculate"} with each orgasm.`); + r.push(`<span class="orange">a pair of ${ballSize} internal testicles</span> hooked up to your urethra, you squirt a little ${virile ? "semen" : "ejaculate"} with each orgasm.`); } } else if (PC.prostate > 0) { r.push(`a functional prostate gland attached to your urethra, you`); @@ -1219,7 +1251,7 @@ App.Desc.Player.crotch = function(PC = V.PC) { r.push(`Your prostate is under constant pressure from your advanced pregnancy, forcing frequent bouts of extreme arousal on you.`); } if (PC.balls > 0) { - if (!isVirile) { + if (!virile) { r.push(`This fluid isn't virile`); if (PC.vasectomy === 1) { r.push(`since you've had a vasectomy.`); @@ -1231,6 +1263,17 @@ App.Desc.Player.crotch = function(PC = V.PC) { } else if (V.geneticMappingUpgrade >= 1 && PC.genes === "XY" && V.seeDicksAffectsPregnancy === 0) { r.push(`Analysis of the sperm mixed into this fluid reveals that you have a ${PC.spermY}% chance of fathering a son.`); } + if (virile && PC.geneMods.aggressiveSperm === 1 && canGetPregnant(PC) && canFemImpreg(PC, PC) && (PC.mpreg === 1 || PC.vagina >= 0)) { + r.push(`Your gene therapy has greatly increased the survivability of your sperm and since you don't project it far from your body on ejaculation,`); + if (PC.mpreg === 1) { + r.push(`it's quite likely that some of it will find its way to your anus.`); + } else { + r.push(`some of it always trickles into your pussy.`); + } + if (V.seePreg) { + r.push(`You need to use birth control or your constant self-seeding will see you pregnant.`); + } + } } } @@ -1300,6 +1343,14 @@ App.Desc.Player.crotch = function(PC = V.PC) { if (PC.vagina === -1) { r.push(`You lack a vagina, which means you can only bear children surgically.`); } + if (PC.geneMods.progenitor === 1) { + r.push(`You've undergone gene therapy to better carry children.`); + if (canGetPregnant(PC)) { + r.push(`Your body is just wasting eggs at this point; menopause will be upon you before you realize it unless you put your womb to work.`); + } else if (PC.preg > 0 && PC.pregKnown && V.dangerousPregnancy === 1) { + r.push(`According to the data, it shouldn't be possible for you to prematurely give birth.`); + } + } if (PC.ovaImplant !== 0) { if (PC.wombImplant === "restraint") { r.push(`You ovaries are modified as well;`); diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js index c5450224ffc7117e8c738089f3becb535d32b1df..54e5149ca8e6ce07d6523bcab73c489d7dfb9afe 100644 --- a/src/player/js/PlayerState.js +++ b/src/player/js/PlayerState.js @@ -1665,6 +1665,8 @@ App.Entity.PlayerState = class PlayerState { * * **macromastia + gigantomastia** - Breasts never stop growing. Increased growth rate, no shrink rate. */ gigantomastia: 0, + /** sperm is much more likely to knock someone up */ + potent: 0, /** is prone to having twins, shorter pregnancy recovery rate */ fertility: 0, /** is prone to having multiples, even shorter pregnancy recovery rate @@ -1712,6 +1714,9 @@ App.Entity.PlayerState = class PlayerState { mGain: 0, /** constantly loses muscle mass, easier to gain muscle. mGain + mLoss - muscle gain/loss amplified, passively lose muscle unless building */ mLoss: 0, + /** ova will split if room is available + * only affects fetuses */ + twinning: 0, /** slave can only ever birth girls */ girlsOnly: 0 }; @@ -2008,11 +2013,23 @@ App.Entity.PlayerState = class PlayerState { /** Are you immortal? * @type {FC.Bool} * 0: no; 1: yes */ - immortality: 0, + immortality: 0, /** Is your milk flavored? * @type {FC.Bool} * 0: no; 1: yes */ - flavoring: 0 + flavoring: 0, + /** Has the slave's sperm been optimized? + * @type {FC.Bool} + * 0: no; 1: yes */ + aggressiveSperm: 0, + /** Has the slave been optimized for production? + * @type {FC.Bool} + * 0: no; 1: yes */ + livestock: 0, + /** Has the slave been optimized for child bearing? + * @type {FC.Bool} + * 0: no; 1: yes */ + progenitor: 0 }; /** flavor of their milk*/ this.milkFlavor = "none"; diff --git a/src/player/personalAttentionSelect.js b/src/player/personalAttentionSelect.js index b62082d7ab4e3be32986c1c804b54e3389b077a1..57e5b4694cc33116311fd1dfad6db85a50da3fe1 100644 --- a/src/player/personalAttentionSelect.js +++ b/src/player/personalAttentionSelect.js @@ -579,7 +579,7 @@ App.UI.Player.personalAttention = function() { // HORNY /* - if (isPlayerHorny(V.PC)) { + if (isHorny(V.PC)) { links.push(attentionLink(i, `Fuck ${him} senseless`, "ravish")); } */ diff --git a/src/pregmod/blackMarket.js b/src/pregmod/blackMarket.js index 1257bc5b2509897e3164b76ad88f1249795284d5..9260b8426b2e2785d9fcdcf0ed24eac627a0758f 100644 --- a/src/pregmod/blackMarket.js +++ b/src/pregmod/blackMarket.js @@ -559,6 +559,81 @@ App.UI.blackMarket = function() { } } break; + case "optimizedSpermFormula": + if (V.geneticMappingUpgrade === 0) { + r.push(`You lack the facilities required for such a treatment to be effective on specific individuals.`); + } else if (V.dispensaryUpgrade === 0) { + r.push(`You lack the facilities required to produce complex gene-altering treatments.`); + } else { + if (V.optimizedSpermFormula === 0) { + const spermCash = 40000; + if (V.cash >= spermCash) { + App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( + "Purchase formulas for injections to greatly improve sperm efficiency", + () => { + cashX(-spermCash, "capEx"); + V.optimizedSpermFormula = 1; + V.merchantIllegalWares.delete("optimizedSpermFormula"); + App.UI.reload(); + }, + [], + "", + `Costs ${(cashFormat(spermCash))}` + )); + } else { + r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(spermCash))}</span> for sperm optimizing injections.`); + } + App.Events.addNode(node, r, "div"); + r = []; + r.push(`"Managed to get these from a pissed off employee just before their employer got sued out of existence. Makes sperm super resilient and vigorous, and from what I've heard, able to survive outside the body for an extended period of time. Apparently`); + if (!V.seePreg) { + r.push(`seeing puddles of spunk crawling around on the floor seemingly 'hunting' fertile women was enough to freak people out.`); + } else { + r.push(`being hunted down and unknowingly inseminated by a wandering puddle of spunk your ${V.seeIncest ? "kid" : "roommate"} left in your bed is enough to really piss people off. Ooh! And there was that herm that got pregnant after blowing a load on her own chest and not cleaning it off fast enough! And that's not even mentioning how well they can swim either — what a headline that debacle was!`); + } + r.push(`Funny when things work too well, right?"`); + } else { + r.push(`You already possess formulas that make sperm way too aggressive.`); + V.merchantIllegalWares.delete("optimizedSpermFormula"); + } + } + break; + case "optimizedBreedingFormula": + if (!V.seePreg) { + r.push(`You have no interest in research to support pregnancy.`); + V.merchantIllegalWares.delete("optimizedBreedingFormula"); + } else if (V.geneticMappingUpgrade === 0) { + r.push(`You lack the facilities required for such a treatment to be effective on specific individuals.`); + } else if (V.dispensaryUpgrade === 0) { + r.push(`You lack the facilities required to produce complex gene-altering treatments.`); + } else { + if (V.optimizedBreedingFormula === 0) { + const breederCash = 100000; + if (V.cash >= breederCash) { + App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( + "Purchase formulas for injections designed to enhance the ability to bear children", + () => { + cashX(-breederCash, "capEx"); + V.optimizedBreedingFormula = 1; + V.merchantIllegalWares.delete("optimizedBreedingFormula"); + App.UI.reload(); + }, + [], + "", + `Costs ${(cashFormat(breederCash))}` + )); + } else { + r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(breederCash))}</span> for optimized breeder injections.`); + } + App.Events.addNode(node, r, "div"); + r = []; + r.push(`"These injections optimize a woman's body for child production. They work amazingly too! The only downside is they take their job a tad too seriously. See, under no circumstances can a girl miscarry with these tweaks, but that's not the problem no — it's how badly they reacted to any sort of fertility agent that might so happen to be in her. By design, she'll be able to handle larger and larger pregnancies as the therapy pushes her to be more productive, but, you see, anything that makes her more fertile causes this to happen far faster than her body can keep up, and with the whole 'refuses to miscarry' thing, well..." He makes a gesture like a popping balloon. "You end up with quite the mess."`); + } else { + r.push(`You already possess formulas for enhancing a body's capability of bearing children.`); + V.merchantIllegalWares.delete("optimizedBreedingFormula"); + } + } + break; case "sympatheticOvaries": if (V.sympatheticOvaries === 0) { if (V.seePreg === 1) { @@ -720,7 +795,7 @@ App.UI.blackMarket = function() { App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( "Refresh illicit wares list", () => { - V.thisWeeksIllegalWares = ["childhoodFertilityInducedNCS", "UterineRestraintMesh", "PGHack", "BlackmarketPregAdaptation", "RapidCellGrowthFormula", "sympatheticOvaries", "asexualReproduction"]; + V.thisWeeksIllegalWares = ["childhoodFertilityInducedNCS", "UterineRestraintMesh", "PGHack", "BlackmarketPregAdaptation", "RapidCellGrowthFormula", "optimizedSpermFormula", "optimizedBreedingFormula", "sympatheticOvaries", "asexualReproduction"]; App.UI.reload(); } ));