diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d664d0fe013133052e9dd474e2fd15cf354c89c..efd0868efc41cb032126567bb23cdfe62544df30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * added a series of consumer reduction drugs * slave's maximum possible erection can now be modified by slave's height and health (toggleable in options) +* added support for AI art * experimental interactions option * fSuckDick added to experimental interactions +* more player-slave dick relations +* bulk ovum transplant ## 0.10.7.1-4.0.0-alpha.26 - 2023-06-17 diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index 9de30128088be4775aeb011fa9dcf31684074001..35a419d76d0291b8ba79dde3b7ca282fe96c25c4 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -1273,6 +1273,7 @@ App.Data.resetOnNGPlus = { raGrowthExpr: 0, sexOverhaul: 0, interactions: 0, + clitoralPenetration : 0, }, NaNArray: [], diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index 23205edd76c3b0a5b87f073c89aca3611a13a4f3..e217df250d315f91839f8cd6613a38c5272d09e0 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -1511,6 +1511,7 @@ App.Update.globalVariables = function(node) { V.experimental.reportMissingClothing = V.experimental.reportMissingClothing || 0; V.experimental.sexOverhaul = V.experimental.sexOverhaul || 0; V.experimental.interactions = V.experimental.interactions || 0; + V.experimental.clitoralPenetration = V.experimental.clitoralPenetration || 0; // Budget V.showAllEntries.costsBudget = V.showAllEntries.costsBudget || 0; diff --git a/src/endWeek/player/prLongTermEffects.js b/src/endWeek/player/prLongTermEffects.js index 2f8989be4c45a0a10a616d77e9bd0e1f06875995..e136fc9e0b8338fb9846de8a85dcd8d47acc823e 100644 --- a/src/endWeek/player/prLongTermEffects.js +++ b/src/endWeek/player/prLongTermEffects.js @@ -815,6 +815,9 @@ App.EndWeek.Player.longTermEffects = function(PC = V.PC) { } else if (PC.health.health > 80) { miscarriageChance -= (PC.health.health / 10); } + if (PC.physicalAge > 60) { + miscarriageChance += (PC.physicalAge - 60); + } if (PC.weight < -50) { miscarriageChance -= PC.weight; } diff --git a/src/endWeek/player/prLongTermPhysicalEffects.js b/src/endWeek/player/prLongTermPhysicalEffects.js index b0d75a38001d2ab61ed4973ec56f2ffd7ed5806a..cbc4163bd6bdd3d884900ff9a5e36c87c486dd27 100644 --- a/src/endWeek/player/prLongTermPhysicalEffects.js +++ b/src/endWeek/player/prLongTermPhysicalEffects.js @@ -321,6 +321,7 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) { } function sexualSatisfaction() { + // work player masturbation into this. With frigid playing a huge role. const sexPartners = V.slaves.filter(s => App.Utils.sexAllowed(V.PC, s) && isSlaveAvailable(s)).shuffle(); const wives = sexPartners.filter(s => s.relationship === -3); // Fuck wives every week diff --git a/src/endWeek/reports/personalAttention.js b/src/endWeek/reports/personalAttention.js index fc58c31b24799737aca43e300a0b96a4ab3a08af..49e38fb9a95f994e99284523895ed8405264da88 100644 --- a/src/endWeek/reports/personalAttention.js +++ b/src/endWeek/reports/personalAttention.js @@ -110,7 +110,9 @@ App.PersonalAttention.slaveReport = function(slave) { let milkTotal = 0; let oldSkill; const hindranceMod = isHinderedDegree(V.PC); - const nymphoMod = isPlayerLusting() ? .75 : 1; + const pcFrigid = isPlayerFrigid(); + const pcHorny = isPlayerLusting(); + const nymphoMod = pcHorny ? .75 : 1; if (pa.objective === "health") { r.push(App.UI.DOM.makeElement("span", `You care for`, ["bold"])); } else if (pa.objective === "spar") { @@ -137,16 +139,80 @@ App.PersonalAttention.slaveReport = function(slave) { } slave.training = Math.clamp(slave.training, 0, 100); slave.training += 80 - (slave.intelligence + slave.intelligenceImplant) / 5 + ((slave.devotion + slave.trust) / 10); + if (hindranceMod <= .5) { + slave.training -= 10; + } if ((V.PC.skill.slaving >= 100) && V.personalAttention.slaves.length === 1) { slave.training += 20; // negate bonus when splitting focus among slaves } switch (pa.objective) { - case "build devotion": - // split devotion based off horny. Some slaves are not going to take it well. - slave.devotion += 6; - if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.SUBMISSIVE) { + case "build devotion": { + let enjoyable = true; + if (pcHorny && isHorny(slave)) { + r.push(`It's quite simple, really. You and ${slave.slaveName} are both really horny, so you fuck, and keep fucking, and then fuck some more. Once you're both so exhausted that you can barely move, ${he}`); + r.push(App.UI.DOM.makeElement("span", `leans in and gives you a kiss.`, ["devotion", "inc"])); + SimpleSexAct.Player(slave, 15); + V.PC.need = 0; + } else if (V.PC.visualAge <= 12 && V.PC.visualAge < V.minimumSlaveAge && !acceptsUnderage(slave)) { + if (pcHorny) { + r.push(`You fuck ${slave.slaveName}, of course, but you try to do it slowly and lovingly, despite your lustful urges. ${He}'s accustomed to the slave life, so the experience should be novel for ${him}, but ${he} is so uncomfortable about your age that ${he} is unable to enjoy it much. Despite your efforts, ${he} is more`); + r.push(App.UI.DOM.makeElement("span", `cowed by your advances`, ["devotion", "inc"])); + r.push(`than touched by your affection.`); + enjoyable = false; + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 4); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 4); + } + SimpleSexAct.Player(slave, 12); + } else { + r.push(`Since ${slave.slaveName} is uncomfortable with your age, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by inviting ${him} to join you in some childish escapades.`); + if (slave.actualAge <= 12) { + r.push(`The young ${girl} eagerly obliges and you have an enjoyable little playdate.`); + } else { + r.push(`${He} is hesitant at first, but loosens up once the game is underway.`); + if (random(1, 2) === 1) { + r.push(`${He} held nothing back and crushed you, but after a little pouting, you have to admit that it was still fun.`); + } else { + r.push(`You feel like ${he} let you win, but it was fun either way.`); + } + } + } + } else if (pcHorny) { + r.push(`You fuck ${slave.slaveName}, of course, but you try to do it slowly and lovingly, despite your lustful urges. ${He}'s accustomed to the slave life, so the experience should be novel for ${him}, but you end up taking things too far and ruining the mood. Despite your efforts, ${he} is more`); + r.push(App.UI.DOM.makeElement("span", `cowed by your advances`, ["devotion", "inc"])); + r.push(`than touched by your affection.`); + enjoyable = false; + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 4); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 4); + } + SimpleSexAct.Player(slave, 12); + } else if (pcFrigid) { + r.push(`Since you have little interest in sex, you spend some quality time with ${slave.slaveName} instead. ${He}'s accustomed to the slave life, so just sitting around and enjoying a movie with you is a novel experience for ${him} and ${he} is`); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); + r.push(`${He} isn't used to being invited to activities that don't end in sex and ${he} finds it nice to be able to let ${his} guard down for once.`); + } else if (slave.anus === 3 && slave.vagina === 3 && slave.geneMods.rapidCellGrowth !== 1 && random(1, 100) > 75) { // consider upping frequency? + r.push(`${slave.slaveName} is a stretched-out, well-traveled slut. Some like their holes loose, but most prefer cunts and butts that don't make sloppy noises when fucked. So, you spend some quality care time with ${him}, carefully massaging ${his} abused holes with oils and lotions. ${He} comes, of course, but ${his} pussy and asshole do benefit from the treatment. You allow ${him} to service you with ${his} mouth to avoid spoiling your work right away. Afterward, ${he}`); + if (hasAnyArms(slave)) { + r.push(App.UI.DOM.makeElement("span", `hugs you and gives you a kiss.`, ["devotion", "inc"])); + } else { + r.push(App.UI.DOM.makeElement("span", `gives you a kiss and tries to hug you,`, ["devotion", "inc"])); + r.push(`but without arms, all ${he} manages is a sort of nuzzle.`); + } + slave.vagina--; + slave.anus--; + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 5); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 5); + } + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.SUBMISSIVE) { r.push(`Since ${slave.slaveName} is a submissive, you`); - r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); r.push(`by indulging ${his} need to be dominated. Already smiling to ${himself}, ${he} changes into bondage gear that`); if (canSee(slave)) { r.push(`blinds ${him},`); @@ -170,80 +236,173 @@ App.PersonalAttention.slaveReport = function(slave) { } else { r.push(`uncomfortably.`); } - r.push(`Thus attired, ${he} is forced to serve you in whatever petty ways occur to you. ${He} holds your tablet for you on ${his} upthrust ass as you work, holds a thin beverage glass for you in ${his} upturned mouth when you eat, and lies still so you can use ${his} tits as a pillow whenever you recline. ${He} loves it.`); - } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "cumslut" && V.PC.dick !== 0) { - r.push(`Since ${slave.slaveName} has an unusual taste for oral sex and cum, you`); - r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"])); - r.push(`by indulging ${him}. You allow ${him} to spend ${his} free time following you around. ${He} is permitted to act as your private cum receptacle. If you use another slave, you usually pull out and give ${his} smiling face a facial. When you come inside another slave instead, ${slave.slaveName} is allowed to get your cum anyway, regardless of whether that requires the other slave to spit it into ${his} mouth or ${slave.slaveName} to suck it out of the other slave's vagina or rectum. Either way, ${he} rubs ${his} stomach happily after ${he}'s swallowed it down.`); - seX(slave, "oral", V.PC, "penetrative", 20); - } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "boobs") { - r.push(`Since ${slave.slaveName} has an unusual taste for having ${his} tits fondled, you`); - r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"])); - r.push(`by indulging ${him}. You keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or buttfucking another slave, you reach over and play with ${him}. ${He} sometimes masturbates while you massage ${his} breasts and`); - if (slave.nipples === "fuckable") { - r.push(`finger`); - } else { - r.push(`pinch`); - } - r.push(`${his} nipples, but often ${he} doesn't even need to.`); - seX(slave, "mammary", V.PC, "penetrative", 10); - } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "pregnancy") { - r.push(`Since ${slave.slaveName} has an unusual taste for big pregnant bellies, you`); - r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"])); - r.push(`by indulging ${him}. You`); - if (isItemAccessible.entry("a small empathy belly", "bellyAccessory") && slave.belly < 1500 && slave.weight < 130) { - r.push(`strap an enormous sympathy belly onto ${him} and`); - } else if (slave.belly < 1500) { - r.push(`strap a pillow around ${his} middle, give ${him} an oversized shirt and`); - } - r.push(`keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or buttfucking another slave, you reach over and rub ${his} dome of a belly for luck. Occasionally you pay more attention to ${him}, making sure to fondle ${his} rounded middle as you feel up ${his} motherly body. ${He} sometimes masturbates when you aren't groping ${him}, enjoying ${his} gravid figure, but often ${he} doesn't even need to.`); - } else if ( - slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "humiliation" && - ( - (canDoVaginal(slave) && slave.vagina > 0) || - (canDoAnal(slave) && slave.anus > 0) - ) - ) { - r.push(`Since ${slave.slaveName} has an unusual sexuality, you`); - r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"])); - r.push(`by indulging ${his} perversions. Since ${he}'s an absolute slut for humiliation, you let ${him} whore around inside the special camera room whenever possible. When you're going out and feel like putting on a show, you bring ${him} on a leash and fuck ${him} in public. ${He} comes harder than ever when you push ${his} naked body up against the wall of a crowded public arcology elevator and molest ${him}.`); - seX(slave, "oral", V.PC, "penetrative", 4); - r.push(VCheck.Both(slave, 4, 2)); - } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "humiliation") { - r.push(`Since ${slave.slaveName} has an unusual sexuality, you`); - r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"])); - r.push(`by indulging ${his} perversions. Since ${he}'s an absolute slut for humiliation, you let ${him} whore around inside the special camera room whenever possible. When you're going out and feel like putting on a show, you`); - if (hasBothLegs(slave)) { - r.push(`bring ${him} on a leash and have ${him} service you in public. ${He} comes harder than ever when you push ${him} down on ${his} knees in a crowded public arcology elevator and facefuck ${him} while ${he}`); - } else { - r.push(`carry ${him} out and have ${him} service you in public. ${He} comes harder than ever when you push ${his} face to your`); - if (V.PC.dick !== 0) { - r.push(`dick`); + r.push(`Thus attired, ${he} is forced to serve you in whatever petty ways occur to you. ${He} holds your tablet for you on ${his} upthrust ass as you work, holds a thin beverage glass for you in ${his} upturned mouth when you eat, and lies still so you can use ${his} ${slave.boobs >= 300 ? "tits" : "chest"} as a pillow whenever you recline. ${He} loves it.`); + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.DOM) { + r.push(`Since ${slave.slaveName} is a dom trapped in a submissive's world, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by giving ${him} a chance to indulge ${himself}. For a short time, you permit ${him} to have ${his} way with you`); + if (V.policies.sexualOpenness === 1 || slave.toyHole === "dick") { + r.push(`in any way ${he} pleases,`); + if (V.PC.vagina === 0 || V.PC.anus === 0) { + r.push(`with the exceptions that ${he} leave no lasting marks nor robs you of your virginity.`); } else { - r.push(`pussy`); + r.push(`so long as ${he} leaves no lasting marks.`); } - r.push(`in a crowded public arcology elevator and facefuck ${him} while ${he}`); + } else { + r.push(`so long as it is within reason and leaves no visible signs; you have a reputation to uphold, after all.`); } + r.push(`Already smiling, ${he}`); if (hasAnyArms(slave)) { - r.push(`masturbates fervently.`); + r.push(`pushes you down`); } else { - r.push(`tries ${his} hardest to masturbate.`); + r.push(`pins you under ${his} body`); } - seX(slave, "oral", V.PC, "penetrative", 8); - } else if ((slave.anus === 3) && (slave.vagina === 3) && slave.geneMods.rapidCellGrowth !== 1) { - r.push(`${slave.slaveName} is a stretched-out, well-traveled slut. Some like their holes loose, but most prefer cunts and butts that don't make sloppy noises when fucked. So, you spend some quality care time with ${him}, carefully massaging ${his} abused holes with oils and lotions. ${He} comes, of course, but ${his} pussy and asshole do benefit from the treatment. You allow ${him} to service you with ${his} mouth to avoid spoiling your work right away. Afterward, ${he}`); + r.push(`as ${he} decides what to do with you. You even stuggle a little, just to excite ${him} more as ${he}'s forced to truly dominate you if ${he} hopes to get anything from this.`); + SimpleSexAct.Player(slave, 5); + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.CUMSLUT && isVirile(V.PC)) { + r.push(`Since ${slave.slaveName} has an unusual ${canTaste(slave) ? "taste" : "desire"} for oral sex and cum, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You allow ${him} to spend ${his} free time following you around. ${He} is permitted to act as your private cum receptacle. If you use another slave, you usually`); + if (canPenetrate(V.PC)) { + r.push(`pull out`); + } else if (V.PC.clit >= 3) { + r.push(`position ${him} under your urethra`); + } else if (V.PC.dick === 0) { + r.push(`substitute ${him} in`); + } else { + r.push(`redirect`); + } + r.push(`and give ${his} smiling face a facial. When you come inside another slave instead, ${slave.slaveName} is allowed to get your cum anyway, regardless of whether that requires the other slave to spit it into ${his} mouth or ${slave.slaveName} to suck it out of the other slave's vagina or rectum. Either way, ${he}`); if (hasAnyArms(slave)) { - r.push(App.UI.DOM.makeElement("span", `hugs you and gives you a kiss.`, ["hotpink"])); + r.push(`rubs ${his} stomach`); } else { - r.push(App.UI.DOM.makeElement("span", `gives you a kiss and tries to hug you,`, ["hotpink"])); - r.push(`but without arms, all ${he} manages is a sort of nuzzle.`); + r.push(`licks ${his} lips`); } - slave.vagina--; - slave.anus--; - seX(slave, "oral", V.PC, "penetrative", 5); + r.push(`happily after ${he}'s swallowed it down.`); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 20); + } else { // nulls get counted as this for now + seX(slave, "oral", V.PC, "vaginal", 20); + } + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.BOOBS) { + if (slave.boobs >= 300) { + r.push(`Since ${slave.slaveName} has an unusual taste for having ${his} tits fondled, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or fucking another slave, you reach over and play with ${him}. ${He} sometimes masturbates while you massage ${his} breasts and`); + if (slave.nipples === "fuckable") { + r.push(`finger`); + } else { + r.push(`pinch`); + } + r.push(`${his} nipples, but often ${he} doesn't even need to.`); + seX(slave, "mammary", V.PC, "penetrative", 10); + } else if (V.PC.boobs >= 300) { + r.push(`Since ${slave.slaveName} has a taste for tits, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}.`); + if (hasAnyArms(slave)) { + r.push(`You bet ${him} ${he} can't keep ${his} ${hasbothArms(slave) ? "hands" : "hand"} on your breasts all day without ever removing ${hasbothArms(slave) ? "them" : "it"}, a challenge ${he} takes to with gusto. Whether you're conducting business, fucking another slave or just enjoying a meal, ${he}'s there playing with your chest, as if ${he} wins, ${he} gets the privilege of ${V.PC.lactation > 0 ? "drinking your milk" : "sucking on your nipples"}.`); + } else if (V.PC.belly >= 1500 || onBedRest(V.PC)) { + r.push(`Since your body limits what fun you can have with an armless slave, you opt to just lie on your side with your breasts exposed for ${him} to play with. ${He} sometimes masturbates while sucking on your nipples and rubbing ${his} face in your cleavage, but ${he} often doesn't even need to.`); + } else if (slave.height <= V.PC.height || !hasAnyLegs(slave)) { + r.push(`You situate ${him} on your lap with ${his} head between your breasts and dress yourself over top of ${him} before going about your day. You make sure to move in such a way that you're always rubbing your chest against ${him}. By the time you finish your business, ${he}'s practically squirming with arousal.`); + } + } else { + r.push(`Since ${slave.slaveName} has a taste for huge tits, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You`); + if (!onBedRest(V.PC)) { + r.push(`grab the largest bra you can find in the wardrobe, take as many sheets and pillows that you'd need to fill its cups, and set it up on ${him} before stuffing it all into an oversized shirt.`); + } else { + r.push(`request the largest bra in the wardrobe, all the spare sheets and pillows from the linen closet, and an oversized shirt to contain it all. When you have everything you need, you go to work setting it all up on ${him}.`); + } + r.push(`Once ${he} manages to get over having such an enormous rack hanging off ${himself}, you keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or fucking another slave, you reach over and give ${his} fake chest a squeeze. Occasionally you pay more attention to ${him}, making sure to get ${him} bouncing as you feel ${him} up. ${He} sometimes masturbates when you aren't groping ${him}, enjoying ${his} buxom figure, but often ${he} doesn't even need to.`); + } + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.BUTTSLUT) { + r.push(`Since ${slave.slaveName} has a penchant for anal play, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or fucking another slave, you reach over and play with ${him}. ${He} sometimes can't control ${himself} and masturbates while you grope ${his} buttocks and tease ${his} anus, but when ${he} manages to wait for permission, you reward ${him} with a satisfying buttfuck.`); + r.push(VCheck.Anal(slave, 10)); + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.PREGNANCY) { + r.push(`Since ${slave.slaveName} has an unusual taste for big pregnant bellies, you`); + if (slave.belly >= 1500) { + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or fucking another slave, you reach over and rub ${his} dome of a belly for luck. Occasionally you pay more attention to ${him}, making sure to fondle ${his} rounded middle as you feel up ${his} motherly body. ${He} sometimes masturbates when you aren't groping ${him}, enjoying ${his} gravid figure, but often ${he} doesn't even need to.`); + } else if (V.PC.bellyPreg >= 1500) { + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You have ${him} lavish attention on your ${V.PC.preg > V.PC.pregData.normalBirth * .75 ? "turgid" : "growing"} belly and service any pregnancy cravings that strike you.`); + // } else if (V.PC.belly < 1500) { + // 5.0.0, female PC dons belly to tease male slave + } else { + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You`); + if (isItemAccessible.entry("a small empathy belly", "bellyAccessory") && slave.weight < 130) { + r.push(`strap an enormous sympathy belly onto ${him} and`); + } else { + r.push(`strap a pillow around ${his} middle, give ${him} an oversized shirt and`); + } + r.push(`keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or fucking another slave, you reach over and rub ${his} dome of a belly for luck. Occasionally you pay more attention to ${him}, making sure to fondle ${his} rounded middle as you feel up ${his} motherly body. ${He} sometimes masturbates when you aren't groping ${him}, enjoying ${his} gravid figure, but often ${he} doesn't even need to.`); + } + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.HUMILATION && !onbedRest(V.PC)) { + if ((canDoVaginal(slave) && slave.vagina > 0) || (canDoAnal(slave) && slave.anus > 0)) { + r.push(`Since ${slave.slaveName} has an unusual sexuality, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${his} perversions. Since ${he}'s an absolute slut for humiliation, you let ${him} whore around inside the special camera room whenever possible. When you're going out and feel like putting on a show, you bring ${him} on a leash and fuck ${him} in public. ${He} comes harder than ever when you push ${his} naked body up against the wall of a crowded public arcology elevator and molest ${him}.`); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 4); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 4); + } + r.push(VCheck.Both(slave, 4, 2)); + } else { + r.push(`Since ${slave.slaveName} has an unusual sexuality, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${his} perversions. Since ${he}'s an absolute slut for humiliation, you let ${him} whore around inside the special camera room whenever possible. When you're going out and feel like putting on a show, you`); + if (hasBothLegs(slave)) { + r.push(`bring ${him} on a leash and have ${him} service you in public. ${He} comes harder than ever when you push ${him} down on ${his} knees in a crowded public arcology elevator and facefuck ${him} while ${he}`); + } else { + r.push(`carry ${him} out and have ${him} service you in public. ${He} comes harder than ever when you push ${his} face to your`); + if (V.PC.dick !== 0) { + r.push(`dick`); + } else if (V.PC.clit >= 3) { + r.push(`phallic clit`); + } else if (V.PC.vagina >= 0) { + r.push(`pussy`); + } else { + r.push(`crotch`); + } + r.push(`in a crowded public arcology elevator and facefuck ${him} while ${he}`); + } + if (hasAnyArms(slave)) { + r.push(`masturbates fervently.`); + } else { + r.push(`tries ${his} hardest to masturbate.`); + } + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 8); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 8); + } + } + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.SADIST) { + r.push(`Since ${slave.slaveName} has an unusual taste for causing anguish, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You allow ${him} to pick out how disobediant slaves will be punished this week, within reason of course; ${he} isn't allowed to cause any lasting harm. ${He} sometimes masturbates while`); + if (canSee(slave)) { + r.push(`watching your other slaves suffer for ${his} amusement,`); + } else if (canHear(slave)) { + r.push(`enjoying the sounds of your others slaves suffering for ${his} amusement,`); + } else { + r.push(`picturing your other slaves undergoing ${his} torments,`); + } + r.push(`but often ${he} doesn't even need to.`); + } else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === Fetish.MASOCHIST) { + r.push(`Since ${slave.slaveName} has an unusual taste for pain, you`); + r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["devotion", "inc"])); + r.push(`by indulging ${him}. You keep ${him} near you as a sort of living punching bag. Whenever you feel stressed, annoyed, or just bored, you grab your crop and give ${him} a few good slaps. ${He} sometimes masturbates while you beat ${him}, but often ${he} doesn't even need to.`); } else if (slave.vagina === 0) { r.push(`${slave.slaveName}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is`); - r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virginity. You gently stimulate ${his}`); if (slave.dick) { r.push(`dick`); @@ -252,33 +411,81 @@ App.PersonalAttention.slaveReport = function(slave) { } else { r.push(`nipples`); } - if (slave.rules.release.master) { - r.push(`while ${he} sucks you off, bringing ${him} to a moaning climax as you cum in ${his} mouth.`); - seX(slave, "oral", V.PC, "penetrative", 5); + if (slave.rules.release.master && (V.PC.dick > 0 || V.PC.vagina >= 0)) { + if (V.PC.dick > 0 || V.PC.clit >= 3) { + r.push(`while ${he} sucks you off,`); + } else { + r.push(`while ${he} eats you out,`); + } + r.push(`bringing ${him} to a moaning climax as you`); + if (V.PC.clit >= 3) { + r.push(`buck against ${his} face.`); + } else { + r.push(`cum in ${his} mouth.`); + } + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 5); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 5); + } } else { r.push(`as you play with ${his} body, subconsciously causing ${him} to become more accustomed to your presence.`); } } else if (slave.anus === 0 && slave.vagina < 0) { - // TODO: not sure if the PC has to have either a dick or a vagina... can PCs be nulls? + r.push(`You haven't decided to take ${slave.slaveName}'s anus yet, so you have ${him}`); if (slave.rules.release.master) { - r.push(`You haven't decided to take ${slave.slaveName}'s anus yet, so you have ${him} ${V.PC.dick > 0 ? `suck you off` : `eat you out`} and allow ${him} to play with ${himself} while ${he} does. You stroke ${his} hair, play with ${his} tits, and generally pamper ${him} while ${he} orally services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`); - r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"])); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + r.push(`suck you off`); + } else if (V.PC.vagina >= 0) { + r.push(`eat you out`); + } else { + r.push(`massage your crotch`); + } + r.push(`and allow ${him} to play with ${himself} while ${he} does. You stroke ${his} hair,`); + if (slave.boobs >= 300) { + r.push(`play with ${his} tits,`); + } else { + r.push(`rub ${his} chest,`); + } + r.push(`and generally pamper ${him} while ${he} orally services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virgin hole.`); - seX(slave, "oral", V.PC, "penetrative", 5); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 5); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 5); + } } else { - r.push(`You haven't decided to take ${slave.slaveName}'s anus yet, so you have ${him} ${V.PC.dick > 0 ? `jerk you off` : `play with your pussy`} and allow ${him} to play with ${himself} while ${he} does. You stroke ${his} hair, play with ${his} tits, and generally pamper ${him} while ${he} services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`); - r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"])); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + r.push(`jerk you off`); + } else if (V.PC.vagina >= 0) { + r.push(`play with your pussy`); + } else { + r.push(`explore your crotch`); + } + r.push(`and allow ${him} to play with ${himself} while ${he} does. You stroke ${his} hair,`); + if (slave.boobs >= 300) { + r.push(`play with ${his} tits,`); + } else { + r.push(`rub ${his} chest,`); + } + r.push(`and generally pamper ${him} while ${he} services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virgin hole.`); } } else if (slave.anus === 0 && slave.vagina > 0 && canDoVaginal(slave)) { r.push(`You fuck ${slave.slaveName}, of course, but you do it slowly and lovingly, and keep well clear of ${his} still-virgin asshole in the process. ${He}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is affectingly`); - r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); r.push(`${He} isn't used to being kissed, teased and massaged before ${he} takes cock. Slaves are usually used without regard to their orgasm, so ${he}'s also surprised and gratified when you make meticulous efforts to delay your own orgasm so it can coincide with ${his} own. ${He}'s a puddle on the sheets under your hands.`); - seX(slave, "oral", V.PC, "penetrative", 4); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 4); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 4); + } r.push(VCheck.Vaginal(slave, 4)); } else if (slave.anus === 0) { r.push(`${slave.slaveName}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is`); - r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} anal virginity. You gently stimulate ${his}`); if (slave.dick) { r.push(`dick`); @@ -287,13 +494,36 @@ App.PersonalAttention.slaveReport = function(slave) { } else { r.push(`nipples`); } - r.push(`while ${he} sucks you off, bringing ${him} to a moaning climax as you cum in ${his} mouth.`); - seX(slave, "oral", V.PC, "penetrative", 5); + r.push(`while ${he}`); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + r.push(`sucks you off,`); + } else if (V.PC.vagina >= 0) { + r.push(`eats you out,`); + } else { + r.push(`rubs your crotch,`); + } + r.push(`bringing ${him} to a moaning climax as you`); + if (V.PC.clit >= 3) { + r.push(`buck against ${his} face.`); + } else if (V.PC.dick > 0 || V.PC.vagina >= 0) { + r.push(`cum in ${his} mouth.`); + } else { + r.push(`grind against ${his} face.`); + } + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 5); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 5); + } } else { r.push(`You fuck ${slave.slaveName}, of course, but you do it slowly and lovingly. ${He}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is affectingly`); - r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["devotion", "inc"])); r.push(`${He} isn't used to being kissed, teased and massaged before ${he} takes cock. Slaves are usually used without regard to their orgasm, so ${he}'s also surprised and gratified when you make meticulous efforts to delay your own orgasm so it can coincide with ${his} own. ${He}'s a puddle on the sheets under your hands.`); - seX(slave, "oral", V.PC, "penetrative", 4); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 4); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 4); + } if (slave.vagina === 0) { r.push(VCheck.Vaginal(slave, 4)); } else { @@ -304,23 +534,36 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`Your`); r.push(App.UI.DOM.makeElement("span", `slave training experience`, ["skill", "player"])); r.push(`allows you to`); - r.push(App.UI.DOM.makeElement("span", `bend ${him} to your will`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `bend ${him} to your will`, ["devotion", "inc"])); r.push(`more quickly without provoking resistance.`); slave.devotion += 1; } - if (slave.trust > 10) { + if (enjoyable) { + slave.devotion += 6; r.push(`Spending time with you`); - r.push(App.UI.DOM.makeElement("span", `builds ${his} trust in ${his} ${getWrittenTitle(slave)}.`, ["mediumaquamarine"])); - slave.trust += 4; + if (slave.trust > 10) { + r.push(App.UI.DOM.makeElement("span", `builds ${his} trust in ${his} ${getWrittenTitle(slave)}.`, ["trust", "inc"])); + slave.trust += 4; + } else { + r.push(App.UI.DOM.makeElement("span", `reduces ${his} fear towards you.`, ["trust", "inc"])); + slave.trust += 6; + } } else { - r.push(`Spending time with you`); - r.push(App.UI.DOM.makeElement("span", `reduces ${his} fear towards you.`, ["mediumaquamarine"])); - slave.trust += 6; + slave.devotion += 3; + r.push(`Spending such an unpleasant interlude with you`); + if (slave.trust > 10) { + r.push(App.UI.DOM.makeElement("span", `builds doubt in ${his} ${getWrittenTitle(slave)}.`, ["trust", "dec"])); + slave.trust -= 4; + } else { + r.push(App.UI.DOM.makeElement("span", `reminds ${him} of why ${he} fears you.`, ["trust", "dec"])); + slave.trust -= 8; + } } currentSlaveValue = 0.2; slave.training = 0; break; - case "health": + } + case "health": { if (slave.relationship === -3 && slave.fetish === Fetish.MINDBROKEN) { r.push(`Since ${slave.slaveName} is your ${wife} and not all there, you keep ${him} under a watchful eye to make sure no harm comes to the broken ${girl}. ${He} almost seems in better spirits under your care, not that it will matter in an hour or two.`); if (slave.kindness) { @@ -329,26 +572,44 @@ App.PersonalAttention.slaveReport = function(slave) { slave.kindness = 1; } } - if (slave.health.condition < 100) { - r.push(`Your close and expert attention improves ${his} health in a way drug treatment or mere medical intervention cannot.`); - r.push(App.UI.DOM.makeElement("span", `${His} health has improved.`, ["health", "inc"])); - improveCondition(slave, 10); - } - if (slave.health.tired > 10) { - r.push(`You watch over ${him} as ${he} sleeps, assuring`); - r.push(App.UI.DOM.makeElement("span", `a proper night's rest.`, ["health", "inc"])); - slave.health.tired = Math.clamp(slave.health.tired - 10, 0, 1000); + if (pcHorny) { + if (slave.health.condition < 100) { + r.push(`Your close attention improves ${his} health in a way drug treatment or mere medical intervention cannot, though you would probably do a better job if you spent less time molesting ${him} during your "examinations".`); + r.push(App.UI.DOM.makeElement("span", `${His} health has improved.`, ["health", "inc"])); + improveCondition(slave, 5); + } + if (slave.health.tired > 10) { + r.push(`You watch ${him} as ${he} sleeps, making sure ${he} gets`); + r.push(App.UI.DOM.makeElement("span", `some undisturbed rest,`, ["health", "inc"])); + r.push(`even as you masturbate to the sight of ${his} naked body.`); + slave.health.tired = Math.clamp(slave.health.tired - 5, 0, 1000); + } + } else { + if (slave.health.condition < 100) { + const skillBonus = Math.trunc(V.PC.skill.medicine / 20); + r.push(`Your close${V.PC.skill.medicine >= 40 ? " and expert" : ""} attention improves ${his} health in a way drug treatment or mere medical intervention cannot.`); + r.push(App.UI.DOM.makeElement("span", `${His} health has improved.`, ["health", "inc"])); + improveCondition(slave, 10 + skillBonus); + } + if (slave.health.tired > 10) { + r.push(`You watch over ${him} as ${he} sleeps, assuring`); + r.push(App.UI.DOM.makeElement("span", `a proper night's rest.`, ["health", "inc"])); + slave.health.tired = Math.clamp(slave.health.tired - 10, 0, 1000); + } } if ((slave.anus >= 3 || slave.vagina >= 3) && slave.geneMods.rapidCellGrowth !== 1) { r.push(`${slave.slaveName} is a veteran sex slave and has seen hard use. Tightening up a slave is difficult, but with close supervision and attention it can be done. You and your other slaves carefully apply injections, creams, and massage, and ${his} other work is carefully managed to reduce wear and tear.`); + if (pcHorny) { + r.push(`It takes all your willpower to not immediately ruin it with a hard fucking, but you manage to power through it. For now, at least.`); + } if (slave.anus >= 3 && (random(1, 100)) > 50) { - r.push(App.UI.DOM.makeElement("span", `${His} anus has recovered and is now merely loose.`, ["orange"])); + r.push(App.UI.DOM.makeElement("span", `${His} anus has recovered and is now merely loose.`, ["change", "positive"])); slave.anus--; } else if (slave.anus >= 3) { r.push(`${His} distended anus does not improve this week.`); } if (slave.vagina >= 3 && random(1, 100) > 50) { - r.push(App.UI.DOM.makeElement("span", `${His} pussy has tightened.`, ["orange"])); + r.push(App.UI.DOM.makeElement("span", `${His} pussy has tightened.`, ["change", "positive"])); slave.vagina--; } else if (slave.vagina >= 3) { r.push(`${His} loose pussy does not recover this week.`); @@ -356,7 +617,11 @@ App.PersonalAttention.slaveReport = function(slave) { } currentSlaveValue = 0.1; slave.training = 0; + if (V.PC.skill.medicine < 10) { + r.push(IncreasePCSkills('medicine', currentSlaveValue)); + } break; + } case "soften behavioral flaw": if (slave.behavioralFlaw === "none") { r.push(`${slave.slaveName} got over ${his} behavioral flaw without you;`); @@ -374,44 +639,138 @@ App.PersonalAttention.slaveReport = function(slave) { coloredText.push(`softening ${his} sexual flaw.`); pa.objective = "soften sexual flaw"; } - r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["yellow"])); + r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["noteworthy"])); } else { if (slave.behavioralFlaw === "arrogant") { - r.push(`${slave.slaveName} thinks ${he}'s better than everyone else. ${He} has some basis for a high opinion of ${himself}; otherwise you wouldn't be bothering with ${him}. You do your best to maintain ${his} belief that ${he} has something special to offer while training ${him} to offer it to you without objection.`); + r.push(`${slave.slaveName} thinks ${he}'s better than everyone else. ${He} has some basis for a high opinion of ${himself}; otherwise you wouldn't be`); + if (pcHorny) { + r.push(`masturbating to the sight of`); + } else { + r.push(`bothering with`); + } + r.push(`${him}.`); + if (pcHorny) { + r.push(`Your little shows mostly serve to reinforce ${his} arrogance instead of tempering it into something special.`); + slave.training *= 0.5; + } else { + r.push(`You do your best to maintain ${his} belief that ${he} has something special to offer while training ${him} to offer it to you without objection.`); + } } else if (slave.behavioralFlaw === "bitchy") { - r.push(`${slave.slaveName} always has a cutting remark ready. Some of them are actually pretty good, and you'd prefer to keep ${his} cutting wit intact. You strike a careful balance with ${him}, punishing the wrong remark at the wrong time, but rewarding appropriately biting comments.`); + r.push(`${slave.slaveName} always has a cutting remark ready. Some of them are actually pretty good, and you'd prefer to keep ${his} cutting wit intact. You strike a careful balance with ${him},`); + if (pcHorny) { + r.push(`forcing ${him} to service you for saying the wrong thing at the wrong time, but rewarding appropriately biting comments with sex. It mostly just makes ${him} bitch about your teaching methods.`); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 7); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 7); + } + SimpleSexAct.Player(slave, 5); + slave.training *= 0.25; + } else { + r.push(`punishing the wrong remark at the wrong time, but rewarding appropriately biting comments.`); + } } else if (slave.behavioralFlaw === "odd") { - r.push(`${slave.slaveName} is odd. ${He}'s usually annoying, but on occasion ${his} oddities can produce great comic relief. You strike a careful balance with ${him}, punishing ${him} when ${he} irritates you, but allowing and even rewarding harmless little idiosyncrasies.`); - } else if (slave.behavioralFlaw === "hates men") { - r.push(`${slave.slaveName} does not like men. ${He} desperately needs social contact, though, so you encourage ${him} to rely on women to address ${his} emotional needs. This is easy, since`); - if (V.PC.vagina !== -1) { - r.push(`you've got a pussy yourself.`); + r.push(`${slave.slaveName} is odd. ${He}'s usually annoying, but on occasion ${his} oddities can produce great comic relief. You strike a careful balance with ${him},`); + if (pcHorny) { + r.push(`forcing ${him} to service you for being irritating, but rewarding ${his} harmless little idiosyncrasies with sex. ${He} seems to be getting some mixed messages from your teaching strategy.`); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 7); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 7); + } + SimpleSexAct.Player(slave, 5); + slave.training *= 0.25; + } else { + r.push(`punishing ${him} when ${he} irritates you, but allowing and even rewarding harmless little idiosyncrasies.`); + } + } else if (slave.behavioralFlaw === "hates men") { // These two need all sorts of retooling in 5.0.0 + r.push(`${slave.slaveName} does not like`); + if (pcHorny) { + if (V.PC.dick > 0) { // 5.0.0 check + r.push(`men, so clearly the best way to overcome this is to teach ${him} to love the touch of one; it backfires spectacularly.`); + slave.training = 0; + } else { + r.push(`men, so clearly the best way to overcome this is the touch of a woman; it goes better than expected.`); + slave.training += 5; + SimpleSexAct.Player(slave, 5); + } } else { - r.push(`there are several readily available.`); + r.push(`men. ${He} desperately needs social contact, though, so you encourage ${him} to rely on women to address ${his} emotional${pcHorny ? " and sexual" : ""} needs. This is easy, since`); + if (V.PC.vagina !== -1) { // 5.0.0 check + r.push(`you've got a pussy yourself.`); + } else { + r.push(`there are several readily available.`); + } } } else if (slave.behavioralFlaw === "hates women") { - r.push(`${slave.slaveName} does not like girls. ${He} desperately needs social contact, though, so you encourage ${him} to rely on men to address ${his} emotional needs. This is easy, since`); - if (V.PC.dick === 0) { - r.push(`there are several readily available.`); + r.push(`${slave.slaveName} does not like`); + if (pcHorny) { // 5.0.0 check + if (V.PC.dick === 0) { // 5.0.0 check + r.push(`girls, so clearly the best way to overcome this is to teach ${him} to love the touch of one; it backfires spectacularly.`); + slave.training = 0; + } else { + r.push(`girls, so clearly the best way to overcome this is to give ${him} a thorough dicking; it works better than expected.`); + slave.training += 5; + seX(slave, "oral", V.PC, "penetrative", 7); + if (slave.vagina > 0) { + seX(slave, "vaginal", V.PC, "penetrative", 6); + } + if (slave.anus > 0) { + seX(slave, "anal", V.PC, "penetrative", 3); + } + } } else { - r.push(`you've got a cock yourself.`); + r.push(`girls. ${He} desperately needs social contact, though, so you encourage ${him} to rely on men to address ${his} emotional needs. This is easy, since`); + if (V.PC.dick === 0) { // 5.0.0 check + r.push(`there are several readily available.`); + } else { + r.push(`you've got a cock yourself.`); + } } } else if (slave.behavioralFlaw === "anorexic") { - r.push(`${slave.slaveName} suffers from anorexia. You work with ${him} patiently, applying the very best in modern therapy for this troubling condition. It's usually a product of poor self esteem, and you do your best to build ${hers} up without diminishing ${his} submission to you.`); + r.push(`${slave.slaveName} suffers from anorexia. You work with ${him}`); + if (pcHorny) { + r.push(`diligently, making use of your libido for this troubling condition. It's usually a product of poor self esteem, so showering ${him} in sexual praise should build ${hers} up without weakening ${his} bond to you. At the very least, ${he} is more willing to eat after being thoroughly tired out.`); + slave.training += 5; + SimpleSexAct.Player(slave, 15); + } else { + r.push(`patiently, applying the very best in modern therapy for this troubling condition. It's usually a product of poor self esteem, and you do your best to build ${hers} up without diminishing ${his} submission to you.`); + } } else if (slave.behavioralFlaw === "gluttonous") { r.push(`${slave.slaveName}'s diet is already closely controlled, but the impulse to overeat is strong in ${him} and like most gluttons ${he} manages to be quite cunning. You take a hard line with ${him}, and do your best to replace ${his} addiction to the endorphin release of eating with an addiction to the endorphin release of exercise.`); + if (pcHorny) { + r.push(`You work ${him} long and hard into the night, and while it is exhausting, this might not be the type of excercise ${he} needs to kick the habit.`); + slave.training *= 0.75; + SimpleSexAct.Player(slave, 20); + } } else if (slave.behavioralFlaw === "liberated") { r.push(`${slave.slaveName} can express a decent argument for why it's wrong to use ${him} as a sex slave. With a combination of rote training, discussion, and reinforcement, you do your best to turn this into a sincere belief in the moral rightness of slavery.`); + if (pcHorny) { + r.push(`Unfortunately, your lust-addled mind fails to leave much of a lasting impression on ${him}.`); + slave.training *= 0.25; + } } else if (slave.behavioralFlaw === "devout") { - r.push(`${slave.slaveName} remains devoted to an old world faith that serves ${him} as a reservoir of mental resilience. Like all such beliefs, ${hers} has certain sexual elements; you amuse yourself by forcing ${him} to break them, and rewarding ${him} generously when ${he} does.`); + r.push(`${slave.slaveName} remains devoted to an old world faith that serves ${him} as a reservoir of mental resilience. Like all such beliefs, ${hers} has certain sexual elements;`); + if (pcHorny) { + r.push(`you eagerly break them in an effort to break ${her}, but only succeed in forcing ${her} hold them even dearer.`); + slave.training = 0; + SimpleSexAct.Player(slave, 4); + } else { + r.push(`you amuse yourself by forcing ${him} to break them, and rewarding ${him} generously when ${he} does.`); + } } - if (slave.training < 100) { + if (slave.training <= 0) { + r.push(`You make no progress into fixing ${his} flaw and, if anything, have made matters worse. You need to rethink your strategy.`); + } else if (slave.training < 100) { r.push(`You make progress, but ${he}'s the same at the end of the week.`); + if (hindranceMod <= .5) { + r.push(`Your body makes you sluggish, allowing ${him} plenty of opportunity to avoid these unpleasant situations.`); + } } else { slave.training = 0; r.push(`By the end of the week,`); - r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, ["green"])); - r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, ["flaw", "break"])); + r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["devotion", "inc"])); SoftenBehavioralFlaw(slave); slave.devotion += 4; } @@ -420,15 +779,15 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`${He} really takes to your close attention;`); r.push(App.UI.DOM.makeElement("span", `${he}'s a natural submissive!`, ["pink"])); slave.fetishKnown = 1; - } else if (slave.fetish === "cumslut") { + } else if (slave.fetish === Fetish.CUMSLUT) { r.push(`While you're giving ${him} personal attention, you discover by chance that`); r.push(App.UI.DOM.makeElement("span", `${he} has an oral fixation!`, ["pink"])); slave.fetishKnown = 1; - } else if (slave.fetish === "masochist") { + } else if (slave.fetish === Fetish.MASOCHIST) { r.push(`While you're giving ${him} personal correction, you discover by chance that`); r.push(App.UI.DOM.makeElement("span", `${he} likes pain!`, ["pink"])); slave.fetishKnown = 1; - } else if (slave.fetish === "humiliation") { + } else if (slave.fetish === Fetish.HUMILIATION) { r.push(`While you're giving ${him} personal attention in public, you discover by chance that`); r.push(App.UI.DOM.makeElement("span", `${he} likes humiliation!`, ["pink"])); slave.fetishKnown = 1; @@ -439,7 +798,10 @@ App.PersonalAttention.slaveReport = function(slave) { coloredText = []; r.push(`${his} training assignment has defaulted to`); if (slave.sexualFlaw === "none") { - if (slave.devotion <= 20 && slave.trust >= -20) { + if (isHorny(V.PC) && (canPenetrate(V.PC) || V.PC.clit >= 3) && (canDoAnal(slave) || canDoVaginal(slave))) { + coloredText.push(`relieving your sexual tension.`); + pa.objective = "ravish"; + } else if (slave.devotion <= 20 && slave.trust >= -20) { coloredText.push(`breaking ${his} will.`); pa.objective = "break will"; } else { @@ -450,7 +812,7 @@ App.PersonalAttention.slaveReport = function(slave) { coloredText.push(`softening ${his} sexual flaw.`); pa.objective = "soften sexual flaw"; } - r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["yellow"])); + r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["noteworthy"])); } } break; @@ -471,25 +833,33 @@ App.PersonalAttention.slaveReport = function(slave) { coloredText.push(`softening ${his} behavioral flaw.`); pa.objective = "soften behavioral flaw"; } - r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["yellow"])); + r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["noteworthy"])); } else { r.push(`${slave.slaveName}`); switch (slave.sexualFlaw) { case "hates oral": r.push(`has a powerful gag reflex. Though it would be simpler to train ${him} out of it, you do your best to train ${him} to safely take a rough facefuck without losing the fun aspects of forcing a slave to swallow a phallus, like the struggles, the gagging, and the tears.`); + if (pcHorny) { + r.push(`Your libido frequently gets in the way, forcing you to stop rutting against ${his} face and get yourself back under control.`); + seX(slave, "oral", V.PC, "penetrative", 10); + slave.training *= 0.75; + } seX(slave, "oral", V.PC, "penetrative", 10); break; case "hates anal": r.push(`does not like it up the butt. Though it would be simpler to train ${him} out of it, you do your best to train ${him} to safely take a rough buttfuck without losing the fun aspects of anal rape, like the struggles, the whining, and the tears.`); - if (canDoAnal(slave)) { + if (canDoAnal(slave) && pcHorny) { r.push(VCheck.Anal(slave, 10)); + r.push(`Your libido frequently gets in the way, forcing you to slow down and get a hold of yourself before you fuck all the progress you've made out of ${his} ass.`); + seX(slave, "anal", V.PC, "penetrative", 10); + slave.training *= 0.75; } else { r.push(`The inability to actually penetrate ${his} ass hinders your efforts, however.`); slave.training -= 20; // more difficult training } break; case "hates penetration": - if (slave.vagina > -1 && canDoVaginal(slave)) { + if (canDoVaginal(slave)) { r.push(`does not like sex. Though it would be simpler to train ${him} out of it, you do your best to train ${him} to safely take a hard pounding without losing the fun aspects of forced sex, like the struggles, the whining, and the tears.`); r.push(VCheck.Vaginal(slave, 10)); } else if (canDoAnal(slave)) { @@ -499,14 +869,42 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`does not dicks in ${his} mouth. Though it would be simpler to train ${him} out of it, you do your best to train ${him} to safely take a rough facefuck without losing the fun aspects of forcing a slave to swallow a phallus, like the struggles, the gagging, and the tears.`); seX(slave, "oral", V.PC, "penetrative", 10); } + if (pcHorny) { + r.push(`Your libido frequently gets in the way, forcing you to stop and reconsider your actions before you reinforce ${his} hatred rather than resolve it.`); + slave.training *= 0.50; + } break; case "apathetic": r.push(`doesn't put out much effort when having sex. You do your best to redirect this apathy into caring for ${his} partners; since ${he} obviously doesn't think much of ${himself}, ${he} can spare the effort.`); - seX(slave, "oral", V.PC, "penetrative", 10); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 5); + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 5); + } + SimpleSexAct.Player(slave, 5); + if (pcHorny) { + r.push(`You frequently get carried away with fucking ${him}, completely forgetting that ${his} inertness is not cause for you to bang ${him} harder.`); + slave.training *= 0.75; + SimpleSexAct.Player(slave, 7); + } break; case "crude": - r.push(`does not pay enough attention to standards when having sex, leading to crude comments and unsexy noises. To remedy this, you have ${him} give you oral regularly: a sacrifice, but you make sacrifices for your slaves' improvement. Oral sex can be difficult to make elegant, but you work with ${him} to make it as pretty as possible, even when you require ${him} to apply ${his} mouth to some of the less common erogenous zones. You do your best to retain ${his} sexual openness while making ${him} more sexually presentable.`); - seX(slave, "oral", V.PC, "penetrative", 10); + r.push(`does not pay enough attention to standards when having sex, leading to crude comments and unsexy noises.`); + if (pcHorny) { + r.push(`Unfortunately, you're often so horny that you fall into the same habits, creating a well of unsexy crudeness between the two of you.`); + slave.training = 0; + SimpleSexAct.Player(slave, 15); + } else { + r.push(`To remedy this, you have ${him} give you oral regularly: a sacrifice, but you make sacrifices for your slaves' improvement. Oral sex can be difficult to make elegant, but you work with ${him} to make it as pretty as possible, even when you require ${him} to apply ${his} mouth to some of the less common erogenous zones. You do your best to retain ${his} sexual openness while making ${him} more sexually presentable.`); + if (V.PC.dick > 0 || V.PC.clit >= 3) { + seX(slave, "oral", V.PC, "penetrative", 10); + if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 5); + } + } else if (V.PC.vagina >= 0) { + seX(slave, "oral", V.PC, "vaginal", 10); + } + } break; case "judgemental": r.push(`has a bad habit of being sexually judgemental, belittling anyone who doesn't live up to ${his} pretensions of standards. You do your best to train ${him} to perform regardless of ${his} partners' endowments, aiming for a delicate balance that will allow ${him} to get off with anyone while permitting ${him} to retain and even build on ${his} appetite for big dicks. You permit ${him} to achieve release only when ${he}'s done well with`); @@ -557,7 +955,7 @@ App.PersonalAttention.slaveReport = function(slave) { coloredText.push(`fostering devotion.`); pa.objective = "build devotion"; } - r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["yellow"])); + r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["noteworthy"])); break; default: r.push(`has something. You should probably report this as nobody knows what is currently happening. ${His} flaw was supposed to be ${slave.sexualFlaw}.`); @@ -567,8 +965,8 @@ App.PersonalAttention.slaveReport = function(slave) { } else { slave.training = 0; r.push(`By the end of the week,`); - r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, ["green"])); - r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"])); + r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, ["flaw", "break"])); + r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["devotion", "inc"])); SoftenSexualFlaw(slave); slave.devotion += 4; } @@ -577,15 +975,15 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`${He} really takes to your close attention;`); r.push(App.UI.DOM.makeElement("span", `${he}'s a natural submissive!`, ["pink"])); slave.fetishKnown = 1; - } else if (slave.fetish === "cumslut") { + } else if (slave.fetish === Fetish.CUMSLUT) { r.push(`While you're giving ${him} personal attention, you discover by chance that`); r.push(App.UI.DOM.makeElement("span", `${he} has an oral fixation!`, ["pink"])); slave.fetishKnown = 1; - } else if (slave.fetish === "masochist") { + } else if (slave.fetish === Fetish.MASOCHIST) { r.push(`While you're giving ${him} personal correction, you discover by chance that`); r.push(App.UI.DOM.makeElement("span", `${he} likes pain!`, ["pink"])); slave.fetishKnown = 1; - } else if (slave.fetish === "humiliation") { + } else if (slave.fetish === Fetish.HUMILIATION) { r.push(`While you're giving ${him} personal attention in public, you discover by chance that`); r.push(App.UI.DOM.makeElement("span", `${he} likes humiliation!`, ["pink"])); slave.fetishKnown = 1; @@ -607,7 +1005,7 @@ App.PersonalAttention.slaveReport = function(slave) { coloredText.push(`softening ${his} behavioral flaw.`); pa.objective = "soften behavioral flaw"; } - r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["yellow"])); + r.push(App.UI.DOM.makeElement("span", coloredText.join(" "), ["noteworthy"])); } } break; @@ -987,7 +1385,7 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`in motion,`); } r.push(`and soon your moves take a sexual`); - if (slave.energy > 95 || slave.aphrodisiacs > 0 || slave.inflationType === "aphrodisiac") { + if (isHorny(slave)) { r.push(`turn, only to be matched by the equally aroused slave${girl}. The session quickly devolves into what can only be described as "tantric wrestling" and only ends when the two of you are too exhausted to continue. Neither of you even considered improving your combat skills, but you both found the match to be`); r.push(App.UI.DOM.makeElement("span", `rather stimulating`, ["hotpink"])); r.push(`and something that should happen again. It isn't long until ${he} challenges you to another sparring match, to which you happily oblige.`); @@ -2048,7 +2446,7 @@ App.PersonalAttention.slaveReport = function(slave) { fuckCount = Math.trunc(fuckCount / 2); } seX(slave, holeCheck, V.PC, "penetrative", fuckCount); - if (V.PC.visualAge <= 12 && V.PC.visualAge < V.minimumSlaveAge && slave.fetish !== Fetish.MINDBROKEN) { + if (V.PC.visualAge <= 12 && V.PC.visualAge < V.minimumSlaveAge && slave.fetish !== Fetish.MINDBROKEN && slave.career !== "a slave since birth") { if (slave.behavioralQuirk === "sinful") { r.push(`${He} may try to deny it, but you can tell ${he}`); r.push(App.UI.DOM.makeElement("span", `enjoyed`, ["devotion", "inc"])); @@ -2317,7 +2715,7 @@ App.PersonalAttention.slaveReport = function(slave) { } enjoyed = true; } - if (V.PC.visualAge <= 12 && V.PC.visualAge < V.minimumSlaveAge && slave.fetish !== Fetish.MINDBROKEN) { + if (V.PC.visualAge <= 12 && V.PC.visualAge < V.minimumSlaveAge && slave.fetish !== Fetish.MINDBROKEN && slave.career !== "a slave since birth") { if (slave.behavioralQuirk === "sinful") { r.push(`${He} may try to deny it, but you can tell ${he}`); r.push(App.UI.DOM.makeElement("span", `enjoyed`, ["devotion", "inc"])); diff --git a/src/endWeek/saLongTermEffects.js b/src/endWeek/saLongTermEffects.js index 0d8652208636f2f77e46dfa3d2d17eeefd48b885..448bc0e06447553578b56f511ce3a365139c93d3 100644 --- a/src/endWeek/saLongTermEffects.js +++ b/src/endWeek/saLongTermEffects.js @@ -2312,6 +2312,9 @@ App.SlaveAssignment.longTermEffects = function saLongTermEffects(slave) { } else if (slave.health.health > 80) { miscarriageChance -= (slave.health.health / 10); } + if (slave.physicalAge > 60) { + miscarriageChance += (slave.physicalAge - 60); + } if (slave.weight < -50) { miscarriageChance -= slave.weight; } diff --git a/src/gui/options/options.js b/src/gui/options/options.js index a79fd1c1b8cf71dd1c0e9078cc0bc424d05f7ce2..0b20cab2c4b8557c2384e6fb5ad4b99948691666 100644 --- a/src/gui/options/options.js +++ b/src/gui/options/options.js @@ -713,6 +713,10 @@ App.UI.optionsPassage = function() { .addComment("This will enable the experimental nursery, which allows players to interact with growing slave children. An alternative to the incubator."); } + options.addOption("Allow sufficiently large clitori to evaluate true in canPenetrate()", "clitoralPenetration", V.experimental) + .addValue("Enabled", 1).on().addValue("Disabled", 0).off() + .addComment("canPenetrate() was originally built to assume dicks, so not all scenes may make sense without one. May also lead to awkward pregnancies."); + if (V.seeExtreme === 1 && V.seeBestiality === 1) { options.addOption("Animal Ovaries are", "animalOvaries", V.experimental) .addValue("Enabled", 1).on().addValue("Disabled", 0).off() diff --git a/src/js/sexActsJS.js b/src/js/sexActsJS.js index bc5183d404c853220675e15c5414502aae02878b..15ba1bdb4d9d1af5555ab159bc1a4a040fee956a 100644 --- a/src/js/sexActsJS.js +++ b/src/js/sexActsJS.js @@ -83,7 +83,7 @@ globalThis.VCheck = (function() { r += `${He} thinks of losing ${his} virginity to ${his} ${getWrittenTitle(slave)} a <span class="hotpink">necessity to be happy.</span> ${He} expects ${his} pussy to be seeing a lot more attention in the future.`; } else { r += `<span class="hotpink">${He} enjoys losing ${his} cherry to you,</span> and `; - if ((slave.fetishKnown && slave.fetish === "pregnancy") || (slave.energy > 95) || (slave.attrXY >= 85 && canPenetrate(V.PC))) { + if ((slave.fetishKnown && slave.fetish === "pregnancy") || (slave.energy > 95) || (canPenetrate(V.PC) && ((slave.attrXY >= 85 && V.PC.dick > 0) || (slave.attrXX >= 85 && V.PC.clit >= 3)))) { r += `can't wait to have ${his} pussy fucked by you again.`; } else { r += `looks forward to having ${his} pussy fucked by you again.`; diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js index 3e68ea1315ee86a76490a859715574d2a2348f70..7ee73e40dc7c1651f0e9e906e575374499e83887 100644 --- a/src/js/statsChecker/statsChecker.js +++ b/src/js/statsChecker/statsChecker.js @@ -700,16 +700,18 @@ globalThis.canAchieveErection = function(slave) { globalThis.canPenetrate = function(slave) { if (!slave) { return null; + /* + } else if (slave.belly >= 300000) { + return false; + */ + } else if (slave.clit >= 3 && !slave.chastityPenis && V.experimental.clitoralPenetration) { + return true; } else if (!canAchieveErection(slave)) { return false; } else if (slave.chastityPenis === 1) { return false; } else if (slave.dick > 7) { return false; - /* - } else if (slave.belly >= 300000) { - return false; - */ } return true; }; @@ -1232,6 +1234,19 @@ globalThis.isHorny = function(actor) { (actor.drugs === "priapism agents")); }; +/** + * A consolidated function for checking if a slave is comfortable with underage partners. + * @param {FC.HumanState} actor + * @returns {boolean} + */ +globalThis.acceptsUnderage = function(actor) { + return (actor.fetish === Fetish.MINDBROKEN || + (actor.behavioralQuirk === "sinful") || + (actor.devotion > 50) || + (actor.trust > 50) || + (actor.career === "a slave since birth")); +}; + /** * @param {FC.HumanState} slave * @returns {boolean} diff --git a/src/js/utilsPC.js b/src/js/utilsPC.js index 9e88a1c2bfc351b6aaab597580c10f91743f9dfa..1e4a468784deff28bd6dc1392c872d4c19fc24ab 100644 --- a/src/js/utilsPC.js +++ b/src/js/utilsPC.js @@ -1134,4 +1134,17 @@ globalThis.isPlayerReceptive = function(penetrator = null) { return true; // forcedFertDrugs influence the behavior of the player, who unconsciously wants to be fertilized } return false; -} \ No newline at end of file +} + +/** Determine if the player favors masturbation over sex. + * Currently not used much, but will be used more with the addition of new .pregMoods + * @returns {boolean} + */ +globalThis.isPlayerFrigid = function() { + if (V.PC.preg > V.PC.pregData.normalBirth / 2 && V.PC.pregMood === 2) { + return false; + } else if (V.PC.energy === 0) { + return true; + } + return false; +}; diff --git a/src/player/desc/pLongCrotch.js b/src/player/desc/pLongCrotch.js index 599b004bfea88ada31b82fd42d7097efb682c714..994f3765cad8bd172d33a11e1271eecffd90f986 100644 --- a/src/player/desc/pLongCrotch.js +++ b/src/player/desc/pLongCrotch.js @@ -447,6 +447,8 @@ App.Desc.Player.crotch = function(PC = V.PC) { if (PC.belly >= 100000) { r.push(`Your belly is so large it pushes against your erection, forcing it down and making it difficult to properly mount a girl.`); + //} else if (PC.belly >= 15000) { + // r.push(`Your belly is large enough that you can't properly reach your erection to masturbate, forcing you to have sex or find some other way to deal with it.`); } else { r.push(`Your gut is so huge and soft, your erection is forced to push a fold into it, inadvertently making you give yourself a bellyjob.`); }