diff --git a/CHANGELOG.md b/CHANGELOG.md index 63555dfdc585fbe1f8e63cad9788325ad2a9acec..d0603fa3b05fd8d884914eee994f882036046783 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## Unreleased +## 0.10.7.1-4.0.0-alpha.18 - 2022-08-26 + * added player drugs +* added player health +* added Doctor Consultation for all your health and drug needs * added player salon +* genePool player object record +* Chattel religionist "Holy Nudism" policy +* chooses own clothing now slightly less restrictive wth Chattel religionist * RA simple mode * RA can now report which rule made a change * New Game++ (Start in new arcology at same week.) diff --git a/js/003-data/constants.js b/js/003-data/constants.js index f467d715bdef265f5a43ad182375331e472a6224..077f6a4c7e26690fc47be4e96dd09b8362ccee64 100644 --- a/js/003-data/constants.js +++ b/js/003-data/constants.js @@ -87,6 +87,7 @@ globalThis.PersonalAttention = Object.freeze({ DEVELOPMENT: 'development project', TECH: 'technical accidents', SEX: 'sex', + RELAX: 'rest and relaxation', PROCLAMATION: 'proclamation', TRAINING: 'slave training', }); diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js index a7d824c32f002781ac6a44e5bb07d7f304c062a2..1de0ba85f1d3ccd6f00dd372d0ef47410543f4de 100644 --- a/src/002-config/fc-version.js +++ b/src/002-config/fc-version.js @@ -1,6 +1,6 @@ App.Version = { base: "0.10.7.1", // The vanilla version the mod is based off of, this should never be changed. - pmod: "4.0.0-alpha.17", + pmod: "4.0.0-alpha.18", commitHash: null, release: 1178, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. }; diff --git a/src/endWeek/economics/persBusiness.js b/src/endWeek/economics/persBusiness.js index 769e4eca39cea279e11fb0dabea41a6dd86ff183..91dc5b53e669e8bae694741894774423556409c4 100644 --- a/src/endWeek/economics/persBusiness.js +++ b/src/endWeek/economics/persBusiness.js @@ -61,16 +61,8 @@ App.EndWeek.personalBusiness = function() { } } } - if (V.PC.health.shortDamage >= 30) { - endWeekHealthDamage(V.PC); - r.push(`The injuries received in the recent battle prevents you from engaging in tiring endeavors.`); - if (V.PC.health.shortDamage >= 51) { - r.push(`Your trusted physician believes it will still take a few weeks to fully recover.`); - } else if (V.PC.health.shortDamage >= 39) { - r.push(`You are starting to feel better. It's very likely you will be back to full working order within the next week.`); - } else { - r.push(`You have finally recovered from your injuries.`); - } + if (onBedRest(V.PC, true) && V.PC.dick < -4000) { // Impossible condition to prevent scope creep. Need to finish this later, not right now. + r.push(`You can't tend to your personal affairs right now. Why? You'll find out when this stops being a placeholder.`); } else if (V.personalAttention.task === PersonalAttention.WHORING) { income = random(2000, 4500); if (V.PC.belly >= 1500) { diff --git a/src/endWeek/economics/personalNotes.js b/src/endWeek/economics/personalNotes.js index 14cfb95440b4314dc767d3b2cdce4cc87d9e5884..307d97a6db21477cb5b6838df5abe69ad4dd46dd 100644 --- a/src/endWeek/economics/personalNotes.js +++ b/src/endWeek/economics/personalNotes.js @@ -59,11 +59,10 @@ App.EndWeek.personalNotes = function() { } r.push(App.EndWeek.Player.drugs()); - // Here or at the start? if (V.useTabs === 1) { App.UI.DOM.appendNewElement("h2", el, `Health`); } - //r.push(App.EndWeek.Player.health()); + r.push(App.EndWeek.Player.health()); App.Events.addParagraph(el, r); return el; diff --git a/src/endWeek/healthFunctions.js b/src/endWeek/healthFunctions.js index 786c67886632c4422c9f56752ec0fe400ea85c9b..c94b078f411215f03ecfd21e490996dcd502eae7 100644 --- a/src/endWeek/healthFunctions.js +++ b/src/endWeek/healthFunctions.js @@ -167,6 +167,13 @@ globalThis.illness = function(slave) { r += ` ${He} has <span class="health dec">caught ${addA(sicknessDegree[H.illness])}</span> from ${his} ${relationshipTerm(rel)} ${rel.slaveName}.`; } } + } else if (H.illness === 0 && slave.relationship === -3) { + if (V.PC.health.illness > 1) { + if (catchesIllness(10)) { + H.illness = V.PC.health.illness - 1; // reduced severity + r += ` ${He} has <span class="health dec">caught ${addA(sicknessDegree[H.illness])}</span> from you.`; + } + } } // or she might catch something from a sick coworker const job = App.Utils.jobForAssignment(slave.assignment); @@ -180,6 +187,14 @@ globalThis.illness = function(slave) { } } } + if (H.illness === 0 && [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(slave.assignment)) { + if (V.PC.health.illness > 1) { + if (catchesIllness(20)) { + H.illness = V.PC.health.illness - 1; // reduced severity + r += ` ${He} has <span class="health dec">caught ${addA(sicknessDegree[H.illness])}</span> from you.`; + } + } + } } } else if (H.illness > 0) { if (jsRandom(1, 100) > 75 && H.illness === 1 && curativesBonus < 2 && slave.assignment !== Job.CLINIC && V.week > 8) { @@ -206,11 +221,13 @@ globalThis.canCatchIllness = function(slave) { if (slave.health.illness > 0) { // already sick return false; } - if (slave.curatives === 1 || slave.inflationType === "curative") { // on preventatives, or inflated with curatives - return false; - } - if (slave.assignment === Job.CLINIC) { // slaves in the clinic are monitored - return false; + if (slave.ID !== -1) { + if (slave.curatives === 1 || slave.inflationType === "curative") { // on preventatives, or inflated with curatives + return false; + } + if (slave.assignment === Job.CLINIC) { // slaves in the clinic are monitored + return false; + } } return true; }; @@ -303,12 +320,15 @@ globalThis.nurseEffectiveness = function(slave) { */ globalThis.endWeekHealthDamage = function(slave) { const H = slave.health; + let illnessToCondition = 0; let chemToShort = 0; + let chemToLong = 0; + let shortRecovery = 0; let shortToCondition = 0; let shortToLong = 0; // Checking if we are dealing with the player - // Player does not make use of most things slaves deal with, only short to long term damage + // Player is the testbed for a new long/short damage system if (slave.ID !== -1) { // dealing with carcinogens // They decay naturally at a rate of 10%, but at as they decay cause short term damage @@ -331,45 +351,115 @@ globalThis.endWeekHealthDamage = function(slave) { if (slave.birthWeek === 0 && slave.physicalAge > 29) { H.longDamage += Math.trunc((slave.physicalAge - 25 + jsRandom(1, 15)) / 20); } - } else if (H.condition < 100) { // The player gets an automatic 5 condition recovery each weak up to 100 - H.condition = Math.min(H.condition + 5, 100); - } - // recovering and transferring short term damage to condition and long term - if (H.shortDamage > 0) { - shortToCondition += Math.max(Math.trunc(H.shortDamage * 0.5), 1); // 50% of short term damage gets transferred - H.shortDamage -= shortToCondition; - const assignment = slave.ID !== -1 ? asSlave(slave).assignment : null; - if (assignment === Job.CLINIC) { - H.shortDamage = Math.trunc(H.shortDamage * 0.5); // An additional 50% of short term damage reduction (75% total) for getting treatment in the clinic - } else if (assignment === Job.REST || assignment === Job.SPA) { - H.shortDamage = Math.trunc(H.shortDamage * 0.75); // An additional 25% of short term damage reduction (62.5% total) for resting - } - if (slave.curatives > 0 || slave.ID === -1) { // transferred damage is half if on preventatives/curatives or target is the player - shortToCondition = Math.trunc(shortToCondition * 0.5); + // recovering and transferring short term damage to condition and long term + if (H.shortDamage > 0) { + shortToCondition += Math.max(Math.trunc(H.shortDamage * 0.5), 1); // 50% of short term damage gets transferred + H.shortDamage -= shortToCondition; + const assignment = slave.ID !== -1 ? asSlave(slave).assignment : null; + if (assignment === Job.CLINIC) { + H.shortDamage = Math.trunc(H.shortDamage * 0.5); // An additional 50% of short term damage reduction (75% total) for getting treatment in the clinic + } else if (assignment === Job.REST || assignment === Job.SPA) { + H.shortDamage = Math.trunc(H.shortDamage * 0.75); // An additional 25% of short term damage reduction (62.5% total) for resting + } + if (slave.curatives > 0 || slave.ID === -1) { // transferred damage is half if on preventatives/curatives or target is the player + shortToCondition = Math.trunc(shortToCondition * 0.5); + } + if (assignment === Job.CLINIC) { + shortToCondition = Math.trunc(shortToCondition * 0.75); + } + shortToLong += Math.trunc(shortToCondition * 0.1); // 10% of transferred damage gets added to long term damage, minimum of 20 short term damage before any long term damage is accumulated + H.longDamage += shortToLong; } - if (assignment === Job.CLINIC) { - shortToCondition = Math.trunc(shortToCondition * 0.75); + if (V.baseDifficulty === 1) { // Reducing longDamage up to a certain point depending on the difficulty + if (H.longDamage > 0) { + H.longDamage -= Math.min(Math.trunc(H.longDamage * 0.1), 1); + } + } else if (V.baseDifficulty === 2) { + if (H.longDamage > 20) { + H.longDamage -= Math.min(Math.trunc((H.longDamage - 20) * 0.1), 1); + } + } else if (V.baseDifficulty === 3) { + if (H.longDamage > 40) { + H.longDamage -= Math.min(Math.trunc((H.longDamage - 40) * 0.1), 1); + } + } else if (V.baseDifficulty === 4) { + if (H.longDamage > 60) { + H.longDamage -= Math.min(Math.trunc((H.longDamage - 60) * 0.1), 1); + } } - shortToLong += Math.trunc(shortToCondition * 0.1); // 10% of transferred damage gets added to long term damage, minimum of 20 short term damage before any long term damage is accumulated - H.longDamage += shortToLong; - } - if (V.baseDifficulty === 1) { // Reducing longDamage up to a certain point depending on the difficulty - if (H.longDamage > 0) { - H.longDamage -= Math.min(Math.trunc(H.longDamage * 0.1), 1); + } else { // player + // This is under heavy testing, especially long term damage. Chem contributes to death directly, so it must not overdo it through long term damage, while at the same time being something to keep in the back of ones mind when using unhealthy drugs. + + // dealing with illness + // moved ahead of everything else to allow its major short term damage impact to make a bigger splash + if (H.illness > 0) { + illnessToCondition = Math.trunc(Math.pow(H.illness, 1.5) * (1 + H.shortDamage * 0.1) * (Math.max(H.longDamage * 0.01, 1)) + 2); // this needs extensive testing, but a healthy player should fight off the damage better than a weakened one. Every week will hit harder and harder due to damage impacts. + H.condition -= illnessToCondition; // direct change, since we don't want to double dip on damage. + H.shortDamage += Math.trunc(Math.pow(H.illness, 1.52) * 3 + 2); // 5, 10, 17, 26, 36 points of damage per respective level of illness + if (H.illness > 4) { + H.longDamage++; + } } - } else if (V.baseDifficulty === 2) { - if (H.longDamage > 20) { - H.longDamage -= Math.min(Math.trunc((H.longDamage - 20) * 0.1), 1); + + // dealing with carcinogens + // slave food aids in neutralization. + // They decay naturally at a rate of 10%, but at as they decay cause short term damage, + // and 1%, rounded down, to long term damage + // Without it, it linearly slowly decays, adds 5% to short term damage, and 1%, rounded down, to long term damage + if (slave.chem > 0) { + if (!canEatFood(slave)) { + if (slave.chem > 10) { + chemToShort += Math.max(Math.trunc(slave.chem * 0.1), 1); + } else if (slave.chem > jsRandom(0, 9)) { + chemToShort += 1; + } + slave.chem -= chemToShort; + H.shortDamage += Math.max(Math.trunc(chemToShort * 0.1), 2); + chemToLong += Math.floor(slave.chem * 0.01); + H.longDamage += chemToLong; + } else { + slave.chem = Math.clamp(slave.chem - 0.2, 0, 1000); // note that it lingers, causing issues + chemToShort += Math.max(Math.trunc(slave.chem * 0.05), 1); + H.shortDamage += chemToShort; + chemToLong += Math.trunc(slave.chem * 0.01); + H.longDamage += chemToLong; + } } - } else if (V.baseDifficulty === 3) { - if (H.longDamage > 40) { - H.longDamage -= Math.min(Math.trunc((H.longDamage - 40) * 0.1), 1); + + // recovering and converting short term damage to long term + if (H.shortDamage > 0) { + // short term damage reduces at a constant rate + // 40+ long term damage begins to harm short term recovery + // at 360+, you're ability to heal properly is completely crippled + // but, keep in mind, that short and long damage do not directly influence health, sans illness + shortRecovery += 10 - Math.trunc(H.longDamage * 0.025); + shortRecovery = Math.max(shortRecovery, 1); + if (V.personalAttention.task === PersonalAttention.RELAX) { + shortRecovery += 5; + } + if (V.PC.diet === "medicinal") { + shortRecovery += 5; + } + H.shortDamage = Math.Max(H.shortDamage - shortRecovery, 0); + // short term damage begins converting to long term damage at 20+ + shortToLong += Math.trunc(H.shortDamage * 0.1); + H.longDamage += shortToLong; } - } else if (V.baseDifficulty === 4) { - if (H.longDamage > 60) { - H.longDamage -= Math.min(Math.trunc((H.longDamage - 60) * 0.1), 1); + + // Reducing longDamage for easier difficulties + if (H.longDamage > 0) { + if (V.baseDifficulty === 1) { + H.longDamage -= 0.3; + } else if (V.baseDifficulty === 2) { + H.longDamage -= 0.1; + } + H.longDamage = Math.max(H.longDamage, 0); } + + // The player gets an automatic 5 condition recovery each week up to 100 + // relaxation and diet is handled in its respective locations + H.condition = Math.min(H.condition + 5, 100); } if (V.disableLongDamage) { H.longDamage = 0; diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js index 9b5de0796a742874efef541aad19117f9bfcfb44..0c1c8b3d6fee1597126502e6e79261401a439824 100644 --- a/src/endWeek/nextWeek/nextWeek.js +++ b/src/endWeek/nextWeek/nextWeek.js @@ -320,6 +320,10 @@ App.EndWeek.nextWeek = function() { V.pSurgery.nursePreg = -3; } } + + if (V.doctor.state > 1) { + V.doctor.state = 1; + } // advance the event queue if (V.eventQueue[0] && V.eventQueue[0].length > 0) { diff --git a/src/endWeek/player/playerReportUtils.js b/src/endWeek/player/playerReportUtils.js index 91f17062db26afb587286b3cecd6fb1d79e7eab7..075c9f45e00765a734d67d081efc478db64ebe75 100644 --- a/src/endWeek/player/playerReportUtils.js +++ b/src/endWeek/player/playerReportUtils.js @@ -1,3 +1,6 @@ +// I'm thinking of tearing this out of the pregnancy breast growth and instead taking a start point and an end point and then reporting a summation of any noteworthy changes after the physical block of the week. +// Weight would also be relevant for this. +// Maybe even height on growth drugs? App.EndWeek.Player.bustUp = function(PC, oldCupSize) { let outcome = ""; diff --git a/src/endWeek/player/prDrugs.js b/src/endWeek/player/prDrugs.js index 4c04dd6361456a6e291029a369e8fb1d4a9b26d4..8b6ddbb7e78dcb575121bb0537dc315240bcfd66 100644 --- a/src/endWeek/player/prDrugs.js +++ b/src/endWeek/player/prDrugs.js @@ -61,6 +61,10 @@ App.EndWeek.Player.drugs = function(PC = V.PC) { case "hormone enhancers": r.push(`Your drug regime prepares your body to accept hormonal effects.`); break; + case "hip wideners": + r.push(`The tablets aid your body with preparing for childbirth, at the cost of <span class="health dec">leaving you ill</span> from the excess hormones.`); + healthDamage(PC, random(3, 5)) + break; case "priapism agents": if (PC.dick === 0) { r.push(`You have no dick, so priapism agents are useless to you. <span class="noteworthy">You stop taking them.</span>`); @@ -1578,7 +1582,7 @@ App.EndWeek.Player.drugs = function(PC = V.PC) { } else { PC.chem += 10; } - } else if (PC.drugs === "detox pills") { + } else if (PC.drugs === "detox pills" || PC.drugs === "hip wideners") { PC.chem += 2; } if (V.arcologies[0].FSBodyPuristLaw === 0 && V.healthyDrugsUpgrade === 0) { @@ -1811,6 +1815,15 @@ App.EndWeek.Player.drugs = function(PC = V.PC) { PC.drugs = "no drugs"; } break; + case "hip wideners": + if (PC.hips > -2) { + r.push(`Your body has become better suited for childbirth; <span class="noteworthy">you stop taking the hormones.</span>`); + PC.drugs = "no drugs"; + } else if (PC.preg <= 0) { + r.push(`You are no longer pregnant and have no need for wider hips; <span class="noteworthy">you stop taking the hormones.</span>`); + PC.drugs = "no drugs"; + } + break; } if (PC.pregControl !== "none" && PC.pregKnown === 0) { r.push(`You aren't pregnant anymore; <span class="noteworthy">you stop bothering with the labor suppressors.</span>`); diff --git a/src/endWeek/player/prHealth.js b/src/endWeek/player/prHealth.js new file mode 100644 index 0000000000000000000000000000000000000000..b2dd16909e77db42c95660c22a5be546fb736ba1 --- /dev/null +++ b/src/endWeek/player/prHealth.js @@ -0,0 +1,250 @@ +// This file calls functions from /src/endWeek/healthFunctions.js +App.EndWeek.Player.health = function(PC = V.PC) { + const r = []; + const PCH = PC.health; + + PC.chem = Math.clamp(PC.chem - 0.01, 0, 1000); + + illness(); + addiction(); + endWeekHealthDamage(PC); + health(); + + return r.join(" "); + + function illness() { + const sicknessDegree = ["fine", "minor illness", "illness", "bad illness", "severe illness", "life-threatening illness"]; + + if (PCH.illness > 0) { + r.push(`You are`); + if (PCH.illness > 4) { + r.push(`deathly`); + } else if (PCH.illness > 3) { + r.push(`seriously`); + } else if (PCH.illness < 2) { + r.push(`slightly`); + } else { + r.push(`visibly`); + } + r.push(`ill,`); + if (PCH.illness > 1) { + r.push(`limiting your social interactions.`); + } else { + r.push(`but not badly enough to impede your socializing.`); + } + } + + const roll = random(1, 100); // high rolls are good + let bonuses = 20; // bonus for living conditions and skills + if (PC.skill.medicine >= 40) { + bonuses += 10; + } + if (PC.diet === "medicinal") { + bonuses += 10; + } + if (V.personalAttention.task === PersonalAttention.RELAX) { + bonuses += 10; + } + + if (roll < 2 && canCatchIllness(PC)) { // Always a 2% per week base chance of you, even in otherwise-safe conditions, spontaneously catching an illness + getIll(PC); + r.push(`You wake up to a sore throat and a runny nose; <span class="health dec">you've fallen ill.</span>`); + if (PCH.illness > 4) { + r.push(`You can barely move, and as you feel the vomit coming, there is nothing you can do to stop it. When you come back to your senses, you're horrified to discover you've coated yourself in your own disgorged blood.`); + } else if (PCH.illness > 3) { + r.push(`All you manage to do is roll to the side of the bed and vomit all over the floor before having to stop to regain some strength. Moving to clean yourself up is agonizing, and all you want is to go back to bed.`); + } else if (PCH.illness > 2) { + r.push(`It's a struggle to get out of bed, and you barely manage to make it to the bathroom before the vomit escapes you.`); + } else if (PCH.illness > 1) { + r.push(`It's a struggle to get out of bed, but you manage.`); + } else { + r.push(`It doesn't feel that bad, though.`); + } + } else if (roll < 6 && PCH.illness > 0) { // Always a 5% chance of feeling worse + PCH.illness += 1 + Math.trunc((PC.chem / 10 + random(1, 50) + 15) / 100); // Illness progresses with 1, unless chem > 350, then there's a chance for 2 + r.push(`You feel worse by week's end <span class="health dec">as your illness progresses.</span>`); + if (PCH.illness > 5) { + healthDamage(PC, 20 * (PCH.illness - 5)); // Condition penalty for going over maximum illness, very dangerous + PCH.illness = 5; + r.push(`You feel your consciousness start to fade, and the last thing you remember is projectile vomiting a large amount of blood across the room. You awake surrounded by terrified slaves, <span class="health dec">unsure if you are alive or not and unwilling to approach you to find out,</span> lest they risk catching whatever it is that got you.`); + } + } else if (roll > 95 && PCH.illness > 0) { // Always a 5% chance of getting better + PCH.illness -= 1; + if (PCH.illness === 0) { + improveCondition(PC, 5); + r.push(`You feel better; <span class="health inc">it seems you've gotten over what ailed you.</span>`); + } else { + r.push(`You're not feeling yourself yet, but <span class="health inc">your illness has waned</span> slightly.`); + } + } else { + const ageModifier = Math.min(PC.physicalAge - 15, 0); // always negative (-15 to 0); younger kids are slightly more likely to get sick + const healthAdjusted = PCH.condition - (PCH.longDamage * 0.5) - (PCH.shortDamage * 1.5) * 1.25 + ageModifier; // -125~ to +125~, before weakness kicks in + const healthFactor = Math.clamp(1 + bonuses / healthAdjusted, 0.5, 1.5); // 0.5 to 1.5 + + if (V.debugMode) { + r.push(`(Illness factors: health ${healthFactor}${PCH.illness > 0 ? `; cure roll ${roll}` : ``})`); + } + + // When ill, being in average health with a level 1 illness has a 60% chance of getting better the next week at complete default + if (PCH.illness > 0 && roll > (30 + (PCH.illness * 10)) / (healthFactor)) { + PCH.illness -= 1; + r.push(`Your immune system <span class="health inc">pushes back</span> against your illness.`); + if (PCH.illness === 0) { + r.push(`It seems to have <span class="health inc">thoroughly beaten</span> whatever was ailing you.`); + } + } else if (canCatchIllness(PC)) { + /** an adult in average condition in an otherwise unprotected environment (no drugs or modifiers) will have `baseChance` chance of catching an illness when exposed + * note the independent roll for each exposure; we're ignoring the original random roll here + * @param {number} baseChance + * @returns {boolean} + */ + const catchesIllness = (baseChance) => { + const catchIll = random(1, 100); + if (V.debugMode) { + r.push(`(Transmission roll: ${catchIll} vs ${baseChance}*mods)`); + } + return catchIll < baseChance / (bonuses * healthFactor); + }; + + // PC is always in and out of the penthouse + if (isMovable(PC)) { + if (catchesIllness(5)) { + getIll(PC); + r.push(`You have picked up <span class="health dec">${addA(sicknessDegree[PCH.illness])}</span> while touring ${V.arcologies[0].name}; with all the people coming and going, it's not surprising that something easily transmissible can gain a foothold.`); + if (PCH.illness > 2) { + r.push(`Wandering around when you're this sick, however, is a serious public health risk given the population density, as well as just plain rude.`); + } + } + } + + /* if you didn't/couldn't catch an illness outside, maybe you'll get one from your slaves + * You're most likely to catch something from your lover, + * followed by consorts, + * then personal attention targets, + * and lastly, anything in the penthouse. + */ + const sexPartners = V.slaves.filter(s => App.Utils.sexAllowed(PC, s) && isSlaveAvailable(s)); + const fucktoys = V.slaves.filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment)); + const wives = V.slaves.filter(s => s.relationship === -3); + if (PCH.illness === 0 && wives.length > 0) { + for (const other of wives.filter(s => s.health.illness > 1)) { + if (catchesIllness(20)) { + PCH.illness = other.health.illness - 1; // reduced severity + r.push(`${other.slaveName} is sick, and has <span class="health dec">passed ${addA(sicknessDegree[PCH.illness])} on</span> to you.`); + break; + } + } + } + if (PCH.illness === 0 && fucktoys.length > 0) { + for (const other of fucktoys.filter(s => s.health.illness > 1)) { + if (catchesIllness(15)) { + PCH.illness = other.health.illness - 1; // reduced severity + r.push(`You have <span class="health dec">caught ${addA(sicknessDegree[PCH.illness])}</span> from your bedslave, ${other.slaveName}.`); + break; + } + } + } + if (PCH.illness === 0 && V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.length > 0 && !onBedRest(V.PC, true)) { + for (const other of V.personalAttention.slaves.map(s => getSlave(s.ID)).filter(s => !!s && s.health.illness > 1)) { + if (catchesIllness(20)) { + PCH.illness = other.health.illness - 1; // reduced severity + r.push(`You tried your best, but you ended up <span class="health dec">catching ${addA(sicknessDegree[PCH.illness])}</span> while training ${other.slaveName}.`); + break; + } + } + } + if (PCH.illness === 0 && sexPartners.length > 0) { + const contacts = 30; // limits max spread rate in large populations - you do try to avoid catching ill, after all + for (const other of sexPartners.randomMany(contacts).filter(s => s.health.illness > 1)) { + if (catchesIllness(5)) { + PCH.illness = other.health.illness - 1; // reduced severity + r.push(`You tried to avoid catching whatever is ailing ${other.slaveName}, but you still ended up <span class="health dec">with ${addA(sicknessDegree[PCH.illness])}.</span>`); + break; + } + } + } + } else if (PCH.illness > 0) { + if (random(1, 100) > 75 && PCH.illness === 1 && V.personalAttention.task !== PersonalAttention.RELAX && V.week > 8) { + // independent 25% chance of getting worse if you have a level 1 illness, aren't treating it, AND already failed your recovery roll (i.e. you've spent more than one week sick) + r.push(`You've ignored your minor illness, allowing it time to <span class="health dec">develop into something more threatening.</span>`); + PCH.illness += 1; + } else { + r.push(`Your <span class="health dec">${sicknessDegree[PCH.illness]} takes its toll on your health.</span>`); + } + // note: health damage from continuing illness is deducted in endWeekHealthDamage + } + } + } + + function health() { + r.push(`Living such a lavish lifestyle has a <span class="health inc">positive effect on one's well-being${V.personalAttention.task === PersonalAttention.RELAX ? ", especially when focusing on rest and relaxation" : ""}.</span> Overall,`); + if (PCH.condition < -90) { + r.push(`<span class="red">you are on the brink of death`); + } else if (PCH.condition < -50) { + r.push(`you are in <span class="red">bad health`); + } else if (PCH.condition < -20) { + r.push(`you are in <span class="red">poor health`); + } else if (PCH.condition <= 20) { + r.push(`you are in <span class="yellow">average health`); + } else if (PCH.condition <= 50) { + r.push(`you are in <span class="green">good health`); + } else if (PCH.condition <= 90) { + r.push(`you are in <span class="green">great health`); + } else { + r.push(`you are the definition of <span class="green">perfect health`); + } + if (PCH.shortDamage >= 20) { + r.push(r.pop() + `,</span>`); + if (PCH.condition < -20) { + r.push(`and`); + if (PCH.shortDamage >= 50) { + r.push(`have been <span class="red">incapacitated by your worsening condition.</span>`); + } else if (PCH.shortDamage >= 20) { + r.push(`are tormented by a <span class="red">general sense of malaise.</span>`); // tormented by malaise? General sense may be redundant here. + } + } else { + r.push(`but`); + if (PCH.shortDamage >= 50) { + r.push(`your <span class="red">worsening condition</span> has caught up with you.`); + } else if (PCH.shortDamage >= 20) { + r.push(`a <span class="red">general sense of malaise</span> lingers over you.`); // a malaise? General sense may be redundant here. + } + } + } else { + r.push(r.pop() + `.</span>`); + } + if (V.debugMode) { + r.push(`Your current health is ${PCH.condition}, with ${PCH.shortDamage} short term damage and ${PCH.longDamage} long term damage.`); + } + } + + function addiction() { + if (PC.addict > 0) { + if (PC.aphrodisiacs > 0) { + PC.addict++; + } else if (PC.addict < 2) { + r.push(`You've finally <span class="cyan">kicked your aphrodisiac addiction.</span>`); + PC.addict = 0; + } else if (PC.drugs === "detox pills") { + r.push(`The aphrodisiac substitute helps keep the cravings in check while slowly weaning you off the real drug.`); + PC.addict -= 1; + } else if (V.aphrodisiacUpgrade === 1 && !canEatFood(PC)) { + r.push(`Substitutes produced by your advanced pharmaceutical fabricator allow you to skip the negative effects of aphrodisiac withdrawal while efficiently flushing them from your system.`); + PC.addict -= 2; + } else if (PC.inflationType !== "aphrodisiac") { + r.push(`The effects of aphrodisiac withdrawal eat away at you, encouraging <span class="health dec">self-destructive behavior.</span>`); + PC.addict -= 2; + healthDamage(PC, 1 * Math.min(random(1, PC.addict), 10)); + } else { + r.push(`You don't mind cutting back on the aphrodisiac pills when your gut is laden with the stuff.`); + } + } else { + if (PC.aphrodisiacs > 0) { + if (random(1, 100) < 40 + (20 * PC.aphrodisiacs)) { + r.push(`<span class="cyan">You've become addicted to aphrodisiacs.</span>`); + PC.addict = 1; + } + } + } + } +}; diff --git a/src/endWeek/player/prPregnancy.js b/src/endWeek/player/prPregnancy.js index ddd20fd98f42e8b46e5ffc1941a55fc5c8db1d9d..40e78c80fe0cda3a06239402296cc2c953a47b51 100644 --- a/src/endWeek/player/prPregnancy.js +++ b/src/endWeek/player/prPregnancy.js @@ -372,6 +372,9 @@ App.EndWeek.Player.pregnancy = function(PC = V.PC) { } else if (PC.preg > PC.pregData.normalBirth / 1.42 && PC.physicalAge >= 16 && PC.hips === 0 && PC.hipsImplant === 0 && random(1, 100) > 70 / uterineHypersensitivityMod) { r.push(`Your hips <span class="change positive">widen</span> to better support your gravidity.`); PC.hips += 1; + } else if (PC.drugs === "hip wideners" && PC.preg > PC.pregData.normalBirth / 1.42 && PC.hips === -2 && PC.hipsImplant === 0 && random(1, 100) > 70 / uterineHypersensitivityMod) { + r.push(`Your hips <span class="change positive">widen</span> to better support your gravidity.`); + PC.hips += 1; } if (PC.preg > PC.pregData.normalBirth / 1.42 && PC.physicalAge >= 12 && buttSize < (4 + (rearQuirk * 3)) && PC.weight >= -30 && random(1, 100) > 70) { r.push(`Your butt <span class="change positive">gets a little bigger</span> as your body ripens.`); diff --git a/src/endWeek/saRules.js b/src/endWeek/saRules.js index 9f23049d3d874555ebd2ce96eeb1a5f60c677bd0..93819424501a1bde796e405418133f6868651316 100644 --- a/src/endWeek/saRules.js +++ b/src/endWeek/saRules.js @@ -232,7 +232,7 @@ App.SlaveAssignment.rules = function(slave) { r.push(`${He}'s permitted to rest when fatigue sets in, but not enough to shake ${his} tiredness; ${he} feels this <span class="gold">deprivation</span> is intentional.`); slave.trust -= 1; } else if (slave.devotion <= 20) { - r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} wellbeing and more to prevent ${him} from become unproductive.`); + r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} well-being and more to prevent ${him} from become unproductive.`); slave.devotion += 1; } else { r.push(`${He}'s permitted to rest when fatigue sets in and is <span class="mediumaquamarine">thankful</span> you would allow ${him} the privilege so that ${he} may serve you better.`); @@ -425,7 +425,7 @@ App.SlaveAssignment.rules = function(slave) { r.push(`${He}'s permitted to rest when fatigue sets in, but not enough to shake ${his} tiredness; ${he} feels this <span class="gold">deprivation</span> is intentional.`); slave.trust -= 1; } else if (slave.devotion <= 20) { - r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} wellbeing and more to prevent ${him} from become unproductive.`); + r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} well-being and more to prevent ${him} from become unproductive.`); slave.devotion += 1; } else { r.push(`${He}'s permitted to rest when fatigue sets in and is <span class="mediumaquamarine">thankful</span> you would allow ${him} the privilege so that ${he} may serve you better.`); @@ -1783,7 +1783,7 @@ App.SlaveAssignment.rules = function(slave) { r.push(`${He}'s permitted to rest when fatigue sets in, but not enough to shake ${his} tiredness; ${he} feels this <span class="gold">deprivation</span> is intentional.`); slave.trust -= 1; } else if (slave.devotion <= 20) { - r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} wellbeing and more to prevent ${him} from become unproductive.`); + r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} well-being and more to prevent ${him} from become unproductive.`); slave.devotion += 1; } else { r.push(`${He}'s permitted to rest when fatigue sets in and is <span class="mediumaquamarine">thankful</span> you would allow ${him} the privilege so that ${he} may serve you better.`); @@ -2093,7 +2093,7 @@ App.SlaveAssignment.rules = function(slave) { r.push(`${He}'s permitted to rest when fatigue sets in, but not enough to shake ${his} tiredness; ${he} feels this <span class="gold">deprivation</span> is intentional.`); slave.trust -= 1; } else if (slave.devotion <= 20) { - r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} wellbeing and more to prevent ${him} from become unproductive.`); + r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} well-being and more to prevent ${him} from become unproductive.`); slave.devotion += 1; } else { r.push(`${He}'s permitted to rest when fatigue sets in and is <span class="mediumaquamarine">thankful</span> you would allow ${him} the privilege so that ${he} may serve you better.`); @@ -2715,7 +2715,7 @@ App.SlaveAssignment.rules = function(slave) { r.push(`${He}'s permitted to rest when fatigue sets in, but not enough to shake ${his} tiredness; ${he} feels this <span class="gold">deprivation</span> is intentional.`); slave.trust -= 1; } else if (slave.devotion <= 20) { - r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} wellbeing and more to prevent ${him} from become unproductive.`); + r.push(`${He}'s permitted to rest when fatigue sets in, and <span class="hotpink">understands</span> this is less for ${his} well-being and more to prevent ${him} from become unproductive.`); slave.devotion += 1; } else { r.push(`${He}'s permitted to rest when fatigue sets in and is <span class="mediumaquamarine">thankful</span> you would allow ${him} the privilege so that ${he} may serve you better.`); diff --git a/src/js/health.js b/src/js/health.js index c1c5b6870e429ccc32c7c683924bfe0e881111fc..39760d4a3a2a66acddcc30bcb78efec08b638e15 100644 --- a/src/js/health.js +++ b/src/js/health.js @@ -32,15 +32,16 @@ globalThis.healthPenalty = function(slave) { * All things hurting a slave go through this to update short term damage and slave health. * @param {App.Entity.SlaveState|App.Entity.PlayerState} slave * @param {number} damage + * @param {number} mult * @returns {void} */ -globalThis.healthDamage = function(slave, damage) { +globalThis.healthDamage = function(slave, damage, mult = 1) { if (!_.isFinite(damage)) { throw Error("Health damage must be a finite number."); } const H = slave.health; damage = Math.max(Math.trunc(damage), 0); - H.shortDamage += damage; + H.shortDamage += damage * mult; H.condition -= damage; updateHealth(slave); }; diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js index 7855bbbb0a5143e93cc41a66f0d133ddb89fcaf9..6d29812b6dc86d08e098daef27ed73ec0ccca404 100644 --- a/src/js/statsChecker/statsChecker.js +++ b/src/js/statsChecker/statsChecker.js @@ -775,6 +775,12 @@ globalThis.canWalk = function(slave) { } else if (slave.heels === 1 && shoeHeelCategory(slave) === 0) { return false; } + // player exclusives + if (slave.ID === -1) { + if (slave.physicalImpairment > 1) { + return false; + } + } return true; }; @@ -804,6 +810,12 @@ globalThis.canStand = function(slave) { } else if (tooBigBelly(slave)) { return false; } + // player exclusives + if (slave.ID === -1) { + if (slave.physicalImpairment > 1) { + return false; + } + } return true; }; @@ -863,6 +875,12 @@ globalThis.canMove = function(slave) { return false; } } + // player exclusives + if (slave.ID === -1) { + if (slave.physicalImpairment > 1) { + return false; + } + } return true; }; @@ -903,7 +921,7 @@ globalThis.isHindered = function(slave) { if (slave.ID === -1) { if (onBedRest(slave)) { return true; - } else if (slave.criticalDamage !== 0) { + } else if (slave.physicalImpairment !== 0) { return true; } } diff --git a/src/js/utilsPC.js b/src/js/utilsPC.js index 005e604a320bab7c3c98b02fef1fcfca22495b0b..8b07f63737a90bf554d3a1b3899b87b9d9ebfba2 100644 --- a/src/js/utilsPC.js +++ b/src/js/utilsPC.js @@ -620,22 +620,28 @@ globalThis.IncreasePCSkills = function(input, increase = 1) { }; /** Returns if the player is on mandatory bedrest. + * If player still conducts business or is completely disabled is controlled by 'workingFromBed' * @param {App.Entity.PlayerState} actor + * @param {boolean} workingFromBed * @returns {boolean} */ -globalThis.onBedRest = function(actor) { - // consider player health and injury in the future! +globalThis.onBedRest = function(actor, workingFromBed = false) { + // consider player injuries in the future! if (!actor) { return null; - } else if (actor.health.shortDamage > 10) { + } else if (actor.health.shortDamage >= 50) { return true; - } else if (!canMove(actor)) { + } else if (actor.health.condition < -90) { + return true; + } else if (!isMovable(actor) && !workingFromBed) { + return true; + } else if (isTrapped(actor) && !workingFromBed) { return true; } else if (actor.preg > actor.pregData.normalBirth / 1.05) { // consider birth delayers and how they play into this return true; - } else if (actor.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20)) { + } else if (actor.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20) && !workingFromBed) { return true; - } else if (actor.bellyPreg >= actor.pregAdaptation * 2200) { + } else if (actor.bellyPreg >= actor.pregAdaptation * 2200 && !workingFromBed) { return true; } else if (isInduced(actor)) { return true; @@ -643,7 +649,7 @@ globalThis.onBedRest = function(actor) { return false; }; -/** Returns if the player is able to move via wheelchair or scooter. +/** Returns if the player is able to move via wheelchair. * Consider moving this to encompass slaves in the future. * @param {App.Entity.PlayerState} actor * @returns {boolean} diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js index dbc1635ae0bf275955651e1df40be989e5f10959..1c7a54d01530ac32eeb5d6f00d07140c2f9077ae 100644 --- a/src/js/utilsSlave.js +++ b/src/js/utilsSlave.js @@ -1673,6 +1673,9 @@ globalThis.SlaveTitle = function(slave, adjective = true, variability = true) { r = `shota ${r}`; } else { r = `loli ${r}`; + if (slave.boobs > 1000) { + r = `oppai ${r}`; + } } } } else { diff --git a/src/player/desc/pLongBelly.js b/src/player/desc/pLongBelly.js index b200c6cfa0ed9ee7889b93f4c76ff5c12316e74a..aa9dba1901e6f595565cc96d60fb45c17e993611 100644 --- a/src/player/desc/pLongBelly.js +++ b/src/player/desc/pLongBelly.js @@ -40,9 +40,9 @@ App.Desc.Player.belly = function(PC = V.PC) { if (PC.physicalAge <= 12) { r.push(`You have been reduced to nothing more than`); if (PC.belly > (PC.pregAdaptation * 1000)) { - r.push(`a breaking womb with a ${loliP} attached. It's a constant struggle to not be lost under the squirming mass of infants that consume every available space inside you.`); + r.push(`a breaking womb with a ${loliP} attached. It's a constant struggle to not be lost under the quivering mass of infants that consume every available space inside you.`); } else { - r.push(`an overstuffed womb with a ${loliP} attached. It's a constant struggle to not be lost under the squirming mass of infants that fill your body.`); + r.push(`an overstuffed womb with a ${loliP} attached. It's a constant struggle to not be lost under the quivering mass of infants that fill your body.`); } } else { r.push(`You have been reduced to nothing more than`); @@ -57,6 +57,10 @@ App.Desc.Player.belly = function(PC = V.PC) { } r.push(`belly off the ground.`); } + if (PC.weight > 190) { + r.push(`Your massively fat belly is stretched past its limit, resembling a "normal" pregnancy more than the gut it is.`); + } + r.push(`You are so full, you can clearly make out the distinct features of each of the outermost infants forced against the thin layer of skin and womb by their countless siblings. Your womb is so cramped, its contents are practically shrinkwrapped under the sheer pressure.`); if (PC.belly > (PC.pregAdaptation * 1000)) { r.push(`Your stomach has taken up a rather bruised tone; you likely don't have much time left.`); } @@ -103,7 +107,7 @@ App.Desc.Player.belly = function(PC = V.PC) { r.push(`belly off the ground, which certainly makes life complicated.`); } if (PC.weight > 190) { - r.push(`Your massively fat belly is stretched to its limit, so much so your folds have been pulled flat and your softness, firm.The implant takes up so much room in your body that it can be clearly seen through your skin.`); + r.push(`Your massively fat belly is stretched to its limit, so much so your folds have been pulled flat and your softness, firm. The implant takes up so much room in your body that it can be clearly seen through your skin.`); } else { r.push(`The implant filling your body takes up so much room that it can be clearly seen through your skin.`); } @@ -115,7 +119,9 @@ App.Desc.Player.belly = function(PC = V.PC) { } } r.push(stackedInflation()); - if (canMove(PC)) { + if (isMovable(PC) && !canMove(PC)) { + r.push(`It takes a little repositioning, but your wheelchair allows you to see your various sides with ease; a feat, really.`); + } else if (canMove(PC)) { r.push(`As laughable as it is, your only means of seeing your various sides is to pivot around your boundless middle as lifting it is out of the question. Even getting into a position to do this is an uphill battle.`); } else { r.push(`It's impossible to roll into a position where you can see anything other than your boundless middle. Half because it is you now, and half because you literally can't move it.`); @@ -250,7 +256,9 @@ App.Desc.Player.belly = function(PC = V.PC) { } } r.push(stackedInflation()); - if (canMove(PC)) { + if (isMovable(PC) && !canMove(PC)) { + r.push(`It takes a little repositioning, but your wheelchair allows you to see your various sides with ease; a feat, really.`); + } else if (canMove(PC)) { r.push(`As laughable as it is, your only means of seeing your various sides is to pivot around your boundless middle rather than try to reposition it to get a better look at yourself.`); if (PC.bellyPreg > 0) { if (PC.belly > (PC.pregAdaptation * 1000)) { @@ -333,7 +341,9 @@ App.Desc.Player.belly = function(PC = V.PC) { } } r.push(stackedInflation()); - if (canMove(PC)) { + if (isMovable(PC) && !canMove(PC)) { + r.push(`It takes a little repositioning, but your wheelchair allows you to see your various sides with ease; a feat, really.`); + } else if (canMove(PC)) { r.push(`As laughable as it is, it is now easier to pivot around your boundless middle than try to reposition it to get a better look at yourself.`); if (PC.bellyPreg > 0) { if (PC.belly > (PC.pregAdaptation * 1000)) { @@ -401,7 +411,12 @@ App.Desc.Player.belly = function(PC = V.PC) { } } r.push(stackedInflation()); - if (canMove(PC)) { + if (isMovable(PC) && !canMove(PC)) { + r.push(`Not only is it impossible to see around your bulbous middle in the mirror, but it juts out so far that it is pressing against the cold surface despite a concentrated effort to not roll into it.`); + if (PC.bellyPreg > 0) { + r.push(`Of course, the impact set your brood off, so now your ${(PC.belly > (PC.pregAdaptation * 1000)) ? "sore" : ""} stomach is squirming about, making it difficult to get a good look at anything on its surface.`); + } + } else if (canMove(PC)) { r.push(`Not only is it impossible to see around your bulbous middle in the mirror, but it juts out so far that it is pressing against the cold surface despite your efforts to avoid being too close to it.`); if (PC.bellyPreg > 0) { r.push(`Of course, this set your brood off, so now your ${(PC.belly > (PC.pregAdaptation * 1000)) ? "sore" : ""} stomach is squirming about, making it difficult to get a good look at anything on its surface.`); @@ -459,7 +474,7 @@ App.Desc.Player.belly = function(PC = V.PC) { } } r.push(stackedInflation()); - if (canMove(PC)) { + if (isMovable(PC)) { r.push(`Not only is it impossible to see around your bulbous middle in the mirror, but it juts out so far that it is pressing against the cold surface despite your efforts to avoid being too close to it.`); } else { r.push(`It's near impossible to roll into a position where you can see anything other than your boundless middle.`); @@ -1533,6 +1548,8 @@ App.Desc.Player.belly = function(PC = V.PC) { } else { r.push(`but you wouldn't still have this belly if you didn't find that arousing, would you?`); } + } else if (PC.belly >= 105000 && !canMove(PC) && isMovable(PC)) { + r.push(`Getting in and out of your wheelchair is an ordeal these days, and that isn't even considering how far off of it you protrude.`); } else if (PC.belly >= 105000 && canStand(PC)) { r.push(`You have trouble standing up and sitting down, with the former an exhausting endeavor.`); } else if (PC.belly >= 90000 && canWalk(PC)) { diff --git a/src/player/desc/pLongCrotch.js b/src/player/desc/pLongCrotch.js index 2b124b5775a24b4ef82f083b3725271515a417d1..46dfb72f7dcb2fd5f27531dae8673380099321a2 100644 --- a/src/player/desc/pLongCrotch.js +++ b/src/player/desc/pLongCrotch.js @@ -847,7 +847,7 @@ App.Desc.Player.crotch = function(PC = V.PC) { } } else { if (isAroused) { - if (!canMove(PC)) { + if (!isMovable(PC)) { r.push(`You and your bedding`); if (canSmell(PC)) { r.push(`reek of pussy juices`); diff --git a/src/player/desc/pLongDescription.js b/src/player/desc/pLongDescription.js index 48a175c2f1573d7250e8ac68077af4555115fc82..12519eed367322cc1a1898efc4a2dcc15b294dcc 100644 --- a/src/player/desc/pLongDescription.js +++ b/src/player/desc/pLongDescription.js @@ -15,9 +15,9 @@ App.Desc.Player.longDescription = function(PC = V.PC) { if (PC.dick && PC.vagina !== -1) { r.push(`futanari`); } else if (PC.dick > 0) { - r.push(`man`); + r.push(`${PC.actualAge > 12 ? "man" : "boy"}`); } else { - r.push(`woman`); + r.push(`${PC.actualAge > 12 ? "woman" : "girl"}`); } r.push(`with`); if (PC.markings === "freckles") { @@ -32,6 +32,8 @@ App.Desc.Player.longDescription = function(PC = V.PC) { if (canStand(PC)) { r.push(`You take a step back to focus more on your overall self.`); + } else if (isMovable(PC)) { + r.push(`You roll yourself back to focus more on your overall self.`); } r.push(App.Desc.Player.body(PC)); r.toParagraph(); @@ -53,10 +55,10 @@ App.Desc.Player.longDescription = function(PC = V.PC) { r.push(`It flows into your`); r.push(App.Desc.Player.butt()); r.toParagraph(); - if (!canMove(PC)) { + if (!isMovable(PC)) { r.push(`You roll over to get a better view of your crotch.`); } else if (PC.belly >= 100000 || PC.weight > 160) { - r.push(`You shift your weight and make use of some angled mirrors to see your crotch beneath your belly.`); + r.push(`You shift your weight and make use of some angled mirrors to see your crotch beneath your ${!canMove(PC) ? "lap-filling " : ""}belly.`); } else if (PC.dick === 0 && PC.vagina === -1) { r.push(`You turn your attention to your nether regions.`); } else if (PC.dick > 0) { @@ -65,7 +67,10 @@ App.Desc.Player.longDescription = function(PC = V.PC) { r.push(`You turn your attention to your special place.`); } r.push(App.Desc.Player.crotch()); + r.toParagraph(); + r.push(App.Desc.Player.health()); r.toParagraph(); + return r.container(); }; diff --git a/src/player/desc/pLongHealth.js b/src/player/desc/pLongHealth.js new file mode 100644 index 0000000000000000000000000000000000000000..7d43227d52a195e801500d7af350f9bfb5dbfb7c --- /dev/null +++ b/src/player/desc/pLongHealth.js @@ -0,0 +1,120 @@ +App.Desc.Player.health = function(PC = V.PC) { + const r = []; + const PCH = PC.health; + + if (PCH.condition < -90) { + r.push(`<span class="red">You look as if you already have one foot in the grave.</span>`); + } else if (PCH.condition < -50) { + r.push(`You feel <span class="red">really unwell.</span>`); + } else if (PCH.condition < -20) { + r.push(`You feel <span class="red">under the weather.</span>`); + } else if (PCH.condition <= 20) { + r.push(`You feel <span class="yellow">fine,</span> just fine.`); + } else if (PCH.condition <= 50) { + r.push(`You're feeling <span class="green">pretty good.</span>`); + } else if (PCH.condition <= 90) { + r.push(`You're feeling <span class="green">really great.</span>`); + } else { + r.push(`You've <span class="green">never felt better.</span>`); + } + + if (PCH.condition < -20) { + if (PCH.shortDamage >= 50) { + r.push(`Your body agrees, leaving you <span class="red">incapacitated by your worsening injuries.</span>`); + } else if (PCH.shortDamage >= 20) { + r.push(`To make it worse, a <span class="red">feeling of malaise</span> looms over you.`); + } + } else { + if (PCH.shortDamage >= 50) { + r.push(`Your body, however, has a different opinion; it <span class="red">refuses to function properly</span> until it is given time to heal.`); + } else if (PCH.shortDamage >= 20) { + r.push(`A <span class="red">feeling of malaise</span> hangs over you, however.`); + } + } + + if (PCH.illness === 1) { + r.push(`You <span class="yellow">might be coming down with something.</span>`); + } else if (PCH.illness === 2) { + r.push(`You've caught some sort of <span class="yellow">minor illness.</span>`); + } else if (PCH.illness === 3) { + r.push(`You've <span class="red">fallen ill;</span> you should see a doctor as soon as you can.`); + } else if (PCH.illness === 4) { + r.push(`You've <span class="red">become seriously ill;</span> you need to see as soon as you can.`); + } else if (PCH.illness === 5) { + r.push(`You've <span class="red">been stricken with a life-threatning illness;</span> you need to see a doctor immediately!`); + } + + if (PC.physicalImpairment > 1 ) { + r.push(`Your body has been <span class="red">completely ruined,</span> making even the simplest of tasks a challange.`); + } else if (PC.physicalImpairment > 0) { + r.push(`Your body has suffered <span class="yellow">permanent damage,</span> making life little more difficult.`); + } + + if (V.debugMode) { + r.push(`Your current health is ${PCH.condition}, with ${PCH.shortDamage} short term damage and ${PCH.longDamage} long term damage. You have a carcinogen build up of ${PC.chem} and an illness severity of ${PCH.illness}.`); + } + + // This all is going to be revised. + // shortDamage will be lingering damage, should increase the odds of further damaging events based off its value, and will naturally decay + // longDamage will not decay, and is caused by high chem and passing a shortDamage threshold. Works similar to shortDamage in increasing susceptibility, but at a greatly reduced percent. Also decreases max life span. + // criticalDamage is a permanant flaw gained by cheating death in certain events. + /* + if (PCH.shortDamage > 5 || PCH.longDamage > 5 || PCH.condition < 0) { + const ldc = PCH.longDamage > 5 || PCH.condition < 0 ? `,` : `.`); + const c = PCH.condition < 0 ? `,` : `.`); + + let and = ''; + + r.push(` Upon closer inspection you note that ${he}`); + + array = []; + if (PCH.shortDamage >= 100) { + array.push(`looks <span class="red">absolutely brutalized</span> and will never be quite the way he was${ldc}`); + } else if (PCH.shortDamage >= 70) { + array.push(`is <span class="red">gravely injured</span> with assured lasting effects${ldc}`); + } else if (PCH.shortDamage >= 40) { + array.push(`is <span class="red">seriously injured</span> with some lasting effects${ldc}`); + } else if (PCH.shortDamage >= 20) { + array.push(`is <span class="orange">injured${ldc}</span>`); + } else if (PCH.shortDamage > 5) { + array.push(`seems to have suffered a <span class="yellow">minor injury</span> recently${ldc}`); + } + + if (PCH.longDamage > 5) { + if (PCH.shortDamage > 5 && PCH.condition >= 0) { + and = `and `); + } + + if (PCH.longDamage >= 70) { + array.push(`${and}is suffering heavily under accumulated <span class="red">permanent health problems${c}</span>`); + } else if (PCH.longDamage >= 40) { + array.push(`${and}has some clear <span class="red">permanent health issues${c}</span>`); + } else if (PCH.longDamage >= 20) { + array.push(`${and}shows signs of <span class="orange">lasting health problems${c}</span>`); + } else { + array.push(`${and}carries some <span class="yellow">minor niggles${c}</span>`); + } + } + + if (PCH.condition < 0) { + if (PCH.shortDamage > 5 || PCH.longDamage > 5) { + and = `and `); + } + + if (PCH.condition < -80 && PCH.shortDamage !== 0 && PCH.longDamage !== 0) { + array.push(`${and}has been treated so badly he <span class="red">is close to the brink.</span>`); + } else if (PCH.condition < -50) { + array.push(`${and}appears to be in <span class="red">terrible condition.</span>`); + } else if (PCH.condition < -20) { + array.push(`${and}appears to be in <span class="orange">poor condition.</span>`); + } else { + array.push(`${and}could be in <span class="yellow">better condition.</span>`); + } + } + + r.push(` ${array.join(' ')}`); + } + */ + + return r.join(" "); +}; diff --git a/src/player/doctorConsultation.js b/src/player/doctorConsultation.js new file mode 100644 index 0000000000000000000000000000000000000000..9399af69f05c3c736976d916856b0c3e0df16ee0 --- /dev/null +++ b/src/player/doctorConsultation.js @@ -0,0 +1,538 @@ +App.UI.doctorConsultation = function() { + const frag = document.createElement("div"); + + const drugsDiv = document.createElement("div"); + const examDiv = document.createElement("div"); + const treatDiv = document.createElement("div"); + const illnessDiv = document.createElement("div"); + const { + HeU, + heU, hisU, + womanU + } = getNonlocalPronouns(V.seeDicks === 0 ? 0 : 100).appendSuffix("U"); + const {girlP} = getPronouns(V.PC).appendSuffix('P'); + + const arcology = V.arcologies[0]; + const price = Math.max(Math.min((Math.pow(5, V.baseDifficulty) * 10), 10000), 500); + + if (V.doctor.state > 0) { // Don't charge on the first visit. + cashX(forceNeg(price), "PCmedical"); + } + + if (V.doctor.state > 1) { + App.Events.addParagraph(frag, [ + `You head to the private clinic to meet with your doctor for another medical examination. After a short wait, and a payment of <span class="cash">${cashFormat(price)},</span> you're directed to your doctor's exam room for your appointment. "Back again so soon? We're happy to keep giving you drugs and advice if you keep giving us money; the owner wants to buy a new organ farm after all. Have to say I am a bit jealous of our neighbor's expensive new toy, I mean can you blame me? The only toys we find here are usually lodged someplace${V.PC.actualAge < V.minimumSlaveAge ? "—Ah! Nevermind! Someone your age shouldn't be hearing things like that, and no, I don't want to know what you get up to up there in the penthouse." : "they shouldn't be, if you catch my drift. You can only take so much of that before you start to question your career decisions, oh, and good luck ever looking at them the same way again"}."` + ]); + } else if (V.doctor.state > 0) { + App.Events.addParagraph(frag, [ + `You head to the private clinic to meet with your doctor for a medical examination. After a short wait, and a payment of <span class="cash">${cashFormat(price)},</span> you're directed to your doctor's exam room for your appointment. "${V.PC.health.condition < 20 || V.PC.health.illness > 1 || V.PC.addict > 10 ? "Well you've seen better days, haven't you? Came to the right place to put back in order, though." : "You seem to be doing well, but let's see what the tests have to say about that"}. Hop up on the scale and we'll get this over with."` + ]); + V.doctor.state = 2; + } else { + App.Events.addParagraph(frag, [ + `You make your way to ${arcology.name}'s main medical pavilion, which houses the largest private clinic in the arcology, intent on finding a primary phisician to keep an eye on your health. ${arcology.FSHedonisticDecadence !== "unset" ? "There is a substantial wait before you're seen, owing to the increasingly eccentric people that make up your citizenry, so you have plenty of time to deal with registering and enjoy a little people-watching, after" : "The clinic operates like a well-oiled machine, and you barely get through registering yourself"} before your name is called. As you enter the exam room, you're greeted by an imposing, rather harried looking ${womanU}, "Welcome ${PlayerName()}.${V.PC.actualAge < V.minimumSlaveAge ? `" ${HeU} gives you a momentary dirty look before realizing what ${heU} did. "Apologies, I just thought you'd be a little older... Nevermind.` : ""} I will be serving as your doctor from here on, and while the first visit is free, future ones will run you <span class="noteworthy">${cashFormat(price)},</span> so do try to remember that. To start, would you please step onto this scale so we may begin this examination?"` + ]); + V.doctor.state = 1; + } + frag.append(medicalExam()); + + if (V.PC.health.condition <= 20) { + frag.append(healthBoost()); + } + if (V.PC.health.illness > 1) { + frag.append(treatIllness()); + } + + frag.append(drugs()); + + return frag; + + function medicalExam() { + const r = []; + const PCH = V.PC.health; + + r.push(`"With all the tests completed, let's see how you did.`); + if (PCH.condition < -90) { + r.push(`<span class="red">Good lord you are very unwell.</span> We can stabilize you, but after that, go home and rest. Eat well, keep your spirits up, and maybe pray a little. If you feel you are dying, call us at once.`); + } else if (PCH.condition < -50) { + r.push(`<span class="red">You're very unhealthy.</span> After I treat you, go home and rest. Eat well, keep your spirits up, and get some rest. If it persists, come back at once.`); + } else if (PCH.condition < -20) { + r.push(`<span class="red">You're rather unhealthy.</span> Get lots of rest and whatever light excercise you can manage. If it gets worse, come back at once, don't wait.`); + } else if (PCH.condition <= 20) { + r.push(`<span class="yellow">You are in fair health.</span> A little worrying, but nothing bad yet.`); + } else if (PCH.condition <= 50) { + r.push(`<span class="green">Your health is good,</span> but not great. Nothing to worry about, as long as it doesn't start dipping.`); + } else if (PCH.condition <= 90) { + r.push(`<span class="green">Your health is great,</span> keep doing whatever it is you're doing.`); + } else { + r.push(`<span class="green">Your health is pretty much the ideal,</span> it can't possibly get any better.`); + } + + if (PCH.illness > 1) { + if (PCH.condition <= 20) { + r.push(`And <span class="red">you're sick</span> to top it off, but we've got something for that too. If you get any worse, you know where we are.`); + } else { + r.push(`You've got <span class="red">some sort of illness</span> going on, but that's pretty easily dealt with via medication, and in your health, you should bounce back nicely.`); + } + } + + r.push(`On the physical side,`); + if (V.PC.weight > 190) { + r.push(`you are <span class="red">much too fat.</span>`); + if (arcology.FSHedonisticDecadence !== "unset") { + r.push(`But who isn't these days?" ${HeU} sighs, patting ${hisU} own growing gut. "Anyway, a little less weight would do you some good.`); + } else if (PCH.condition < -20) { + r.push(`All that weight is quite literally crushing you. This is why your health is in decline.`); + } else { + r.push(`You may be managing your health well enough to fool yourself into thinking you'll be fine, but it will catch up to you one day, and when it does, it's all downhill from there.`); + } + } else if (V.PC.weight > 160) { + r.push(`you are <span class="red">too fat.</span>`); + if (arcology.FSHedonisticDecadence !== "unset") { + r.push(`But who isn't these days?" ${HeU} sighs, patting ${hisU} own growing gut. "Anyway, a little exercise and watching what you eat will keep your health up despite the weight.`); + } else if (PCH.condition < -20) { + r.push(`Poor health coupled with obesity puts you at serious risk of heart failure. Think about that before each meal.`); + } else { + r.push(`You may be managing your health well enough, but there is always the looming chance of complications arising from your weight, and when it happens, you may find it hard to get back on your feet, leading to further issues down the road.`); + } + } else if (V.PC.weight > 130) { + r.push(`you are <span class="red">too fat.</span>`); + if (arcology.FSHedonisticDecadence !== "unset") { + r.push(`But who isn't these days?" ${HeU} sighs, patting ${hisU} own growing gut. "Anyway, a little exercise and watching what you eat will keep any complications at bay.`); + } else if (PCH.condition < -20) { + r.push(`Your weight is not a good mix with your overall health. You'll find yourself plauged with complications that will steadily drag you further and further down.`); + } else { + r.push(`With your overall health, I think you should manage fine despite the weight. You may hit a snag here and there, but you're fit enough to bounce back. If you don't, however, we'll be here to patch you up.`); + } + } else if (V.PC.weight > 95) { + r.push(`you are getting rather fat.`); + if (arcology.FSHedonisticDecadence !== "unset") { + r.push(`But who isn't these days?" ${HeU} sighs, patting ${hisU} own growing gut. "Anyway, just consider your future wellbeing, is all.`); + } else if (PCH.condition < -20) { + r.push(`While any complications will still be minor, your poor health will make them far more frequent then you'd like.`); + } else { + r.push(`You're healthy enough that it isn't a concern though. And even if anything happens due to your weight, you're fit enough to shrug it off.`); + } + } else if (V.PC.weight < -95) { + r.push(`you are <span class="red">very malnourished.</span>`); + if (PCH.condition > 20) { + r.push(`You need to eat more or your health will start to falter.`); + } else { + r.push(`This is no doubt a major factor in your recent health issues.`); + } + } else if (V.PC.weight < -30) { + r.push(`you are a bit thin.`); + if (PCH.condition < -20) { + r.push(`I recommend putting on a little weight until your health improves. Having to work it off afterwards will help solidify your wellbeing as well.`); + } + } else { + r.push(`your weight is fine.`); + } + + if (V.PC.preg > 0) { + if (V.PC.actualAge <= 12 && V.PC.actualAge < V.minimumSlaveAge) { + if (V.PC.pregKnown) { + if (isInduced(V.PC)) { + r.push(r.pop() + `" ${HeU} seems to be trying ${hisU} hardest to avoid looking at you, "You're fully dilated, but at your age, odds aren't in your favor for a successful natural birth. If you'd consent, I'll have you prepped for a cesarean at once.`); + } else if (V.dangerousPregnancy === 1) { + if ((V.PC.belly > (V.PC.pregAdaptation * 3200)) || V.PC.bellyPreg >= 500000) { + r.push(r.pop() + `" ${HeU} looks ready to vomit after having inspected your body-turned-womb, "This is going to haunt my dreams. How, why? I can't understand what would propel a child to do this to themselves. I have no advice for you other than taking residency here until whatever happens, happens. I just hope there's something left to salvage...`); + } else if ((V.PC.bellyPreg >= V.PC.pregAdaptation * 2200) || (V.PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + r.push(r.pop() + `" ${HeU} grimaces at the bulge hanging heavily from your underage body, "Your body is about at the limit of what it can handle. The best I can tell you is to try to not move around if you can help it. When further complications arise, please seek us out fast.`); + } else if (V.PC.bellyPreg > V.PC.pregAdaptation * 1000) { + r.push(r.pop() + `" ${HeU} grimaces at the bulge extending from your underage body, "This was truly inevitable. Kids shouldn't be having kids. Their bodies just can't handle it. The best I can tell you is to avoid strenuous activities, get lots of rest, and keep to a healthy diet. It's only going to become more complicated from here.`); + } else { + r.push(r.pop() + `" ${HeU} glances uncomfortably at your stomach, "Your pregnancy is progressing smoothly, for now. But children aren't ready to make babies, so please take it easy.`); + } + } else { + r.push(r.pop() + `" ${HeU} glances uncomfortably at your stomach, "Your pregnancy is progressing smoothly, for now. But children aren't ready to make babies, so please take it easy.`); + } + } else { + r.push(`Your urine sample says you are... <span class="pregnancy">pregnant.</span> If someone took advantage of you, you can tell us you know. This is a safe place. Or, um, have you been 'experimenting'? No, no, I don't want to know if you have been.`); + V.PC.pregKnown = 1; + } + } else if (V.PC.actualAge < V.minimumSlaveAge) { + if (V.PC.pregKnown) { + if (isInduced(V.PC)) { + r.push(`I didn't want to say anything at the moment, but you're fully dilated, and since you're a bit young still, should I take you to maternity or...?`); + } else if (V.dangerousPregnancy === 1) { + if ((V.PC.belly > (V.PC.pregAdaptation * 3200)) || V.PC.bellyPreg >= 500000) { + r.push(`Dear god, how did you manage to get yourself into this state? At your age, to be swollen like that; it's just disturbing to see. Anyway, Assuming your womb just doesn't burst on its own, try to stay as still as much as possible and, um, avoid pointy objects?`); + } else if ((V.PC.bellyPreg >= V.PC.pregAdaptation * 2200) || (V.PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + r.push(`Hmm, your body is struggling to bear the weight in your womb. Try to stay put as much as you can and don't move around too much. No strenuous activities, either! Especially 'fooling around' after it got you into this state!`); + } else if (V.PC.bellyPreg > V.PC.pregAdaptation * 1000) { + r.push(`Hmm, your body is starting to have a bit of trouble, it seems. Just take it easy and you shouldn't run into any complications.`); + } else { + r.push(`Your pregnancy is progressing smoothly.`); + } + } else { + r.push(`Your pregnancy is progressing smoothly.`); + } + } else { + r.push(`Your urine sample... You do know about protection, right? 'Cause, <span class="pregnancy">you're pregnant.</span>`); + V.PC.pregKnown = 1; + } + } else { + if (V.PC.pregKnown) { + if (isInduced(V.PC)) { + r.push(`I didn't want to say anything at the moment, but you're fully dilated, and I'm pretty sure the baby is coming out even as we speak. Should we, take care of that for you, or...?`); + } else if (V.dangerousPregnancy === 1) { + if ((V.PC.belly > (V.PC.pregAdaptation * 3200)) || V.PC.bellyPreg >= 500000) { + r.push(`I'll never not be disturbed by this. Assuming your womb just doesn't burst on its own, try to stay as still as you can and, um, avoid pointy objects?`); + } else if ((V.PC.bellyPreg >= V.PC.pregAdaptation * 2200) || (V.PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + r.push(`Hmm, your belly is pretty tight. Try to stay put as much as you can and don't move around too much. No strenuous activities, either! If you really need to do 'that', just take it slow.`); + } else if (V.PC.bellyPreg > V.PC.pregAdaptation * 1000) { + r.push(`Hmm, your belly is a little tight. Just take it easy and your pregnancy will progress without trouble.`); + } else { + r.push(`Your pregnancy is progressing smoothly.`); + } + } else { + r.push(`Your pregnancy is progressing smoothly.`); + } + } else { + r.push(`That urine sample you gave up has a surprise for you. <span class="pregnancy">Congratulations, you're pregnant!</span>`); + V.PC.pregKnown = 1; + } + } + } + if ((V.PC.bellyPreg >= V.PC.pregAdaptation * 2200) || (V.PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + r.push(`We have drugs that can delay birth to an extent, helping to avoid miscarriage and premature birth in at-risk mothers. With what I've seen, you're eligible for them. They aren't the healthiest things to take, however, and there are serious isseus if you accidentally forget to stop taking them to allow for birth when you're due.`); + } + if (V.PC.preg > V.PC.pregData.normalBirth / 1.42 && V.PC.hips === -2 && V.PC.hipsImplant === 0) { + r.push(`Your hips are a bit too narrow for birth and, assuming you manage, you will end up splitting your pelvis. You could take these tablets to boost the amount of relaxin in your system in an effort to widen your hips, but long term use will cause more problems than its worth. It's up to you if you want to take them or just opt for a cesarean section.`); + } + + // injuries + if (V.PC.physicalImpairment > 0) { + r.push(r.pop() + `" ${HeU} sighs, "No improvements to the physical damage...`); + } + + if (V.PC.hears === -1) { + r.push(`Hearing could be better...`); + } else { + r.push(`Hearing is fine...`); + } + if (anyVisionEquals(V.PC, 1)) { + r.push(`Eyesight is poor...`); + // Do something with laser eye surgery here? + } else { + r.push(`Eyesight, fine...`); + } + + if (V.PC.energy > 95) { + if (V.PC.actualAge <= 12) { + r.push(`Anaphrodisiacs. I'm prescribing them to you. You are way too young to doing things like that. Now I feel dirty thanks to you.`); + } else { + r.push(`I noticed your orgasm during the cancer screening. You've lost control of your sex drive, haven't you? I can prescribe anaphrodisiacs to you if you want to regain your composure.`); + } + } + + if (V.PC.addict > 3 || V.PC.aphrodisiacs > 0 || V.PC.inflationType === "aphrodisiac") { + r.push(`The urinalyses tells me you've been hitting the aphrodisiacs. I hope you know the risks involved with that. I'm sure you do, but if you ever need any assistance with it, we do have detox pills available.`); + } + + if (V.PC.chem > 5) { + if (canEatFood(V.PC)) { + r.push(`You've got some <span class="red">carcinogen buildup</span> according to your blood test. Whatever it is that you are doing to cause this, you should know that it is taking years off your life. It's hard to get rid of too, which is the real problem, but I think there is a diet that can help deal with it. Or at least there was, I don't know how easy it is to obtain the ingrediants anymore.`); + } else { + r.push(`You've got some <span class="red">carcinogen buildup</span> according to your blood test. Your diet will neutralize most of it, given time. Still, you should probably cut back on whatever it is you're doing.`); + } + } + + if (V.week > 45 && V.PC.digestiveSystem === "atrophied") { + r.push(`<span class="noteworthy">Some progress has been made when it comes to reversing the effects of long-term consumption of slave food.</span> It's best described as an intermediary diet to get your body used to real food again. From what I've heard, the process is horrible, and you can't stop once you start or you'll undo all your effort. Hmm, it also says not to give it pregnant and nursing women, the infirm, and those with compromised immune systems. Oh, and that one should put on some bodyfat before starting, to help offset the whole starvation thing. The more I read, the worse it gets, but it may be worth considering, given your, you know, past.`); + } + r.push(`And that's all that's worth really noting."`); + + r.join(" "); + App.Events.addNode(examDiv, r); + + return examDiv; + } + + function drugs() { + const hormonesDiv = document.createElement("div"); + const playerDrugsDiv = document.createElement("div"); + const pregDrugsDiv = document.createElement("div"); + const anaphrodisiacDiv = document.createElement("div"); + const weaningDiv = document.createElement("div"); + + App.Events.addParagraph(frag, [ + `"With that out of the way, ${V.PC.actualAge < V.minimumSlaveAge ? "I guess I should ask if there is anything our pharmacy could do for you, though I'm not entirely comfortable offering someone your age drugs like these. I guess you are legally an adult, for all intents and purposes, so my opinion doesn't really matter, does it" : "is there anything our pharmacy can help you with"}? A prescription will last as long as you keep refilling it, and overall it's a much safer choice than going under the knife at any of our neighbors or resorting to using drugs designed for slaves."` + ]); + + if (V.week > 45 && V.PC.digestiveSystem === "atrophied") { + drugsDiv.append(slaveFoodCure()); + } + + if (V.consumerDrugs === 0) { + drugsDiv.append(playerDrugs()); + drugsDiv.append(hormones()); + } + if (V.PC.pregControl !== "none" || V.PC.bellyPreg >= V.PC.pregAdaptation * 2200 || (V.PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) { + drugsDiv.append(pregDrugs()); + } + if (V.PC.energy > 95 || V.PC.aphrodisiacs < 0) { + drugsDiv.append(anaphrodisiacs()); + } + + return drugsDiv; + + function playerDrugs() { + App.UI.DOM.appendNewElement("h3", playerDrugsDiv, `Drugs`); + const text = []; + const links = []; + + if (V.PC.drugs === "no drugs") { + playerDrugsDiv.append(`You are not using any pharmaceutical drugs. Start taking: `); + } else { + playerDrugsDiv.append(`You are planning on taking ${PC.drugs}. Instead take: `); + } + + if (V.PC.drugs !== "breast enhancers") { + if (V.PC.boobs < 10000) { + links.push(App.UI.DOM.link(`Breast enhancers`, () => { + V.PC.drugs = "breast enhancers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Breast enhancers`, [ + `"Surely your back is already hurting? I can't advise going any larger, not that the patches would be effective anyway."`, + ])); + } + } + if (V.PC.drugs !== "butt enhancers") { + if (V.PC.butt < 8) { + links.push(App.UI.DOM.link(`Butt enhancers`, () => { + V.PC.drugs = "butt enhancers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Butt enhancers`, [ + `"Isn't it getting a bit hard for you to move? I can't advise going any larger, not that the patches would be effective anyway."`, + ])); + } + } + if (V.PC.drugs !== "lip enhancers") { + if (V.PC.lips <= 85) { + links.push(App.UI.DOM.link(`Lip enhancers`, () => { + V.PC.drugs = "lip enhancers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Lip enhancers`, [ + `"I can hear how difficult it is for you to form words with those lips. I'm not going to be the one that costs you the ability to talk."`, + ])); + } + } + if (V.PC.drugs !== "penis enlargers") { + if (V.PC.dick > 0) { + if (V.PC.dick < 6) { + links.push(App.UI.DOM.link(`Penis enlargers`, () => { + V.PC.drugs = "penis enlargers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Penis enlargers`, [ + `"The lightheadedness you feel when you get aroused is mostly due to your current size, so getting larger will only make things worse."`, + ])); + } + } + } + if (V.PC.drugs !== "testicle enlargers") { + if (V.PC.balls > 0 && V.PC.scrotum > 0) { + if (V.PC.balls < 30) { + links.push(App.UI.DOM.link(`Testicle enlargers`, () => { + V.PC.drugs = "testicle enlargers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Testicle enlargers`, [ + `I could diagnose you with elephantiasis and nobody would bat an eye over it. Really though, nothing I can say would help the patches actually work on you at that size.`, + ])); + } + } + } + if (V.PC.drugs !== "fertility supplements") { + if (V.PC.ovaries === 1 || V.PC.mpreg === 1) { + links.push(App.UI.DOM.link(`Fertility supplements`, () => { + V.PC.drugs = "fertility supplements"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Fertility supplements`, [ + `It would be a waste of drugs to give these to someone that doesn't even have the organs needed to produce eggs.`, + ])); + } + } + if (V.PC.drugs !== "hip wideners") { + if (V.PC.preg > V.PC.pregData.normalBirth / 1.42 && V.PC.hips === -2 && V.PC.hipsImplant === 0) { + links.push(App.UI.DOM.link(`Hip wideners`, () => { + V.PC.drugs = "hip wideners"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } + } + if (V.PC.drugs !== "detox pills") { + if (V.PC.addiction > 3) { + links.push(App.UI.DOM.link(`Detox pills`, () => { + V.PC.drugs = "detox pills"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } + } + + text.push(App.UI.DOM.generateLinksStrip(links)); + + App.Events.addNode(playerDrugsDiv, text); + + return playerDrugsDiv; + } + + function hormones() { + App.UI.DOM.appendNewElement("h3", hormonesDiv, `Hormones`); + const text = []; + const links = []; + + if (V.PC.hormones !== 0) { + hormonesDiv.append(`You are planning to use ${PC.hormones === 1 ? "female" : "male"} hormones this week. `); + links.push(App.UI.DOM.link(`Decide against it`, () => { + V.PC.hormones = 0; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + hormonesDiv.append(`You do not intend to take artificial hormones. `); + } + if (V.PC.hormones > -1) { + links.push(App.UI.DOM.link(`Start male hormones`, () => { + V.PC.hormones = -1; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } + if (V.PC.hormones < 1) { + links.push(App.UI.DOM.link(`Start female hormones`, () => { + V.PC.hormones = 1; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } + + text.push(App.UI.DOM.generateLinksStrip(links)); + App.Events.addNode(hormonesDiv, text); + + return hormonesDiv; + } + + function pregDrugs() { + App.UI.DOM.appendNewElement("h3", pregDrugsDiv, `Pregnancy Drugs`); + const text = []; + + if (V.PC.pregControl === "none") { + pregDrugsDiv.append(`You've been advised to start taking labor suppressors. `); + text.push( + App.UI.DOM.link(`Follow ${hisU} advice`, () => { + V.PC.pregControl = "labor suppressors"; + App.UI.DOM.replace(drugsDiv, drugs); + }) + ); + } else { + pregDrugsDiv.append(`You're taking labor suppressors to ${PC.preg >= V.PC.pregData.normalBirth ? "delay giving birth" : "prevent giving birth prematurely"}. `); + text.push( + App.UI.DOM.link(`Decide against it`, () => { + V.PC.pregControl = "none"; + App.UI.DOM.replace(drugsDiv, drugs); + }) + ); + } + + + App.Events.addNode(pregDrugsDiv, text); + + return pregDrugsDiv; + } + + function anaphrodisiacs() { + const text = []; + + App.UI.DOM.appendNewElement("h3", anaphrodisiacDiv, `Anaphrodisiacs`); + + if (V.PC.aphrodisiacs < 0) { + anaphrodisiacDiv.append(`You plan on taking anaphrodisiacs to reign in your sex drive. `); + text.push( + App.UI.DOM.link(`Decide against it`, () => { + V.PC.aphrodisiacs = 0; + App.UI.DOM.replace(drugsDiv, drugs); + }) + ); + } else { + anaphrodisiacDiv.append(`You've been offered an anaphrodisiac prescription to combat your nymphomania. `); + text.push( + App.UI.DOM.link(`Take ${hisU} offer`, () => { + V.PC.aphrodisiacs = -1; + App.UI.DOM.replace(drugsDiv, drugs); + }) + ); + } + + App.Events.addNode(anaphrodisiacDiv, text); + + return anaphrodisiacDiv; + } + + function slaveFoodCure() { + const text = []; + + App.UI.DOM.appendNewElement("h3", weaningDiv, `Diet`); + weaningDiv.append(`You have been given the opportunity to eat real food again. `); + if (V.PC.preg > 0) { + links.push(App.UI.DOM.disabledLink(`Start the process`, [ + `It would be unethical to allow you to start this diet while pregnant.`, + ])); + } else if (V.PC.health.condition <= 20) { + links.push(App.UI.DOM.disabledLink(`Start the process`, [ + `In your condition, this diet while have a deleterious effect on your health.`, + ])); + } else if (V.PC.health.illness > 1) { + links.push(App.UI.DOM.disabledLink(`Start the process`, [ + `This diet will decimate your health, and with you ill, well... It won't end well.`, + ])); + } else if (V.PC.weight < -10) { + links.push(App.UI.DOM.disabledLink(`Start the process`, [ + `Put on a little weight first. I'd hate to see you starve to death or be forced to give up halfway.`, + ])); + } else { + text.push( + App.UI.DOM.link(`Start the process`, () => { + V.PC.diet = "weaning"; + App.UI.DOM.replace(drugsDiv, drugs); + }) + ); + } + + App.Events.addNode(weaningDiv, text); + + return weaningDiv; + } + } + + function healthBoost() { + const text = []; + + text.push(`${HeU} gives you a quick prick with a syringe. "${V.PC.actualAge > 12 ? `Heres a little something to <span class="health inc">help your health.</span> It's just a quick pick-me-up, but perhaps it will get you back on track` : `That's a good ${girlP}, that wasn't so bad, was it? Here, have a lollipop to feel better. As for the shot, it should <span class="health inc">improve your health a little,</span> and hopefully set you on the road to recovery`}."`); + improveCondition(V.PC, 5); + + App.Events.addNode(treatDiv, text); + + return treatDiv; + } + + function treatIllness() { + const text = []; + + text.push(`${HeU} hands you a pill bottle. "${V.PC.actualAge > 12 ? `These should <span class="health inc">get that illness under control.</span> Take them with food, three times a day, and you should be feeling a lot better by the time they run out` : `Take one of these with your breakfast, lunch and dinner, alright? Keep doing that until they're all gone and that <span class="health inc">illness should stop making you feel so bad.</span> Make sure you take all of them, too! Just because you start to feel fine doesn't mean you're cured yet`}."`); + V.PC.health.illness = Math.max(0, V.PC.health.illness-2); + + App.Events.addNode(illnessDiv, text); + + return illnessDiv; + } +}; diff --git a/src/player/electiveSurgery.js b/src/player/electiveSurgery.js index 5ba9aaf8d5f247f649da8321e75c1cbf53a9045d..d39b69fff4a40555271c7956695687210adb7442 100644 --- a/src/player/electiveSurgery.js +++ b/src/player/electiveSurgery.js @@ -100,7 +100,7 @@ App.UI.electiveSurgery = function() { } } else { App.Events.addParagraph(el, [ - `You ${canWalk(V.PC) ? "wander" : "drive"} up and down ${arcology.name}'s primary medical pavilion, taking in what practices are available and their relative popularity. ${arcology.FSBodyPurist !== "unset" ? "Most of the plastic surgeons have packed up and left, but of those that chose to stay," : "While there is no shortage of plastic surgeons to choose from,"} there is a clear winner; the small suite at the end of the wing completely swarmed by patrons. It takes some effort to work your way through the crowd, but the moment the ${nurse.boobs > 2000 ? "busty" : "cute"} assistant behind the counter notices you and ${nurse.belly >= 10000 ? "waddles" : "rushes"} over${nurse.butt > 10 ? `, practically bulldozing ${himselfU} a path in the process with ${hisU} absurd hips and rear` : ""}, do you find yourself whisked away to an exam room by ${himU}. "You're the new owner, right? Recognized you from the newsfeeds. Anyway, we'll need to do a few measurements, take some biometrics, and sign a couple papers before we can put you under the knife. You know, standard business and all that." With the paperwork taken care of, and after what can only be called an "intimate fondlng" under the guise of a medical examination${nurse.butt > 10 || nurse.belly >= 5000 || nurse.boobs > 2000 ? `, with a little helping of ${hisU} larger assets rubbing against you on the side` : ""}, you're ready to look over the available procedures. ${nurse.butt > 10 || nurse.belly >= 5000 || nurse.boobs > 2000 ? `"Heh, yeah I can get a little handsy, and feeling all of this," ${heU} gestures at ${hisU} enhanced curves, "pushing against someone is just soo thrilling!"` : `"Heh, yeah I can get a little handsy"`}. I think that's part of why we're so popular, not that the doctors' work is shabby or anything! I mean, I came out okay, right? Plus I really do enjoy seeing what they can come up with, it's an art form, really, and boy does it get me excited." ${HeU} coughs and gets back to the heart of the matter. "You have a dream body, and we have the means to make it happen! So, what can I help you with?"` + `You ${canWalk(V.PC) ? "wander" : "drive"} up and down ${arcology.name}'s primary medical pavilion, taking in what practices are available and their relative popularity. ${arcology.FSBodyPurist !== "unset" ? "Most of the plastic surgeons have packed up and left, but of those that chose to stay," : "While there is no shortage of plastic surgeons to choose from,"} there is a clear winner; the small suite at the end of the wing completely swarmed by patrons. It takes some effort to work your way through the crowd, but the moment the ${nurse.boobs > 2000 ? "busty" : "cute"} assistant behind the counter notices you and ${nurse.belly >= 10000 ? "waddles" : "rushes"} over${nurse.butt > 10 ? `, practically bulldozing ${himselfU} a path in the process with ${hisU} absurd hips and rear` : ""}, do you find yourself whisked away to an exam room by ${himU}. "${V.PC.visualAge < V.minimumSlaveAge ? "Oh my god! You're so cute! Does your mother know you're here? If she doesn't, your secret's safe with us!" : "You're the new owner, right? Recognized you from the newsfeeds"}. Anyway, we'll need to do a few measurements, take some biometrics, and sign a couple papers before we can put you under the knife. You know, standard business and all that." With the paperwork taken care of, and after what can only be called an "intimate fondlng" under the guise of a medical examination${nurse.butt > 10 || nurse.belly >= 5000 || nurse.boobs > 2000 ? `, with a little helping of ${hisU} larger assets rubbing against you on the side` : ""}, you're ready to look over the available procedures. ${nurse.butt > 10 || nurse.belly >= 5000 || nurse.boobs > 2000 ? `"Heh, yeah I can get a little handsy, and feeling all of this," ${heU} gestures at ${hisU} enhanced curves, "pushing against someone is just soo thrilling!"` : `"Heh, yeah I can get a little handsy"`}. I think that's part of why we're so popular, not that the doctors' work is shabby or anything! I mean, I came out okay, right? Plus I really do enjoy seeing what they can come up with, it's an art form, really, and boy does it get me excited." ${HeU} coughs and gets back to the heart of the matter. "You have a dream body, and we have the means to make it happen! So, what can I help you with?"` ]); App.Events.addParagraph(el, [ `"Oh! I almost forgot! Since you're a new client, <span class="green">today's basic surgery is half off!</span>${arcology.FSBodyPurist !== "unset" ? `But, <span class="red">the cost of implants is still high</span> due to policy, unfortunately...` : arcology.FSTransformationFetishist !== "unset" ? `And with <span class="green">implants being so cheap,</span> we're practically giving them away!` : ""}"` diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js index 666b2f1f5a342625dc520eaf12af4e5073638059..7cc3d7a9012fdf25e9b13d9aa7e2ffa7765ee933 100644 --- a/src/player/js/PlayerState.js +++ b/src/player/js/PlayerState.js @@ -319,7 +319,7 @@ App.Entity.PlayerState = class PlayerState { * * 50 - 90: Extremely healthy * * 90 - : Unnaturally healthy */ - condition: 0, + condition: 60, /** your short term health damage, used to determine how long you are in recovery */ shortDamage: 0, /** your long term health damage */ diff --git a/src/player/managePersonalAffairs.js b/src/player/managePersonalAffairs.js index 88f697727424cf629b3eaed3c6bb3c8ede1ddd5a..3e628bbd5c7effeb14e07fe44d0571ed07865a00 100644 --- a/src/player/managePersonalAffairs.js +++ b/src/player/managePersonalAffairs.js @@ -78,8 +78,10 @@ App.UI.managePersonalAffairs = function() { App.Events.addParagraph(appearanceDiv, text); text = []; - // text.push(doctor()); - text.push(surgeon()); + if (isMovable(PC)) { + text.push(doctor()); + text.push(surgeon()); + } if (hasAnyArms(PC)) { text.push(salon()); } @@ -93,11 +95,9 @@ App.UI.managePersonalAffairs = function() { if (V.doctor.state > 0) { text.push(App.UI.DOM.passageLink(`Consult your doctor`, "Doctor Consultation", () => { - cashX(forceNeg(500), "PCmedical"); })); } else { text.push(App.UI.DOM.passageLink(`Seek out a local doctor`, "Doctor Consultation", () => { - cashX(forceNeg(500), "PCmedical"); })); } App.Events.addNode(doctorDiv, text); @@ -885,7 +885,7 @@ App.UI.managePersonalAffairs = function() { if (PC.pregControl !== "none") { drugsDiv.append(pregDrugs()); } - // drugsDiv.append(aphrodisiacs()); + drugsDiv.append(aphrodisiacs()); return drugsDiv; @@ -935,7 +935,7 @@ App.UI.managePersonalAffairs = function() { V.PC.drugs = "no drugs"; App.UI.DOM.replace(drugsDiv, drugs); })); - if (["breast enhancers", "butt enhancers", "lip enhancers", "penis enlargers", "testicle enlargers", "fertility supplements"].includes(PC.drugs) && V.consumerDrugs === 0) { + if ((["breast enhancers", "butt enhancers", "lip enhancers", "penis enlargers", "testicle enlargers", "fertility supplements"].includes(PC.drugs) && V.consumerDrugs === 0) || (["hip wideners", "detox pills"].includes(PC.drugs))) { App.UI.DOM.appendNewElement("div", playerDrugsDiv, `You will need to visit your doctor to start a new prescription.`, ["indent", "note"]); } } else { @@ -994,29 +994,52 @@ App.UI.managePersonalAffairs = function() { } } if (PC.drugs !== "penis enlargers") { - if (PC.dick < 30) { - links.push(App.UI.DOM.link(`Penis enlargers`, () => { - PC.drugs = "penis enlargers"; - App.UI.DOM.replace(drugsDiv, drugs); - })); - } else { - links.push(App.UI.DOM.disabledLink(`Penis enlargers`, [ - `Penis is too large for the patches to work`, - ])); + if (PC.dick > 0 || PC.vagina >= 0) { + if (PC.dick > 0) { + if (PC.dick < 30) { + links.push(App.UI.DOM.link(`Penis enlargers`, () => { + PC.drugs = "penis enlargers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Penis enlargers`, [ + `Penis is too large for the patches to work`, + ])); + } + } else { + if (PC.clit < 5) { + links.push(App.UI.DOM.link(`Clit enlargers`, () => { + PC.drugs = "penis enlargers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Clit enlargers`, [ + `Clit can't get any bigger`, + ])); + } + } } } if (PC.drugs !== "testicle enlargers") { - if (PC.balls < 125) { - links.push(App.UI.DOM.link(`Testicle enlargers`, () => { - PC.drugs = "testicle enlargers"; - App.UI.DOM.replace(drugsDiv, drugs); - })); - } else { - links.push(App.UI.DOM.disabledLink(`Testicle enlargers`, [ - `Balls are too large for the patches to work`, - ])); + if (PC.balls > 0 && PC.scrotum > 0) { + if (PC.balls < 125) { + links.push(App.UI.DOM.link(`Testicle enlargers`, () => { + PC.drugs = "testicle enlargers"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } else { + links.push(App.UI.DOM.disabledLink(`Testicle enlargers`, [ + `Balls are too large for the patches to work`, + ])); + } } } + if (PC.drugs !== "fertility supplements") { + links.push(App.UI.DOM.link(`Fertility supplements`, () => { + PC.drugs = "fertility supplements"; + App.UI.DOM.replace(drugsDiv, drugs); + })); + } } if (PC.drugs !== "stamina enhancers") {