diff --git a/CHANGELOG.md b/CHANGELOG.md index aebf4da5d4e0aab7de4045895e06039f9eafc282..37c46de18bd4c6a31e11e3bef9851c58359e4c1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## Unreleased +* overhauled incubator tank controls +* added Ravish PA * added torture PA +* RECI adoption * refsArtifact events +* added support for mod-added drugs * fixes ## 0.10.7.1-4.0.0-alpha.25 - 2023-03-12 diff --git a/src/endWeek/economics/persBusiness.js b/src/endWeek/economics/persBusiness.js index 961ace789b5da148c27c6036242115e4e0b03649..7d49422d16409ed3b92b3c9548d09f13d20ff28b 100644 --- a/src/endWeek/economics/persBusiness.js +++ b/src/endWeek/economics/persBusiness.js @@ -13,7 +13,7 @@ App.EndWeek.personalBusiness = function() { let upgradeCount; let dataGain; let hindranceMod = isHinderedDegree(V.PC); - const nymphoMod = isHorny(V.PC) ? .75 : 1; + const nymphoMod = isPlayerLusting() ? .75 : 1; const {girlP} = getPronouns(V.PC).appendSuffix("P"); if (V.useTabs === 0) { App.UI.DOM.appendNewElement("h2", el, `Personal Business`); diff --git a/src/endWeek/events/death.js b/src/endWeek/events/death.js index 8d5e3a2f9f1ed126d2604ca46416615fe85b77e3..f55f2426f09cd86d3e049979d53e64d3b6d9f7b0 100644 --- a/src/endWeek/events/death.js +++ b/src/endWeek/events/death.js @@ -82,6 +82,23 @@ App.Events.SEDeath = class SEDeath extends App.Events.BaseEvent { r.push(`suddenly, unrelated to`); } r.push(`${his} living conditions. Thankfully the suit notifies its owner of such things; especially with the rumors of earlier models and necrophilia you hear occasionally.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) { + r.push(`After achieving your fourth climax in a row, you slap <span class="pink bold">${slave.slaveName}</span> on the ass for a job well done. To your chagrin, ${he}, almost comically, flops over onto ${his} side without changing position. ${He} passed sometime during coitus and you aren't sure when. ${slave.slaveName} died at the age of ${slave.actualAge};`); + if (slave.actualAge < 10) { + r.push(`${he} lived a tragically short life.`); + } else if (slave.actualAge < 20) { + r.push(`${he} died far too young.`); + } else if (slave.actualAge < 30) { + r.push(`${he} died in what would be a sex slave's prime.`); + } else if (slave.actualAge < 50) { + r.push(`${he} died in ${his} prime.`); + } else if (slave.actualAge < 65) { + r.push(`${he} lived a fair life, good or bad.`); + } else if (slave.actualAge < 90) { + r.push(`${he} lived a long life and experienced much during it.`); + } else { + r.push(`${he} lived a very long life that few get to see.`); + } } else if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) { r.push(`After taking a break from beating <span class="pink bold">${slave.slaveName}</span> to freshen up, you return to find ${him} dead. Age claimed ${his} life before you could; you can't help but feel a little cheated.`); } else { @@ -127,6 +144,29 @@ App.Events.SEDeath = class SEDeath extends App.Events.BaseEvent { r.push(`You are notified by ${V.dairyName} staff that one of the occupied milkers has ceased producing. Upon inspection, it would seem <span class="pink bold">${slave.slaveName},</span> the cow restrained in it, died of an aphrodisiac overdose. How ${he} managed to get them is unknown, but ${he} was a good cow; ${he} gave milk up until ${his} death.`); } else if (slave.fuckdoll > 0) { r.push(`One of your Fuckdolls' monitoring systems alerts you that the slave contained within has died. It would seem <span class="pink bold">${slave.slaveName}</span> has died of an aphrodisiac overdose. Thankfully the suit notifies its owner of such things; especially with the rumors of earlier models and necrophilia you hear occasionally. It does little to deal with the resulting mess of the orgasm ${he} died during, however.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) { + r.push(`After three sequential orgasms, you aren't quite satisfied yet, but <span class="pink bold">${slave.slaveName}</span> is nearing ${his} limit. Fortunately, a quick dose of aphrodisiacs corrects that and ${he}'s back in for another round. Once you really get going and begin to near your end, ${he} spasms`); + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`and clamps down`); + } else { + r.push(`and bucks`); + } + r.push(`hard against you, sending you careening over the edge into orgasmic bliss. Only once you manage to catch your breath and move to comment on ${his} impressive climax do you discover that it was ${his} last. ${slave.slaveName} died of an overdose at the age of ${slave.actualAge};`); + if (slave.actualAge < 10) { + r.push(`${he} lived a tragically short life.`); + } else if (slave.actualAge < 20) { + r.push(`${he} died far too young.`); + } else if (slave.actualAge < 30) { + r.push(`${he} died in what would be a sex slave's prime.`); + } else if (slave.actualAge < 50) { + r.push(`${he} died in ${his} prime.`); + } else if (slave.actualAge < 65) { + r.push(`${he} lived a fair life, good or bad.`); + } else if (slave.actualAge < 90) { + r.push(`${he} lived a long life and experienced much during it.`); + } else { + r.push(`${he} lived a very long life that few get to see.`); + } } else if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) { r.push(`While taking a break from beating <span class="pink bold">${slave.slaveName}</span> to enjoy a little raping, ${he} seizes up in a particularly strong orgasm due to all the aphrodiasiacs you've been pumping into ${him}. As you finish up, you can't help but notice that ${he} as gone completely limp. A brief inspection reveals you've fucked the life out of ${him}.`); SimpleSexAct.Player(slave); @@ -159,6 +199,27 @@ App.Events.SEDeath = class SEDeath extends App.Events.BaseEvent { r.push(`You are notified by ${V.dairyName} staff that one of the occupied milkers has ceased producing. Upon inspection, it would seem <span class="pink bold">${slave.slaveName},</span> the cow restrained in it, died to poor health caused by ${his} living conditions. ${He} was a good cow; ${he} gave milk up until ${his} death.`); } else if (slave.fuckdoll > 0) { r.push(`One of your Fuckdolls' monitoring systems alerts you that the slave contained within has died. It would seem <span class="pink bold">${slave.slaveName}</span> has died of general poor health. Thankfully the suit notifies its owner of such things; especially with the rumors of earlier models and necrophilia you hear occasionally. Clean up is easy enough, however.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) { + r.push(`As you are enjoying <span class="pink bold">${slave.slaveName}</span>'s body, you can't help but notice ${he} is participating less and less in your copulation. You carry on to completion, only to discover you have successfully mated with a dead body! ${He} was in poor health lately, and odds are high that ${his} body just couldn't handle the strain of near-constant intercourse. Given the urges to keep going, the intrusive thoughts about how ${his} body is still warm, and that perhaps this is your fault, maybe this should be the wake-up call for you getting your libido back under control. ${slave.slaveName} died at the age of ${slave.actualAge};`); + if (slave.actualAge < 10) { + r.push(`${he} lived a tragically short life.`); + } else if (slave.actualAge < 20) { + r.push(`${he} died far too young.`); + } else if (slave.actualAge < 30) { + r.push(`${he} died in what would be a sex slave's prime.`); + } else if (slave.actualAge < 50) { + r.push(`${he} died in ${his} prime.`); + } else if (slave.actualAge < 65) { + r.push(`${he} lived a fair life, good or bad.`); + } else if (slave.actualAge < 90) { + r.push(`${he} lived a long life and experienced much during it.`); + } else { + r.push(`${he} lived a very long life that few get to see.`); + } + if (V.arcologies[0].FSPaternalist !== "unset" && slave.actualAge < 75) { + r.push(`Allowing a slave to perish under your care <span class="red">severely damages</span> your image as a caring slaveowner and <span class="red">calls into question</span> your paternalistic resolve. It's probably best that they don't find out that you finished in ${him} after the fact.`); + FutureSocieties.Change("Paternalist", -10); + } } else if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) { r.push(`As you begin to work <span class="pink bold">${slave.slaveName}</span> over, you find ${he} is quickly becomes unresponsive to your strikes, so you do the only logical thing; hit ${him} harder. When ${he} still ignores your efforts, you decide to give ${him} a cursory inspection. Turns out you managed to beat the life out of ${him}.`); if (V.arcologies[0].FSPaternalist !== "unset") { @@ -184,7 +245,7 @@ App.Events.SEDeath = class SEDeath extends App.Events.BaseEvent { r.push(`${he} lived a very long life that few get to see.`); } if (V.arcologies[0].FSPaternalist !== "unset" && slave.actualAge < 75) { - r.push(`Allowing a slave to die under your care <span class="red">severely damages</span> your image as a caring slaveowner and <span class="red">calls into question</span> your paternalistic resolve.`); + r.push(`Allowing a slave to perish under your care <span class="red">severely damages</span> your image as a caring slaveowner and <span class="red">calls into question</span> your paternalistic resolve.`); FutureSocieties.Change("Paternalist", -10); } } diff --git a/src/endWeek/reports/personalAttention.js b/src/endWeek/reports/personalAttention.js index 0618134572e983442874eb5329211e9953de3287..1e04cfc223e81ce319d681a3598f549172d9e8fc 100644 --- a/src/endWeek/reports/personalAttention.js +++ b/src/endWeek/reports/personalAttention.js @@ -17,7 +17,7 @@ App.PersonalAttention.slaveReport = function(slave) { He, His, he, his, him, himself, wife, girl, hers, } = getPronouns(slave); - const {womenP} = getPronouns(V.PC).appendSuffix("P"); + const {womenP, girlP} = getPronouns(V.PC).appendSuffix("P"); let r = []; if (onBedRest(V.PC, true)) { @@ -25,7 +25,9 @@ App.PersonalAttention.slaveReport = function(slave) { if (pa.objective === "health") { r.push(`wanted to care for`); } else if (pa.objective === "ravish") { - r.push(`really wanted to fuck`); + r.push(`really wanted to sate your lust in`); + } else if (pa.objective === "ravished") { + r.push(`really wanted to sate your urges with`); } else if (pa.objective === "torture") { r.push(`wanted to torment`); } else { @@ -61,6 +63,34 @@ App.PersonalAttention.slaveReport = function(slave) { } App.Events.addNode(el, r, "div", "indent"); return el; + } else if (pa.objective === "ravish") { + if (!canAchieveErection(V.PC) && V.PC.vagina === -1 && V.PC.clit < 3) { + r.push(`Plowing`); + r.push(App.UI.DOM.makeElement("span", slave.slaveName, ["slave-name"])); + r.push(`senseless just isn't the same when you aren't getting any pleasure out of it.`); + r.push(App.UI.DOM.makeElement("span", `${His} assignment has defaulted to fostering devotion`, "yellow")); + r.push(`to better prepare ${him} for future fuckings.`); + pa.objective = "build devotion"; + App.Events.addNode(el, r, "div", "indent"); + return el; + } else if (!canDoVaginal(slave) && !canDoAnal(slave)) { + r.push(App.UI.DOM.makeElement("span", slave.slaveName, ["slave-name"])); + r.push(`is completely secured in chastity, leaving no holes suitable for constant sex.`); + r.push(App.UI.DOM.makeElement("span", `${His} assignment has defaulted to fostering devotion`, "yellow")); + r.push(`until you decide what to do with ${him}.`); + pa.objective = "build devotion"; + App.Events.addNode(el, r, "div", "indent"); + return el; + } + } else if (pa.objective === "ravished" && !canPenetrate(slave)) { + r.push(`You find it rather difficult to get dicked when`); + r.push(App.UI.DOM.makeElement("span", slave.slaveName, ["slave-name"])); + r.push(`doesn't have a working one.`); + r.push(App.UI.DOM.makeElement("span", `${His} assignment has defaulted to fostering devotion`, "yellow")); + r.push(`until you figure out what to do with ${him}.`); + pa.objective = "build devotion"; + App.Events.addNode(el, r, "div", "indent"); + return el; } // actually training this slave @@ -76,7 +106,7 @@ App.PersonalAttention.slaveReport = function(slave) { let milkTotal = 0; let oldSkill; const hindranceMod = isHinderedDegree(V.PC); - const nymphoMod = isHorny(V.PC) ? .75 : 1; + const nymphoMod = isPlayerLusting() ? .75 : 1; if (pa.objective === "health") { r.push(App.UI.DOM.makeElement("span", `You care for`, ["bold"])); } else if (pa.objective === "spar") { @@ -90,11 +120,17 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`You tightly bind and`); } r.push(App.UI.DOM.makeElement("span", `brutally torment`, ["bold"])); + } else if (pa.objective === "ravish" || pa.objective === "ravished") { + r.push(App.UI.DOM.makeElement("span", `Whenever your lust peaks, you take advantage of`, ["bold"])); } else { r.push(App.UI.DOM.makeElement("span", `You train`, ["bold"])); } r.push(App.UI.DOM.makeElement("span", slave.slaveName, ["slave-name"])); - r.push(`when ${he} isn't otherwise occupied.`); + if (pa.objective === "ravish" || pa.objective === "ravished") { + r.push(`to keep your arousal in check.`); + } else { + r.push(`when ${he} isn't otherwise occupied.`); + } slave.training = Math.clamp(slave.training, 0, 100); slave.training += 80 - (slave.intelligence + slave.intelligenceImplant) / 5 + ((slave.devotion + slave.trust) / 10); if ((V.PC.skill.slaving >= 100) && V.personalAttention.slaves.length === 1) { @@ -866,25 +902,17 @@ App.PersonalAttention.slaveReport = function(slave) { if (canPenetrate(V.PC)) { r.push(`some sweaty sex.`); seX(slave, "vaginal", V.PC, "penetrative"); - if (canImpreg(slave, V.PC)) { - knockMeUp(slave, 5, 0, -1); - } + tryKnockMeUp(slave, 5, 0, V.PC); } else { r.push(`some sweaty tribbing.`); seX(slave, "vaginal", V.PC, "vaginal"); - if (canFemImpreg(slave, V.PC)) { - knockMeUp(slave, 3, 0, -1); - } - if (canFemImpreg(V.PC, slave)) { - knockMeUp(V.PC, 3, 0, slave.ID); - } + tryKnockMeUp(slave, 3, 0, V.PC); + tryKnockMeUp(V.PC, 3, 0, slave); } } else if (canDoAnal(slave) && slave.anus > 0 && canPenetrate(V.PC)) { r.push(`some sweaty anal.`); seX(slave, "anal", V.PC, "penetrative"); - if (canImpreg(slave, V.PC)) { - knockMeUp(slave, 5, 1, -1); - } + tryKnockMeUp(slave, 5, 1, V.PC); } else if ((V.policies.sexualOpenness === 1 || slave.toyHole === "dick") && (V.PC.dick > 0 || V.PC.vagina >= 0) && ((slave.dick > 0 && slave.chastityPenis === 0) || canDoVaginal(slave)) && V.PC.belly + slave.belly < 5000) { r.push(`a sweaty 69.`); if (V.PC.dick > 0) { @@ -901,14 +929,10 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`you getting filled by ${his} dick.`); if (V.PC.vagina > 0) { seX(slave, "penetrative", V.PC, "vaginal"); - if (canImpreg(V.PC, slave)) { - knockMeUp(V.PC, 5, 0, slave.ID); - } + tryKnockMeUp(V.PC, 5, 0, slave); } else { seX(slave, "penetrative", V.PC, "anal"); - if (canImpreg(V.PC, slave)) { - knockMeUp(V.PC, 5, 1, slave.ID); - } + tryKnockMeUp(V.PC, 5, 1, slave); } } else if (V.PC.dick > 0) { r.push(`you getting your dick sucked.`); @@ -1025,9 +1049,7 @@ App.PersonalAttention.slaveReport = function(slave) { if (V.PC.vagina > 0) { r.push(`and quickly penetrates you. A few thrusts in and your libido is back in control and bucking against ${him} as ${he} fucks you raw. ${He} doesn't have much sexual stamina, nor time to take it slow, so ${he} blows ${his} load into you as soon as ${he} can and hurries off before anyone else notices what is going on.`); seX(slave, "penetrative", V.PC, "vaginal"); - if (canImpreg(V.PC, slave)) { - knockMeUp(V.PC, 5, 0, slave.ID); - } + tryKnockMeUp(V.PC, 5, 0, slave); } else if (V.PC.anus > 0) { if (V.PC.vagina === 0) { r.push(`and, after considering your virgin pussy for a moment, decides not to risk it and shoves it in your ass instead.`); @@ -1037,9 +1059,7 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`A few thrusts in and your libido is back in control and bucking against ${him} as ${he} fucks you raw. ${He} doesn't have much sexual stamina, nor time to take it slow, so ${he} blows ${his} load into you as soon as ${he} can and hurries off before anyone else notices what is going on.`); cumTotal = (cumAmount(slave) / 70); seX(slave, "penetrative", V.PC, "anal"); - if (canImpreg(V.PC, slave)) { - knockMeUp(V.PC, 5, 1, slave.ID); - } + tryKnockMeUp(V.PC, 5, 1, slave); } else { if (V.PC.vagina === 0 || V.PC.anus === 0) { r.push(`and, after considering your virginity for a moment, decides not to risk it and shoves it in your mouth instead.`); @@ -1160,9 +1180,7 @@ App.PersonalAttention.slaveReport = function(slave) { } r.push(`A few thrusts in and your libido is back in control and bucking against ${him} as ${he} fucks you raw. ${He} doesn't have much sexual stamina, but ${he} makes sure to take ${his} time to better the odds of fucking you senseless. ${He} thoroughly creampies you for good measure before heading on ${his} way.`); seX(slave, "penetrative", V.PC, "vaginal"); - if (canImpreg(V.PC, slave)) { - knockMeUp(V.PC, 15, 0, slave.ID); - } + tryKnockMeUp(V.PC, 15, 0, slave); } else if (V.PC.anus >= 0) { if (V.PC.anus > 0) { r.push(`and quickly shoves it in your ass.`); @@ -1178,9 +1196,7 @@ App.PersonalAttention.slaveReport = function(slave) { r.push(`${He} briefly considers trying to drain the cumballoon ${he} has turned you into, but decides it's not worth the added risk.`); } seX(slave, "penetrative", V.PC, "anal"); - if (canImpreg(V.PC, slave)) { - knockMeUp(V.PC, 15, 1, slave.ID); - } + tryKnockMeUp(V.PC, 15, 1, slave); } else { r.push(`and quickly shoves it in your mouth.`); if (canTaste(V.PC)) { @@ -1662,7 +1678,422 @@ App.PersonalAttention.slaveReport = function(slave) { FutureSocieties.Change("Hedonistic", 2); } } - // add slave death here + break; + } + case "ravish": { // make sure these clear the slave's .need + const tinyDick = canAchieveErection(V.PC) && (V.PC.dick === 1 || (V.PC.dick < 3 && V.PC.physicalAge > 12) || (slave.sexualQuirk === "size queen" && V.PC.dick < 4)); + const holeCheck = canDoVaginal(slave) ? "vaginal" : "anal"; + let bigDick = canAchieveErection(V.PC) && (V.PC.dick > 5 || V.PC.dick - (holeCheck === "vaginal" ? slave.vagina : slave.anus) > 3 || (slave.physicalAge <= 12 && V.PC.dick > 2)); + if (canAchieveErection(V.PC) && !canPenetrate(V.PC)) { + r.push(`You spend most of the week attempting to figure out a way to pair your dick with ${his} ${holeCheck === "vaginal" ? "genitals" : "rear"} while grinding as much pleasure out of ${him} as possible. Eventually the urges can no longer be ignored; your cock is going in ${him} one way or another. As you line your inhuman erection up with ${his} ${holeCheck === "vaginal" ? "vagina" : "anus"} to becomes overwhelmingly clear that you aren't going to easily fit, but that's not going to stop you; you need to fuck and you need it now! ${He} shivers in ${slave.fetish === Fetish.MASOCHIST && slave.devotion > 20 ? "anticipation" : "fear"} as you ram it as deep into ${him} as it will go and start vigorously humping away, the sheer tightness quickly sending you over the edge. In a moment of post-climax clarity, you realize you've`); + if (V.seeExtreme) { + r.push(App.UI.DOM.makeElement("span", `ripped ${his} ${holeCheck === "vaginal" ? "pussy" : "asshole"} completely apart`, ["health", "dec"])); + r.push(`and the blood loss is quickly claiming ${him}.`); + } else { + r.push(App.UI.DOM.makeElement("span", `seriously injured`, ["health", "dec"])); + r.push(`${him}.`); + } + r.push(`You resist the urge for another round and rush ${him} off to the autosurgery in an attempt to put everything back where it belongs.`); + healthDamage(slave, 70); + if (slave.fetish === Fetish.MASOCHIST && slave.devotion > 20) { + slave.trust -= 10; + slave.devotion += 2; + r.push(`When ${he} wakes up, ${he}'s`); + r.push(App.UI.DOM.makeElement("span", `clearly distraught`, ["trust", "dec"])); + r.push(`from the ordeal, but overall seems to have`); + r.push(App.UI.DOM.makeElement("span", `found the sex exquisite.`, ["devotion", "inc"])); + } else if (slave.fetish !== Fetish.MINDBROKEN) { + slave.trust -= 40; + slave.devotion -= 20; + r.push(`When ${he} wakes up, ${he}'s`); + r.push(App.UI.DOM.makeElement("span", `completely terrified`, ["trust", "dec"])); + r.push(`of you and your dick and`); + r.push(App.UI.DOM.makeElement("span", `brutally reminded`, ["devotion", "dec"])); + r.push(`that ${he} is ultimately just a sex toy to be used and thrown out when it breaks.`); + } + seX(slave, holeCheck, V.PC, "penetrative"); + r.push(`Needless to say, there isn't much left of ${his}`); + if (holeCheck === "vaginal") { + if (slave.vagina === 0) { + r.push(App.UI.DOM.makeElement("span", `once virgin hole.`, ["virginity", "loss"])); + slave.vagina = 6; + } else if (slave.vagina < 6) { + r.push(`cunt other than the`); + r.push(App.UI.DOM.makeElement("span", `cavernous excavation`, ["change", "negative"])); + r.push(`you've left.`); + slave.vagina = 6; + } else { + r.push(`cunt, but you can't say there was to begin with. At least you're sure ${he} felt you inside ${him}, which is an accomplishment in and of itself.`); + } + } else if (holeCheck === "anal") { + if (slave.anus === 0) { + r.push(App.UI.DOM.makeElement("span", `once virgin hole.`, ["virginity", "loss"])); + slave.anus = 6; + } else { + r.push(`rectum other than the`); + r.push(App.UI.DOM.makeElement("span", `cavernous excavation`, ["change", "negative"])); + r.push(`you've left.`); + slave.anus = 6; + } + } + // Attempt to scramble fetus + if (V.dangerousPregnancy === 1 && !isInLabor(slave) && slave.pregAdaptation < 500 && slave.broodmother < 1 && slave.preg > slave.pregData.normalBirth / 2 && slave.geneMods.progenitor !== 1) { + let aborted = false; + if (slave.preg >= slave.pregData.normalBirth / 1.33) { + startLabor(slave); + } else if (slave.preg > slave.pregData.normalBirth / 1.81) { + slave.prematureBirth = 1; + startLabor(slave); + } else if (slave.fetish === Fetish.MASOCHIST && slave.devotion > 20) { + r.push(`The destruction you've wrought upon ${his} reproductive organs unsurprisingly`); + r.push(App.UI.DOM.makeElement("span", `caused ${him} to miscarry,`, "miscarriage")); + r.push(`but it seems ${he} accepted this inevitability the moment you entered ${him}.`); + aborted = true; + } else if (slave.fetish === Fetish.MINDBROKEN) { + r.push(`The destruction you've wrought upon ${his} reproductive organs unsurprisingly`); + r.push(App.UI.DOM.makeElement("span", `caused ${him} to miscarry,`, "miscarriage")); + r.push(`but ${his} broken mind fails to notice it amongst the other damage.`); + aborted = true; + } else { + r.push(`The destruction you've wrought upon ${his} reproductive organs unsurprisingly`); + r.push(App.UI.DOM.makeElement("span", `caused ${him} to miscarry.`, "miscarriage")); + if (slave.sexualFlaw === "breeder") { + r.push(`${He} is`); + r.push(App.UI.DOM.makeElement("span", `filled with violent, all-consuming hatred`, ["devotion", "dec"])); + r.push(`at you for doing this to ${him}.`); + if (slave.pregType > 4) { + r.push(`The loss of so many children at once`); + r.push(App.UI.DOM.makeElement("span", `shatters the distraught breeder's mind.`, ["mindbreak"])); + applyMindbroken(slave); + } else { + r.push(`${He} cares little for what punishment awaits ${his} actions.`); + slave.devotion -= 25 * slave.pregType; + } + } else { + r.push(`adding additional`); + r.push(App.UI.DOM.makeElement("span", `insult`, ["devotion", "dec"])); + r.push(`to ${his} injuries.`); + slave.devotion -= 10; + } + aborted = true; + } + if (aborted) { + slave.preg = rulesDemandContraceptives(slave, V.defaultRules) ? -1 : 0; + TerminatePregnancy(slave); + actX(slave, "abortions"); + if (slave.abortionTat > -1) { + slave.abortionTat++; + r.push(`The temporary tattoo of a child has been replaced with ${his} ${ordinalSuffix(slave.abortionTat)} crossed out infant.`); + cashX(forceNeg(V.modCost), "slaveMod", slave); + } + } + } + } else { + r.push(`You've had so much pent up sexual energy lately that you frequently need an outlet to keep the urges under control and your mind clear.`); + if (canPenetrate(V.PC)) { + r.push(`Your rock-hard erection is so eager for ${his} ${holeCheck === "vaginal" ? "pussy" : "ass"} that you waste no time on foreplay before in sticking it in.`); + } else if (V.PC.clit >= 3) { + r.push(`Your clit is so large and sensetive that it makes the perfect tool to piston in and out of ${his} ${holeCheck === "vaginal" ? "pussy" : "ass"} until the pleasure makes your body go numb.`); + } else if (V.PC.vagina === 0) { + r.push(`You don't care if it`); + r.push(App.UI.DOM.makeElement("span", `breaks your hymen and ruins your virginity,`, ["virginity", "loss"])); + r.push(`you need the stimulation of the double-ended dildo penetrating you while you fuck ${his} ${holeCheck === "vaginal" ? "pussy" : "ass"} with it.`); + V.PC.vagina++; + } else { + r.push(`A simple strap-on isn't enough; you need the stimulation of a double-ended dildo penetrating you while you fuck ${his} ${holeCheck === "vaginal" ? "pussy" : "ass"} to sate your needs.`); + } + if (slave.fetish === Fetish.MINDBROKEN) { + r.push(`At least you're seeking quantity over quality, since the mindbroken ${V.PC.balls > 0 ? "cumdump" : "slut"} brings little to the bedroom.`); + } else if (slave.energy < 20) { + r.push(`Since ${he} is sexually frigid, this existance is nothing but`); + r.push(App.UI.DOM.makeElement("span", `torment`, ["devotion", "dec"])); + r.push(`to ${him}.`); + if (bigDick) { + r.push(`As ${he} suffers your dick warping ${his} body to your desires, ${he} can't shake the`); + r.push(App.UI.DOM.makeElement("span", `fear`, ["trust", "dec"])); + r.push(`that ${he}'s nothing more than a disposable fucktoy to you.`); + slave.devotion -= 10; + slave.trust -= 10; + } else { + r.push(`${He} is`); + r.push(App.UI.DOM.makeElement("span", `terrified`, ["trust", "dec"])); + r.push(`that ${he}'ll ultimately be reduced to nothing but a disposable fucktoy.`); + slave.devotion -= 8; + slave.trust -= 8; + } + } else if (slave.devotion < -20 && slave.trust < -20) { + if (bigDick) { + r.push(`Being utterly dominated by such a large phallus demands ${his}`); + r.push(App.UI.DOM.makeElement("span", `submission to you,`, ["devotion", "inc"])); + r.push(`but also reinforces the`); + r.push(App.UI.DOM.makeElement("span", `fear`, ["trust", "dec"])); + r.push(`that this is all life is, and will be, for ${him}.`); + slave.devotion += 1; + slave.trust -= 8; + } else { + r.push(`Being chain raped is a`); + r.push(App.UI.DOM.makeElement("span", `horrible experience`, ["devotion", "dec"])); + r.push(`and serves to confirm ${his}`); + r.push(App.UI.DOM.makeElement("span", `fears`, ["trust", "dec"])); + r.push(`of what it means to be a slave.`); + slave.devotion -= 8; + slave.trust -= 8; + } + } else if (slave.energy > 95) { + r.push(`${He}'s as horny as you and naturally`); + r.push(App.UI.DOM.makeElement("span", `draws closer`, ["devotion", "inc"])); + r.push(`to anyone able to keep up with ${his} sex drive; ${he} understands that ${he} can`); + r.push(App.UI.DOM.makeElement("span", `trust in you`, ["trust", "inc"])); + r.push(`to satisfy ${his} needs, even it it's only for your own sake.`); + slave.energy = Math.clamp(slave.energy + 1, 0, 100); + slave.devotion += 6; + slave.trust += 6; + } else if (slave.devotion > 20) { + if (slave.energy > 60) { + r.push(`While it may be a bit more often than ${he}'d like, ${he} is`); + r.push(App.UI.DOM.makeElement("span", `happy`, ["devotion", "inc"])); + r.push(`that you find ${him} useful, and`); + r.push(App.UI.DOM.makeElement("span", `pleased`, ["trust", "inc"])); + r.push(` to see that you're willing to keep going until ${he} is satisfied as well. Getting fucked all the time`); + r.push(App.UI.DOM.makeElement("span", `builds ${his} already healthy libido`, ["libido", "inc"])); + r.push(`as ${his} body grows accustomed to the non-stop sex.`); + slave.energy = Math.clamp(slave.energy + 2, 0, 100); + slave.devotion += 3; + slave.trust += 5; + } else if (tinyDick) { + r.push(`While ${he} is`); + r.push(App.UI.DOM.makeElement("span", `pleased`, ["devotion", "inc"])); + r.push(`to be of use to you, ${he} can't help but`); + r.push(App.UI.DOM.makeElement("span", `find you unthreatening`, ["trust", "inc"])); + r.push(`when you have such a meager tool.`); + slave.devotion += 1; + slave.trust += 3; + } else if (bigDick && slave.sexualQuirk !== "size queen") { + r.push(`Being constantly filled with your dick is overwhelming, ${he} can do nothing but`); + r.push(App.UI.DOM.makeElement("span", `submit`, ["devotion", "inc"])); + r.push(`${himself} to you.`); + slave.devotion += 3; + } else { + r.push(`While it may be a bit much, ${he} is`); + r.push(App.UI.DOM.makeElement("span", `happy`, ["devotion", "inc"])); + r.push(`to help you stay in control of yourself.`); + slave.devotion += 2; + } + } else if (slave.trust > 20) { + if (slave.energy > 80) { + r.push(`While it may be a bit more often than ${he} wants, ${he}`); + r.push(App.UI.DOM.makeElement("span", `appreciates`, ["trust", "inc"])); + r.push(`your efforts in keeping ${him} satisfied; ${he} finds ${himself} starting to`); + r.push(App.UI.DOM.makeElement("span", `warm up`, ["devotion", "inc"])); + r.push(`to you. Getting fucked all the time`); + r.push(App.UI.DOM.makeElement("span", `builds ${his} already healthy libido`, ["libido", "inc"])); + r.push(`as ${his} body grows accustomed to the non-stop sex.`); + slave.energy = Math.clamp(slave.energy + 2, 0, 100); + slave.devotion += 2; + slave.trust += 2; + } else if (tinyDick) { + r.push(`${He} quickly realizes that you're so small ${he} can tolerate being fucked all the time by you. ${He}'s`); + r.push(App.UI.DOM.makeElement("span", `appalled`, ["devotion", "dec"])); + r.push(`by the thought, but feels like you'll`); + r.push(App.UI.DOM.makeElement("span", `scrutinize ${him} less`, ["trust", "inc"])); + r.push(`if ${he} gives you what you want.`); + slave.devotion -= 2; + slave.trust += 6; + } else if (bigDick && slave.sexualQuirk !== "size queen") { + r.push(`Being constantly filled with your dick helps to wear down ${his} defiant streak. ${He} realizes that ${he} is`); + r.push(App.UI.DOM.makeElement("span", `slowly losing ${himself} to you;`, ["devotion", "inc"])); + r.push(`a`); + r.push(App.UI.DOM.makeElement("span", `worrisome`, ["trust", "dec"])); + r.push(`prospect.`); + slave.devotion += 2; + slave.trust -= 2; + } else { + r.push(`While it may be a bit more often than ${he} wants, ${he} can't deny that ${he}`); + r.push(App.UI.DOM.makeElement("span", `enjoys`, ["trust", "inc"])); + r.push(`you attending to ${his} needs. What ${he} doesn't realize is ${he} is starting to`); + r.push(App.UI.DOM.makeElement("span", `tolerate`, ["devotion", "inc"])); + r.push(`your company.`); + slave.devotion += 1; + slave.trust += 2; + } + } else { + if (slave.energy > 80) { + r.push(`While it may be a bit more often than ${he} wants, ${he}`); + r.push(App.UI.DOM.makeElement("span", `enjoys`, ["devotion", "inc"])); + r.push(`the time you spend fucking. Even though ${he} can sense`); + r.push(App.UI.DOM.makeElement("span", `${his} urges intensifying,`, ["libido", "inc"])); + r.push(`${he} feels like ${he} can`); + r.push(App.UI.DOM.makeElement("span", `depend on you`, ["trust", "inc"])); + r.push(`to them them in check.`); + slave.energy = Math.clamp(slave.energy + 2, 0, 100); + slave.devotion += 2; + slave.trust += 1; + } else if (tinyDick) { + r.push(`With the constant fuckings, ${he} can't help but be`); + r.push(App.UI.DOM.makeElement("span", `disappointed`, ["devotion", "dec"])); + r.push(`by the size of your dick. ${He} begins to`); + r.push(App.UI.DOM.makeElement("span", `slip into routine,`, ["trust", "inc"])); + r.push(`quickly getting you off so ${he} can get on with ${his} day.`); + slave.devotion -= 1; + slave.trust += 1; + } else if (bigDick && slave.sexualQuirk !== "size queen") { + r.push(`Being constantly full of your dick really helps ${him} to`); + r.push(App.UI.DOM.makeElement("span", `understand`, ["devotion", "inc"])); + r.push(`that ${his} body is being warped for your pleasure, though ${he}'s`); + r.push(App.UI.DOM.makeElement("span", `terrified`, ["trust", "dec"])); + r.push(`that you may grow tired of ${him} and discard your stretched-out fucktoy.`); + slave.devotion += 3; + slave.trust -= 3; + } else { + r.push(`The chain raping forces ${him} to`); + r.push(App.UI.DOM.makeElement("span", `submit`, ["devotion", "inc"])); + r.push(`to your desires, but ${he} can't help but feel`); + r.push(App.UI.DOM.makeElement("span", `disposable.`, ["trust", "dec"])); + slave.devotion += 2; + slave.trust -= 2; + } + } + healthDamage(slave, 5); + slave.health.tired = Math.clamp(slave.health.tired + 10, 0, 100); + if (bigDick) { + r.push(`${He}'s left`); + r.push(App.UI.DOM.makeElement("span", `tired and sore`, ["health", "dec"])); + r.push(`from all the ferocious pounding, but the worst of it has to be the`); + if (canDoVaginal(slave)) { + r.push(App.UI.DOM.makeElement("span", `dull ache`, ["health", "dec"])); + r.push(`at the back of ${his} vagina where your dick kept pummeling ${him}.`); + } else { + r.push(App.UI.DOM.makeElement("span", `dull ache`, ["health", "dec"])); + r.push(`in ${his} rectum where your dick kept pummeling ${him}.`); + } + healthDamage(slave, 5); + } else { + r.push(`By the end of the week, ${he}'s`); + r.push(App.UI.DOM.makeElement("span", `tired and sore`, ["health", "dec"])); + r.push(`from all the ferocious pounding.`); + } + if (!canLift(slave, V.PC)) { + r.push(`${He} was unable to properly support your weight, effectively`); + r.push(App.UI.DOM.makeElement("span", `crushing ${him}`, ["health", "dec"])); + r.push(`beneath you during the frantic sex.`); + healthDamage(slave, 5); + } + if (holeCheck === "vaginal") { + if (slave.vagina === 0) { + r.push(`If ${he} was a virgin,`); + r.push(App.UI.DOM.makeElement("span", `${he} definitely isn't now;`, ["virginity", "loss"])); + r.push(`it wasn't on your mind when you started, and it certainly isn't on ${his} after all the orgasms.`); + slave.vagina += 1; + } else if (bigDick) { + if (slave.vagina === 1) { + r.push(`With how much time you've spent hilted in ${him}, it's not very surprising that ${his} pussy has`); + r.push(App.UI.DOM.makeElement("span", `adapted to your size.`, ["change", "positive"])); + slave.vagina += 1; + } else if (slave.vagina === 2) { + if (V.PC.dick > 4 && random(1, 100) > 80) { + r.push(`With how much ${he} stretches around you each time you thrust into ${him}, it comes of little surprise when ${his} pussy`); + r.push(App.UI.DOM.makeElement("span", `stays opened`, ["change", "positive"])); + r.push(`in anticipation for the next round.`); + slave.vagina += 1; + } + } else if (slave.vagina === 3) { + if (V.PC.dick > 5 && random(1, 100) > 80) { + r.push(`With how much ${he} bulges outwards each time you thrust into ${him}, it comes of little surprise when ${his} pussy`); + r.push(App.UI.DOM.makeElement("span", `stays gaped`, ["change", "positive"])); + r.push(`in anticipation for the next round.`); + slave.vagina += 1; + } + } + } + if (canPenetrate(V.PC)) { + tryKnockMeUp(slave, 100, 0, V.PC); + } + } else { + if (slave.anus === 0) { + r.push(`If ${he} was a anal virgin,`); + r.push(App.UI.DOM.makeElement("span", `you've definetly broken in ${his} backdoor;`, ["virginity", "loss"])); + r.push(`it wasn't on your mind when you started pounding, and it certainly isn't on ${his} with the asspain.`); + slave.anus += 1; + } else if (bigDick) { + if (slave.anus === 1) { + r.push(`With how much time you've spent hilted in ${him}, it's not very surprising that ${his} anus has`); + r.push(App.UI.DOM.makeElement("span", `stretched to better fit your girth.`, ["change", "positive"])); + slave.anus += 1; + } else if (slave.anus === 2) { + if (V.PC.dick > 4 && random(1, 100) > 80) { + r.push(`With how much ${his} anus stretches around you with each thrust, it comes of little surprise when it`); + r.push(App.UI.DOM.makeElement("span", `stays gaped`, ["change", "positive"])); + r.push(`with anticipation for the next round.`); + slave.anus += 1; + } + } else if (slave.anus === 3) { + if (V.PC.dick > 5 && random(1, 100) > 80) { + r.push(`With how much ${his} lower belly bulges outwards with every thrust, it comes of little surprise that ${his} anus`); + r.push(App.UI.DOM.makeElement("span", `stays gaped`, ["change", "positive"])); + r.push(`from how much your girth has stretched ${him}.`); + slave.anus += 1; + } + } + } + if (canPenetrate(V.PC)) { + tryKnockMeUp(slave, 100, 1, V.PC); + } + } + let fuckCount = random(35, 56); + if (getSharedPersonalAttention()) { + fuckCount = Math.trunc(fuckCount / 2); + } + seX(slave, holeCheck, V.PC, "penetrative", fuckCount); + if (V.PC.visualAge < V.minimumSlaveAge && slave.fetish !== Fetish.MINDBROKEN) { + if (slave.behavioralFlaw === "sinful") { + r.push(`${He} may try to deny it, but you can tell ${he}`); + r.push(App.UI.DOM.makeElement("span", `enjoyed`, ["devotion", "inc"])); + r.push(`having sex with an underaged ${girlP}.`); + slave.devotion += 2; + } else if (slave.devotion < 50 && slave.trust < 50) { + r.push(`It's pretty obvious that ${he} was`); + r.push(App.UI.DOM.makeElement("span", `uncomfortable`, ["devotion", "dec"])); + r.push(`being pushed into a sexual situation with an underaged ${girlP}.`); + slave.devotion -= 2; + } + } + // Frantic pounding sets off labor + if (slave.preg > slave.pregData.normalBirth / 1.1111 && slave.pregControl !== "labor suppressors" && slave.broodmother < 1 && !isInLabor(slave)) { + if (WombBirthReady(slave, slave.pregData.normalBirth) > 0) { + startLabor(slave); + } else if (WombBirthReady(slave, slave.pregData.normalBirth / 1.1111) > 0 && (random(1, 100) > 50) && slave.geneMods.progenitor !== 1) { + startLabor(slave); + } + } + } + V.PC.need = 0; + if (V.PC.energy < 100) { + V.PC.energy += 11 - Math.max(Math.round(V.PC.energy / 10), 1); + } + if (canAchieveErection(V.PC) && !canPenetrate(V.PC)) { + // send to clinic/rest + if (V.clinic > App.Entity.facilities.clinic.employeesIDs().size) { + r.push(`${He}'ll be`); + r.push(App.UI.DOM.makeElement("span", `spending some time in ${V.clinicName} recovering,`, ["job", "change"])); + r.push(`so you'll have to find something else to fuck for the time being.`); + r.push(assignJob(slave, Job.CLINIC)); + } else { + r.push(`${He}'ll need to`); + r.push(App.UI.DOM.makeElement("span", `rest and recover`, ["job", "change"])); + r.push(`after being split in half;`); + r.push(App.UI.DOM.makeElement("span", `${his} training assignment has defaulted to caring for ${his} health`, "noteworthy")); + r.push(`so that you may keep an eye on ${him}. You're still pretty horny, though.`); + pa.objective = "health"; + r.push(assignJob(slave, Job.REST)); + } + } else if (!isHorny(V.PC)) { + r.push(`With your libido back under control, you turn your attention to putting ${his} piesces back where they belong;`); + r.push(App.UI.DOM.makeElement("span", `${his} training assignment has defaulted to caring for ${his} health.`, "noteworthy")); + pa.objective = "health"; + } else { + r.push(`While you are managing to keep your libido in check,`); + r.push(App.UI.DOM.makeElement("span", `you still fall steadily deeper into prurience.`, ["libido", "inc"])); + } break; } case "fix behavioral flaw": diff --git a/src/endWeek/saLongTermPhysicalEffects.js b/src/endWeek/saLongTermPhysicalEffects.js index 6ca5a0e660dfbc807b06bd11f05d2416899366e7..4a3ecef7b004bbb5e53dd8d4e42070393a215fb3 100644 --- a/src/endWeek/saLongTermPhysicalEffects.js +++ b/src/endWeek/saLongTermPhysicalEffects.js @@ -530,9 +530,9 @@ App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects } } // Has to come here otherwise runs too late for satiation. - if (V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.some(p => p.ID === slave.ID) && !onBedRest(V.PC, true)) { - const pa = V.personalAttention.slaves.find((s) => s.ID === slave.ID); // This can probably be improved. - if (pa.objective === "spar") { + if (!onBedRest(V.PC, true)) { + const pa = getPersonalAttentionType(slave.ID); + if (pa === "spar") { if (canWalk(V.PC) && canWalk(slave) && hasAnyArms(V.PC) && hasAnyArms(slave) && canSee(slave) && slave.fetish !== "mindbroken") { if (isHorny(V.PC)) { if (slave.energy > 95 || slave.aphrodisiacs > 0 || slave.inflationType === "aphrodisiac") { @@ -540,8 +540,6 @@ App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects } } } - } else if (pa.objective === "ravish") { - slave.need = 0; } } diff --git a/src/endWeek/saReleaseRules.js b/src/endWeek/saReleaseRules.js index 2ac87bfadec6a76331bef0c663309fb0598a757a..6ba91050ed4f204dbeb78f2821a3a5623b4c7104 100644 --- a/src/endWeek/saReleaseRules.js +++ b/src/endWeek/saReleaseRules.js @@ -24,6 +24,9 @@ App.SlaveAssignment.nonAssignmentRelease = function(slave) { } // no fetish effects/discovery here...saServeYourOtherSlaves' subLife will take care of that slave.need = 0; + } else if (!onBedRest(V.PC, true) && ["ravish", "ravished"].includes(getPersonalAttentionType(slave.ID))) { + r.push(`is completely sated by your personal attention and has little interest in seeking additional sexual stimulation.`); + slave.need = 0; } else if (!App.Utils.hasNonassignmentSex(slave) && release.masturbation === 0) { if (release.master === 1) { const toYou = assignmentVisible(slave) ? `to you` : `up to the penthouse`; diff --git a/src/events/intro/pcAppearance.js b/src/events/intro/pcAppearance.js index b5bef1fd459b39b3e6cfd15dee381b4082eb928d..531cd4e961fc6ab51d09859a97a92ef93ba99338 100644 --- a/src/events/intro/pcAppearance.js +++ b/src/events/intro/pcAppearance.js @@ -317,6 +317,11 @@ App.UI.Player.appearance = function(options, summary = false) { if (V.PC.dick === 0 && V.PC.physicalAge > 13) { options.addOption("Your clit is", "clit", V.PC) .addValueList([["Normal", 0], ["Large", 1], ["Huge", 2]]); + options.addOption("It is", "foreskin", V.PC) + .addValueList([ + ["Exposed by a circumcision", 0] + ["Covered by a hood", 1], + ]) } if (V.PC.physicalAge <= 18) { options.addOption("You are", "vagina", V.PC) @@ -464,6 +469,9 @@ App.UI.Player.syncAgeBasedParameters = function() { V.PC.pubertyXY = 1; } } + if (V.PC.dick === 0 && V.PC.vagina >= 0) { + V.PC.foreskin = 1; + } if (V.PC.boobs < 250) { V.PC.nipples = "tiny"; } else if (V.PC.boobs < 1000) { diff --git a/src/events/scheduled/burst/burst.js b/src/events/scheduled/burst/burst.js index cd54aefeaefcf8e0882da38fc1256938e242c412..dd69d85f40b068d64cdd00113075281e4e648e89 100644 --- a/src/events/scheduled/burst/burst.js +++ b/src/events/scheduled/burst/burst.js @@ -20,6 +20,8 @@ App.Events.SEBurst = class SEBurst extends App.Events.BaseEvent { node.append(birth(slave, {artRenderer})); } else if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) { node.append(torture(slave)); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) { + node.append(ravish(slave)); } else { node.append(pop(slave)); } @@ -77,7 +79,7 @@ App.Events.SEBurst = class SEBurst extends App.Events.BaseEvent { if (artRenderer) { App.UI.DOM.drawOneSlaveRight(el, slave, artRenderer); } - r.push(`${slave.slaveName} belly is positively bursting`); + r.push(`${slave.slaveName}'s belly is positively bursting`); if (slave.inflation !== 0) { r.push(`with ${slave.inflationType},`); } else { @@ -95,6 +97,47 @@ App.Events.SEBurst = class SEBurst extends App.Events.BaseEvent { return el; } + /** + * + * @param {App.Entity.SlaveState} slave + * @returns {DocumentFragment} + */ + function ravish(slave) { + const el = new DocumentFragment(); + const r = []; + const { + he, his, him + } = getPronouns(slave); + if (artRenderer) { + App.UI.DOM.drawOneSlaveRight(el, slave, artRenderer); + } + r.push(`Fucking ${slave.slaveName} with ${his} overfilled`); + if (slave.inflation !== 0) { + r.push(slave.inflationType); + } + r.push(`belly bouncing around every which way is a blast, though ${he} begins to wince and groan more than usual as the week nears its end. As you finish up a particularly intense`); + if (canAchieveErection(V.PC)) { + r.push(`session by blowing a huge load into ${him}, you notice ${his} belly slowly starting to swell. As you ponder this development with a few extra thrusts to get out that last bit of cum, ${his} middle bursts beneath you, sending you crashing onto ${his} lifeless body from the sudden shift and into a pool of`); + if (slave.inflation !== 0) { + r.push(`blood, guts and ${slave.inflationType}.`); + } else { + r.push(`blood and guts.`); + } + r.push(`That was not what you expected to happen, and you probably shouldn't keep humping what's left of ${him} instead of cleaning up.`); + } else { + r.push(`session, you can't help but notice ${his} belly slowly starting to swell; an oddity, given you aren't unloading anything into ${him}. You ponder this development as you shift ${him} into a favorable position for another round, only to have ${his} middle burst on top of you, covering you with a deluge of`); + if (slave.inflation !== 0) { + r.push(`blood, guts and ${slave.inflationType}.`); + } else { + r.push(`blood and guts.`); + } + r.push(`You lay there, stunned and holding ${his} corpse upright over you, dumbfounded by what just happened.`); + } + el.append(r.join(" ")); + el.append(horrifiedSlaves(slave)); + return el; + } + function sectionBreak() { const hr = document.createElement("hr"); hr.style.margin = "0"; diff --git a/src/gui/storyCaption.js b/src/gui/storyCaption.js index 6cab85272a7a68b4e56345715634b47144f3082e..f033a1131bd7a816d3f23523546a656ebaa981cd 100644 --- a/src/gui/storyCaption.js +++ b/src/gui/storyCaption.js @@ -20,6 +20,9 @@ App.UI.StoryCaption.render = function() { if (V.event instanceof App.Events.BaseEvent) { App.UI.DOM.appendNewElement("div", fragment, V.event.eventName); } + if (V.debugMode) { + App.UI.DOM.appendNewElement("div", fragment, playerConsistencyCheck()); + } } fragment.append(week()); diff --git a/src/js/birth/birth.js b/src/js/birth/birth.js index cae2738ff836b97c9fc6d8aaf0ce93e9169d3d43..32004166b0abf9d91ecc8f63f2e1c01b299f2065 100644 --- a/src/js/birth/birth.js +++ b/src/js/birth/birth.js @@ -3992,6 +3992,53 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen // add extra events here (moving between jobs | after work) if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) { r.push(`${He}'s given birth during your torture sessions enough times for you to start making games of it; perhaps you see how hard you can hit ${him} before you cause ${his} water to break, or maybe you try to break it yourself. The best part is, no matter how many come out of ${him}, ${he} never loses that exploitable baby bump.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) { + if (random(1, 20) > suddenBirth) { + r.push(`You take a break from fucking ${him} to allow ${him} time to birth ${his} ${firstText} baby. Once the child is sent off, you conclude your break and go back to fucking ${his}`); + if (canDoVaginal(slave)) { + if (slave.mpreg === 0) { + r.push(`sore, gaping`); + } + r.push(`pussy`); + } else { + if (slave.mpreg === 1) { + r.push(`sore, gaping buttpussy`); + } else { + r.push(`anus`); + } + } + r.push(`while caressing the turgid swell of ${his}, still very baby-filled, middle.`); + } else { + if (canDoVaginal(slave) && slave.mpreg === 0) { + r.push(`You groan in displeasure as you feel the head of ${firstText} baby begins to steadily edge you out of ${his} pussy. You sigh and resort to masturbating until the brat is fully born and sent away so you can get back to fucking ${his} turgid body until you inevitably send ${him} back into labor and this all repeats again.`); + } else if (canDoVaginal(slave)) { + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`You moan with pleasure as the pressure of ${firstText} baby moving through ${his} rectum pushes down against your ${V.PC.clit >= 3 ? "clit" : "dick"} making everything feel so wonderfully tight. In fact, maybe too tight; you struggle to extract yourself from the clenching orifice before you find your tool painfully crushed. With a stimulating pop, you pull out just as ${his} baby slips from ${his} rectum, climaxing in the`); + if (isVirile(V.PC)) { + r.push(`process and christening it in a shower of cum.`); + } else { + r.push(`process.`); + } + r.push(`Once ${he}'s cleaned up and the baby is taken care of, you bend ${him} back over, caressing the turgid swell of ${his} still baby-filled middle in the process, and carry on fucking ${him}.`); + } else { + r.push(`You grunt in displeasure as the pressure of ${firstText} baby moving through ${his} rectum pushes down on your strap-on and traps it in place. You try to wiggle it loose, but it just won't budge. You sigh and catch ${his} baby as it pops out of ${his} butthole before handing it off and evaluating just how crushed your favorite toy is.`); + } + } else if (canDoAnal(slave) && slave.mpreg === 1) { + r.push(`You groan in displeasure as you feel the head of ${firstText} baby begins to steadily blockade ${his} anus from your penetration. You sigh and resort to masturbating until the brat is fully born and sent away so you can get back to fucking ${his} turgid body until you inevitably send ${him} back into labor and this all repeats again.`); + } else { + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`You moan with pleasure as the pressure of ${firstText} baby being born forces ${his} rectum to tighten around your ${V.PC.clit >= 3 ? "clit" : "dick"}. It quickly becomes way too tight; you struggle to dislodge yourself from the clenching orifice before you get completely crushed. With a stimulating pop, you pull out just as ${his} baby slips from ${his} pussy, climaxing in the`); + if (isVirile(V.PC)) { + r.push(`process and christening it in a shower of cum.`); + } else { + r.push(`process.`); + } + r.push(`Once ${he}'s cleaned up and the baby is taken care of, you bend ${him} back over, caressing the turgid swell of ${his} still baby-filled middle in the process, and carry on fucking ${him}.`); + } else { + r.push(`You grunt in displeasure as the pressure of ${firstText} baby moving through ${his} birth canal pushes down on your strap-on and traps it in place. You try to wiggle it loose, but it just won't budge. You sigh and catch ${his} baby as it pops out of ${his} vagina before handing it off and evaluating just how crushed your favorite toy is.`); + } + } + } } else if (!canWalk(slave)) { if (slave.fetish === Fetish.MINDBROKEN) { if (random(1, 20) > suddenBirth) { @@ -4904,6 +4951,53 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen // add extra events here (moving between jobs | after work) if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) { r.push(`${He}'s given birth during your torture sessions enough times for you to start making games of it; perhaps you see how hard you can hit ${him} before you cause ${his} water to break, or maybe you try to break it yourself. If you time it right, it's even possible to force ${him} to pop out two babies at once! The best part is, no matter how many come out of ${him}, ${he} never loses the huge target that is ${his} gravid middle.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) { + if (random(1, 20) > suddenBirth) { + r.push(`The constant fucking has a bad habit of sending ${him} into labor, forcing you to stop and allow ${him} a moment to pop out the child. Once it is sent off, you conclude your break and go back to fucking ${his}`); + if (canDoVaginal(slave)) { + if (slave.mpreg === 0) { + r.push(`sore, gaping`); + } + r.push(`pussy`); + } else { + if (slave.mpreg === 1) { + r.push(`sore, gaping buttpussy`); + } else { + r.push(`anus`); + } + } + r.push(`while enjoying the agitated movements emanating from ${his} brood trapped beneath you.`); + } else { + if (canDoVaginal(slave) && slave.mpreg === 0) { + r.push(`You groan in displeasure as you feel yourself starting to be edged out of ${his} pussy by another of ${his} brood being born. You sigh and resort to masturbating until the brat is fully born and sent away so you can get back to fucking ${his} baby-stuffed body until you inevitably send ${him} back into labor and this all repeats again.`); + } else if (canDoVaginal(slave)) { + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`You moan with pleasure at the pressure of another of ${his} brood begining to move through ${his} rectum. The feeling of it pushing down against your ${V.PC.clit >= 3 ? "clit" : "dick"} makes everything feel so wonderfully tight. In fact, maybe too tight; you struggle to extract yourself from the clenching orifice before you find your tool painfully crushed. With a stimulating pop, you pull out just as ${his} baby slips from ${his} rectum, climaxing in the`); + if (isVirile(V.PC)) { + r.push(`process and christening it in a shower of cum.`); + } else { + r.push(`process.`); + } + r.push(`Once the baby is taken care of, you bend ${him} back over ${his} massive belly and carry on fucking ${him} in the hopes of triggering another baby to be born.`); + } else { + r.push(`You grunt in displeasure as the pressure of another of ${his} brood slipping into ${his} rectum traps your strap-on in place. You try to wiggle it loose, but it just won't budge. You sigh and catch the baby as it pops out of ${his} butthole before handing it off and evaluating just how crushed your favorite toy is.`); + } + } else if (canDoAnal(slave) && slave.mpreg === 1) { + r.push(`You groan in displeasure as you feel yourself blocked out of ${his} anus by the crowning head of another of ${his} brood. You sigh and resort to masturbating until the brat is fully born and sent away so you can get back to fucking ${his} baby-stuffed body until you inevitably send ${him} back into labor and this all repeats again.`); + } else { + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`You moan with pleasure as the pressure of another of ${his} brood slipping into ${his} birth canal forces ${his} rectum to tighten around your ${V.PC.clit >= 3 ? "clit" : "dick"}. It quickly becomes way too tight; you struggle to dislodge yourself from the clenching orifice before you get completely crushed. With a stimulating pop, you pull out just as ${his} baby slips from ${his} pussy, climaxing in the`); + if (isVirile(V.PC)) { + r.push(`process and christening it in a shower of cum.`); + } else { + r.push(`process.`); + } + r.push(`Once the baby is taken care of, you bend ${him} back over ${his} massive belly and carry on fucking ${him} in the hopes of triggering another baby to be born.`); + } else { + r.push(`You grunt in displeasure as the pressure of another of ${his} brood slipping into ${his} birth canal pushes down on your strap-on and traps it in place. You try to wiggle it loose, but it just won't budge. You sigh and catch ${his} baby as it pops out of ${his} pussy before handing it off and evaluating just how crushed your favorite toy is.`); + } + } + } } else if (!canWalk(slave)) { if (slave.fetish === Fetish.MINDBROKEN) { r.push(`While stroking ${his} pregnancy absentmindedly, ${slave.slaveName}'s body begins to birth another of ${his} brood. ${He} carries on until the contractions drag ${him} onto ${his} swollen belly.`); @@ -5038,6 +5132,21 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen } } else if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true) && random(1, 100) > 50) { r.push(`A little thing like childbirth isn't going to stop you from beating ${him}, however, so you focus your efforts on timing your strikes in-between ${his} contractions, never truly giving ${his} body a chance to rest. You keep at it until ${his} belly is fully deflated and ${his} ${newborns} collected, and once they are, try to find just how much of a gut-punch it takes to dislodge a placenta.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true) && random(1, 100) > 50) { + r.push(`With contractions underway, you take a break from fucking ${him} to allow ${him} the time ${he} needs to birth ${his} ${children}. Once they are sent off and ${he} is cleaned up, you get right back to fucking ${his}`); + if (canDoVaginal(slave)) { + if (slave.mpreg === 0) { + r.push(`sore`); + } + r.push(`pussy`); + } else { + if (slave.mpreg === 1) { + r.push(`sore`); + } else { + r.push(`anus`); + } + } + r.push(`despite ${his} need for rest.`); } else { const animals = []; @@ -5713,6 +5822,21 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen } r.push(`set up on the operating table. ${He} is quickly sedated and subjected to a c-section in order to avoid potential problems. The surgery is quick and ${he} is moved to a bed to recover. When ${he} awakes, ${his} ${slave.pregType > 1 ? `children have` : `child has`} already been taking away.`); } + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true) && random(1, 100) > 50) { + r.push(`With contractions underway, you take a break from fucking ${him} to help ${him} into a position more suitable to birth ${his} ${children}. Once they are sent off and ${he} is cleaned up, you flip ${him} back over and resume fucking ${his}`); + if (canDoVaginal(slave)) { + if (slave.mpreg === 0) { + r.push(`sore`); + } + r.push(`pussy`); + } else { + if (slave.mpreg === 1) { + r.push(`sore`); + } else { + r.push(`anus`); + } + } + r.push(`despite ${his} need for some rest.`); } else { switch (slave.assignment) { case Job.REST: @@ -6082,6 +6206,36 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true) && random(1, 2) === 2) { r.push(`${slave.slaveName} rudely interrupts your torture session by releasing ${his} water all over your office floor. A little thing like childbirth isn't going to stop you from beating ${him}, however, so you focus your efforts on timing your strikes in-between ${his} contractions, never truly giving ${his} body a chance to rest. You keep at it until ${his} belly is fully deflated and ${his} ${newborns} collected, and once they are, try to find just how much of a gut-punch it takes to dislodge a placenta.`); + } else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true) && random(1, 2) === 2) { + if (canDoVaginal(slave) && slave.mpreg === 0) { + r.push(`You groan in displeasure as you feel a head begin to steadily edge you out of ${his} pussy. You sigh and resort to masturbating over ${his} laboring body until ${he} is emptied of ${children} and you can go back to fucking the still gaping hole.`); + } else if (canDoVaginal(slave)) { + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`You moan with pleasure as the pressure of a baby moving through ${his} rectum pushes down against your ${V.PC.clit >= 3 ? "clit" : "dick"} making everything feel so wonderfully tight. In fact, maybe too tight; you struggle to extract yourself from the clenching orifice before you find your tool painfully crushed. With a stimulating pop, you pull out just as the baby begins to crown from ${his} butthole, climaxing in the`); + if (isVirile(V.PC)) { + r.push(`process and christening it in a shower of cum.`); + } else { + r.push(`process.`); + } + r.push(`Once ${he}'s cleaned up and ${his} ${childrenAre} taken care of, you get right back to fucking ${him}.`); + } else { + r.push(`You grunt in displeasure as the pressure of a baby moving through ${his} rectum pushes down on your strap-on and traps it in place. You try to wiggle it loose, but it just won't budge. You sigh and let ${him} finish giving birth from ${his} butthole before handing the ${children} off and evaluating just how badly ${he} managed to crush your toy.`); + } + } else if (canDoAnal(slave) && slave.mpreg === 1) { + r.push(`You groan in displeasure as you feel a head begin to steadily block passage into ${his} anus. You sigh and resort to masturbating over ${his} laboring body until ${he} is emptied of ${children} and you can go back to fucking the still gaping hole.`); + } else { + if (canPenetrate(V.PC) || V.PC.clit >= 3) { + r.push(`You moan with pleasure as the pressure of a baby being born forces ${his} rectum to tighten around your ${V.PC.clit >= 3 ? "clit" : "dick"}. It quickly becomes way too tight; you struggle to dislodge yourself from the clenching orifice before you get completely crushed. With a stimulating pop, you pull out just as the baby crowns from ${his} pussy, climaxing in the`); + if (isVirile(V.PC)) { + r.push(`process and christening it in a shower of cum.`); + } else { + r.push(`process.`); + } + r.push(`Once ${he}'s cleaned up and ${his} ${childrenAre} taken care of, you get right back to fucking ${him}.`); + } else { + r.push(`You grunt in displeasure as the pressure of a baby moving through ${his} birth canal pushes down on your strap-on and traps it in place. You try to wiggle it loose, but it just won't budge. You sigh and let ${him} finish giving birth before handing the ${children} off and evaluating just how badly ${he} managed to crush your toy.`); + } + } } else if (random(1, 2) === 1 && canWalk(slave)) { // at assignment else in halls/etc, only if able to move diff --git a/src/js/personalAttentionFunctions.js b/src/js/personalAttentionFunctions.js index 5483eed7e4a528880ace4efc57e45e97f4c0fc22..ce52d459b859907d0f759967cbbf43ccde7e9995 100644 --- a/src/js/personalAttentionFunctions.js +++ b/src/js/personalAttentionFunctions.js @@ -42,8 +42,10 @@ App.PersonalAttention.update = function(input) { return "spar"; case "explore her sexuality": return "explore sexuality"; - case "fuck her senseless": + case "manage your libido": return "ravish"; + case "get fucked senseless": + return "ravished"; case "torture her": return "torture"; } @@ -88,7 +90,9 @@ App.PersonalAttention.getText = function(objective, slave) { case "explore sexuality": return `explore ${his} sexuality`; case "ravish": - return `fuck ${him} senseless`; + return `manage your libido`; + case "ravished": + return `sate your urges`; case "torture": return `torture ${him}`; } @@ -110,6 +114,7 @@ globalThis.getPersonalAttention = function(ID, objective = null) { return ((V.personalAttention.slaves[0].ID === ID && V.personalAttention.slaves[0].objective === objective) || (V.personalAttention.slaves[1]?.ID === ID && V.personalAttention.slaves[1]?.objective === objective)); } } + return false; }; globalThis.getPersonalAttentionType = function(ID) { @@ -124,3 +129,11 @@ globalThis.getPersonalAttentionType = function(ID) { } return "none"; }; + +globalThis.getSharedPersonalAttention = function() { + if (typeof V.personalAttention.slaves === "undefined") { + return "false"; + } else { + return V.personalAttention.slaves[0].objective === V.personalAttention.slaves[1]?.objective; + } +}; \ No newline at end of file diff --git a/src/js/utilsPC.js b/src/js/utilsPC.js index 2f18d167e8f575601f86a6a4cdf02d46be985be4..2a3eb99e4361bfb83fcf58247d6e4206335adbf7 100644 --- a/src/js/utilsPC.js +++ b/src/js/utilsPC.js @@ -932,6 +932,50 @@ globalThis.isHinderedDegree = function(actor, sexyTime = false) { return Math.max(.25, mult); }; +/** For event consistency. Returns the expected state of the player on the sidebar if debug mode is on. + * @param {App.Entity.PlayerState} actor + * @returns {string} + */ +globalThis.playerConsistencyCheck = function(actor = V.PC) { + let r; + if (onBedRest(actor)) { + if (onBedRest(actor, true)) { + if (!isMovable(actor)) { + return "Bedbound"; + } else if (isTrapped(actor)) { + r = "Roombound"; + if (!canWalk(actor)) { + r += "+Wheelchair"; + } + if (isHindered(actor)) { + r += "+Hindered"; + } + return r; + } else { + r = "Bedrest"; + if (!canWalk(actor)) { + r += "+Wheelchair"; + } + if (isHindered(actor)) { + r += "+Hindered"; + } + } + } else { + return "Incapacitated"; + } + } else if (!canWalk(actor)) { + r = "Wheelchair"; + if (isHindered(actor)) { + r += "+Hindered"; + } + return r; + } else if (isHindered(actor)) { + return "Hindered"; + } else { + return "Unhindered"; + } +} + /** Returns if the player can eat solid food. * Consider moving this to encompass slaves in the future. * @param {App.Entity.PlayerState} actor @@ -950,6 +994,23 @@ globalThis.canEatFood = function(actor) { return true; }; +/** Returns if the player is thinking with their genitals. + * Mainly for use in events and personal attention. + * Intented to allow ravishing a slave to give you mental clarity at the cost of making the problem worse in the long run. + * @param {App.Entity.PlayerState} actor + * @returns {boolean} + */ +globalThis.isPlayerLusting = function(actor = V.PC) { + if (isHorny(actor)) { + if (getPersonalAttention(null, "ravish") || getPersonalAttention(null, "ravished")) { + return false; + } else { + return true; + } + } + return false; +}; + /** * 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/player/personalAttentionSelect.js b/src/player/personalAttentionSelect.js index 0d9f8514599153d0373dadbf57d0d9520f72d3c2..22f0fa2d320188b92228ef40ff2dfdaa6b0763b4 100644 --- a/src/player/personalAttentionSelect.js +++ b/src/player/personalAttentionSelect.js @@ -578,11 +578,30 @@ App.UI.Player.personalAttention = function() { App.UI.DOM.appendNewElement("h3", div, `Change training objective`); // HORNY - /* if (isHorny(V.PC)) { - links.push(attentionLink(i, `Fuck ${him} senseless`, "ravish")); + if (canDoAnal(slave) || canDoVaginal(slave)) { + if (canAchieveErection(V.PC) || V.PC.clit >= 3) { + links.push(attentionLink(i, `Sate your lust in ${him}`, "ravish")); + } else if (V.PC.vagina >= 0) { + links.push(attentionLink(i, `Sate your lust in ${him} using a double-ended dildo`, "ravish")); + } else if (V.PC.dick > 0) { + links.push(App.UI.DOM.disabledLink(`Sate your lust in ${him}`, [ + `You want to ravish ${him}, but you can't get it up. What bullshit!` + ])); + } + } + /* + if (V.PC.vagina >= 0 || (slave.toyHole === "dick" || V.policies.sexualOpenness === 1)) { + if (canPenetrate(slave)) { + links.push(attentionLink(i, `Get fucked until you're satisfied`, "ravished")); + } else if (!canAchieveErection(slave) && slave.dick > 0) { + links.push(App.UI.DOM.disabledLink(`Get fucked until you're satisfied`, [ + `You need dick, but ${his} is completely worthless!` + ])); + } + } + */ } - */ // Devotion App.Events.addNode(div, [