code:
// 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);

	if (PC.diet !== PCDiet.MEDICINAL) {
		healthBlips();
	}
	illness();
	addiction();
	endWeekHealthDamage(PC);
	health();

	return r.join(" ");

	function healthBlips() {
		if (PC.chem > 5) {
			if (random(1, 220) < (PC.chem * 2) + PC.physicalAge - PC.health.condition) {
				healthDamage(PC, 5);
				switch (random(1, 10)) {
					case 1:
						r.push(`A bout of foreplay was interrupted when your partner discovered a small lump in your ${PC.boobs >= 300 ? "breast" : "chest"}. Your doctor removed it easily enough, for a small fee, with testing revealing it as benign.`);
						cashX(forceNeg(500), "PCmedical");
						break;
					case 2:
						r.push(`A bout of intense vertigo kept you stuck in bed, unwilling to move. Eventually the feeling passes on its own, just as suddenly as it arrived.`);
						break;
					case 3:
						r.push(`You spent the morning experiencing an unshakable sense of dread. Eventually the feeling passes on its own, just as suddenly as it arrived.`);
						break;
					case 4:
						r.push(`You're plagued by a series of severe headaches that are calmed easily enough by a dose of aspirin each.`);
						break;
					case 5:
						r.push(`You experience recurrent nausea each morning this week.`);
						if (PC.preg.isBetween(0, 4)) {
							if (PC.pregKnown === 0) {
								r.push(`It turns out <span class="pregnant">you're pregnant,</span> but it still didn't feel like ${PC.counter.birthsTotal > 0 ? "your morning sickness did last pregnancy" : "morning sickness to you"}.`);
								PC.pregKnown = 1;
							} else {
								r.push(`You have been experiencing morning sickness already, and this is not helping matters.`);
							}
						} else {
							r.push(`Your stomach is soothed with a little medication, but it was still unpleasant.`);
						}
						break;
					case 6:
						r.push(`You had trouble sleeping without taking anything before bed, several nights in a row.`);
						break;
					case 7:
						r.push(`After a vigorous lovemaking session, you discover your heart rate is not coming down. A minor dose of medication resolves it, but it was still alarming.`);
						break;
					case 8:
						r.push(`Much to your dismay, you discover that your blood isn't clotting properly. Eventually the cut stops bleeding on its own, but it does not bode well should anything worse happen to you.`);
						break;
					case 9:
						r.push(`You've developed several ugly little ${PC.skin} skin tags. The autosurgery has everything you need to trivially remove them, but they are still annoying.`);
						break;
					default:
						r.push(`Often you just feel wrong for a short spell before recovering.`);
				}
				r.push(`This likely was <span class="health dec">a side effect</span> of some treatment you've undergone.`);
			}
		}

		if (PC.weight > 190) {
			r.push(`Your extreme obesity <span class="health dec">directly impacts</span> your health, but since you let yourself get this large, it's not really that bothersome.`);
			healthDamage(PC, 2);
			if (random(1, 100 + PC.health.condition) < 5) {
				r.push(`Unfortunately, this week ushered in severe health complications related to it. After extensive, and very costly, heart surgery, your life was saved, though you'd better set aside some ¤ for when it happens again.`);
				cashX(forceNeg(15000), "PCmedical");
				healthDamage(PC, 80);
			}
		} else if (PC.weight > 160) {
			if (random(1, 150 + PC.health.condition) < 5) {
				r.push(`Your obesity has brought severe health complications upon you this week. They required extensive, and costly, surgery to correct, so it may be time to pay more mind to your wellbeing.`);
				cashX(forceNeg(5000), "PCmedical");
				healthDamage(PC, 40);
			}
		} else if (PC.weight > 130) {
			if (random(1, 175 + PC.health.condition) < 5) {
				r.push(`Your weight caused you some <span class="health dec">severe health complications</span> this week. They passed after some time, but are rather concerning.`);
				healthDamage(PC, 20);
			}
		} else if (PC.weight > 95) {
			if (random(1, 200 + PC.health.condition) < 5) {
				r.push(`Your weight caused you some <span class="health dec">minor health complications</span> this week. It passed quickly enough, and shouldn't be a real problem.`);
				healthDamage(PC, 5);
			}
		}
	}

	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 === PCDiet.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, unsure if you are alive or not and unwilling to approach you to find out, 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 ${addA(sicknessDegree[PCH.illness])} 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 positive effect on one's well-being${V.personalAttention.task === PersonalAttention.RELAX ? ", especially when focusing on rest and relaxation" : ""}. 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.inflationType === InflationLiquid.APHRO) {
				r.push(`You don't mind cutting back on the aphrodisiac pills when your gut is laden with the stuff.`);
			} 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 {
				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 {
			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;
				}
			}
		}
	}
};

repo_name: Ducati/fc

license: mit


code:
App.EndWeek.Player.hormones = function(PC, selfManufactured, hormonePower) {
	const r = [];

	const gigantomastiaMod = PC.geneticQuirks.gigantomastia === 2 ? (PC.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
	const rearLipedemaMod = PC.geneticQuirks.rearLipedema === 2 ? 1 : 0;
	const boobSize = App.Medicine.fleshSize(PC, 'boobs');
	const buttSize = App.Medicine.fleshSize(PC, 'butt');
	let normBreasts;
	let normButt;
	const faceValue = PC.face - PC.faceImplant;
	const effects = [];
	/** @type {FC.Zeroable<string>} */
	let faceShape = 0;
	let faceInc = 0;

	hormoneBalance();
	if (V.hormoneUpgradeMood === 0 || !selfManufactured) {
		moodConflict();
	}
	if (PC.physicalAge >= 18 || V.loliGrow === 0 || PC.geneMods.NCS === 1 || V.playerAging < 2) {
		hormonesEffects();
	}

	return r.join(" ");

	function hormoneBalance() {
		if (PC.hormoneBalance <= -400) {
			r.push(`You are overflowing with masculine hormones`);
			if (PC.hormones === 1) {
				r.push(`and taking female ones in an attempt to balance things out.`);
			} else if (PC.hormones === -1) {
				r.push(r.pop() + `, supported through your continued use of artificial ones.`);
			} else {
				r.push(r.pop() + `, but lack the means to maintain such a state and will slowly regress to a more normal balance over time.`);
			}
		} else if (PC.hormoneBalance <= -300) {
			r.push(`Your system is completely flooded with male hormones`);
		} else if (PC.hormoneBalance <= -200) {
			r.push(`Your body is awash with masculine hormones`);
		} else if (PC.hormoneBalance <= -100) {
			r.push(`Your hormone balance is overly masculine`);
		} else if (PC.hormoneBalance < -20) {
			if (PC.hormones === 0 && PC.genes === GenderGenes.MALE) {
				r.push(`Your hormone balance is normal.`);
			} else {
				r.push(`You have a masculine hormone balance`);
				if (PC.hormones === 1) {
					r.push(r.pop() + `, but are taking female ones in an attempt to become feminine.`);
				} else if (PC.hormones === -1) {
					r.push(`being supplemented by your use of artificial hormones.`);
				} else {
					r.push(r.pop() + `.`);
				}
			}
		} else if (PC.hormoneBalance >= 400) {
			r.push(`You are overflowing with feminine hormones`);
			if (PC.hormones === -1) {
				r.push(`and taking male ones in an attempt to balance things out.`);
			} else if (PC.hormones === 1) {
				r.push(r.pop() + `, supported through your continued use of artificial ones.`);
			} else {
				r.push(r.pop() + `, but lack the means to maintain such a state and will slowly regress to a more normal balance over time.`);
			}
		} else if (PC.hormoneBalance >= 300) {
			r.push(`Your system is completely flooded with female hormones`);
		} else if (PC.hormoneBalance >= 200) {
			r.push(`Your body is awash with feminine hormones`);
		} else if (PC.hormoneBalance >= 100) {
			r.push(`Your hormone balance is overly feminine`);
		} else if (PC.hormoneBalance > 20) {
			if (PC.hormones === 0 && PC.genes === GenderGenes.FEMALE) {
				r.push(`Your hormone balance is normal.`);
			} else {
				r.push(`You have a feminine hormone balance`);
				if (PC.hormones === -1) {
					r.push(r.pop() + `, but are taking male ones in an attempt to become more masculine.`);
				} else if (PC.hormones === 1) {
					r.push(`being supplemented by your use of artificial hormones.`);
				} else {
					r.push(r.pop() + `.`);
				}
			}
		} else {
			r.push(`Your hormone balance is very androgynous`);
			if (PC.hormones === -1) {
				r.push(r.pop() + `, but you are taking male hormones in an attempt to become more masculine.`);
			} else if (PC.hormones === 1) {
				r.push(r.pop() + `, but you are taking female hormones in an attempt to become more feminine.`);
			} else {
				r.push(r.pop() + `.`);
			}
		}
		if (PC.hormoneBalance > -400 && PC.hormoneBalance <= -100) {
			if (PC.hormones === 1) {
				r.push(r.pop() + `, but you are taking female ones in an attempt to balance things out.`);
			} else if (PC.hormones === -1) {
				r.push(`and further bolstered by your use of artificial ones.`);
			} else {
				r.push(r.pop() + `, but will slowly regress to a more normal balance unless supplemented.`);
			}
		} else if (PC.hormoneBalance < 400 && PC.hormoneBalance >= 100) {
			if (PC.hormones === -1) {
				r.push(r.pop() + `, but you are taking male ones in an attempt to balance things out.`);
			} else if (PC.hormones === 1) {
				r.push(`and further bolstered by your use of artificial ones.`);
			} else {
				r.push(r.pop() + `, but will slowly regress to a more normal balance unless supplemented.`);
			}
		}
	}

	function moodConflict() {
		if ((PC.hormoneBalance > 20 && PC.genes === GenderGenes.MALE && PC.balls !== 0 && PC.ballType !== "sterile") || (PC.hormoneBalance < -20 && PC.genes === GenderGenes.FEMALE && (PC.ovaries !== 0 || PC.mpreg !== 0))) {
			r.push(`Your altered hormonal balance conflicts with your natural hormones, causing occasional moodiness.`);
			if (PC.energy > 10) {
				r.push(`These clashing hormones also have the frustrating effect of <span class="libido dec">disrupting your sex drive.</span>`);
				PC.energy--;
			}
		}
	}

	function hormonesEffects() {
		if (Math.abs(PC.hormoneBalance) >= 50) {
			if (PC.hormoneBalance > 30 && PC.geneMods.NCS !== 1) {
				const slimModBreasts = (V.arcologies[0].FSSlimnessEnthusiastFoodLaw === 1 && !canEatFood(PC)) ? 0.45 : 1; // 600 average breast target, 270 target, 475 @ 350 hormone
				const slimModButts = (V.arcologies[0].FSSlimnessEnthusiastFoodLaw === 1 && !canEatFood(PC)) ? 0.6 : 1; // 2.5 average butt, 1.5 target
				/* 'Expected' breast size based on weight for feminine-bodied player. Masculine-bodied takes a small hit. */
				normBreasts = Math.trunc((100 + (PC.weight + 100) * 5 + 2 * PC.lactationAdaptation) * (0.85 + PC.hormoneBalance / 400) * gigantomastiaMod * slimModBreasts / Math.max(PC.title * 1.25, 1));
				normButt = ((PC.weight + 100) * 0.025 * (0.9 + PC.hormoneBalance / 600) * (rearLipedemaMod / 2 + 1) * slimModButts / Math.max(PC.title * 1.10, 1));
			}

			if (PC.hormoneBalance >= 350) {
				if (PC.geneMods.NCS === 1) {
					if ((PC.shoulders + Math.abs(PC.shouldersImplant)) > -1 && PC.shoulders > -2 && random(1, 100) < (40 + (20 * hormonePower))) {
						effects.push(`<span class="change positive">shoulders to narrow`);
						PC.shoulders--;
					}
				} else if (PC.physicalAge < 25) {
					if (PC.shoulders + Math.abs(PC.shouldersImplant) > -1 && PC.shoulders > -2 && random(1, 100) < 20 + (10 * hormonePower)) {
						effects.push(`<span class="change positive">shoulders to narrow`);
						PC.shoulders--;
					}
					if (PC.geneMods.NCS === 0 && PC.hips - (Math.abs(PC.hipsImplant)) < 1 && PC.hips < 2 && random(1, 100) <= 20 + (10 * hormonePower)) {
						effects.push(`<span class="change positive">hips to widen`);
						PC.hips++;
					}
				}

				if (PC.faceImplant < 5) {
					if (PC.faceShape === FaceShape.MASC) {
						faceShape = FaceShape.ANDRO;
					} else if (PC.faceShape === FaceShape.ANDRO && PC.geneticQuirks.androgyny !== 2) {
						faceShape = FaceShape.NORMAL;
					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === FaceShape.NORMAL) {
						faceShape = FaceShape.CUTE;
					}
				}
				if (faceValue < 50 && PC.face < 75) {
					effects.push(`<span class="change positive">facial structure to soften`);
					faceInc = 1 + hormonePower;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						faceInc *= 2;
					}
					faceIncreaseAction(PC, faceInc);
				}

				if (PC.voice.isBetween(0, 3)) {
					effects.push(`<span class="change positive">voice to heighten`);
					PC.voice++;
				}

				if (PC.muscles > 10 && PC.diet !== PCDiet.MUSCLE && PC.drugs !== Drug.STEROID && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
					effects.push(`<span class="change negative">muscles to lose mass`);
					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					}
				}
				if (PC.waist > -30) {
					effects.push(`<span class="change positive">waist to narrow`);
					PC.waist = Math.clamp(PC.waist - (2 + hormonePower), -30, 100);
				}

				if (PC.geneMods.NCS === 0) {
					if (boobSize < 0.9 * normBreasts) {
						/* Grow to 90% of normBreasts */
						effects.push(`<span class="change positive">breasts to slightly grow`);
						PC.boobs += 25;
					}
					if (PC.nipples === NippleShape.TINY) {
						effects.push(`<span class="change positive">tiny nipples to enlarge`);
						PC.nipples = NippleShape.CUTE;
					}
					if (buttSize < Math.trunc(4.5 * normButt) / 5) {
						/* 90% of normButt, rounded down to the next increment of .2 */
						effects.push(`<span class="change positive">butt to swell`);
						PC.butt += 0.2;
					}
				}
				if (PC.vagina !== -1 && PC.ovaries !== 0 && PC.vaginaLube < 2) {
					effects.push(`<span class="change positive">pussy to produce more lubricant`);
					PC.vaginaLube++;
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (PC.dick > 1) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.dick > 2) {
							effects.push(`<span class="change negative">dick to greatly shrink`);
							PC.dick -= 1;
						} else {
							effects.push(`<span class="change negative">dick to shrink`);
						}
						PC.dick--;
					}
					if (PC.balls > 1) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.balls > 2) {
							effects.push(`<span class="change negative">testicles to heavily atrophy`);
							PC.balls -= 1;
						} else {
							effects.push(`<span class="change negative">testicles to atrophy`);
						}
						PC.balls--;
					}
					if (PC.clit > 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.clit > 1) {
							effects.push(`<span class="change negative">clit to greatly shrink`);
							PC.clit -= 1;
						} else {
							effects.push(`<span class="change negative">clit to shrink`);
						}
						PC.clit--;
					}
				}
			} else if (PC.hormoneBalance >= 300) {
				if (PC.faceImplant < 5) {
					if (PC.faceShape === FaceShape.MASC) {
						faceShape = FaceShape.ANDRO;
					} else if (PC.faceShape === FaceShape.ANDRO && PC.geneticQuirks.androgyny !== 2) {
						faceShape = FaceShape.NORMAL;
					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === FaceShape.NORMAL) {
						faceShape = FaceShape.CUTE;
					}
				}
				if (faceValue < 30 && PC.face < 60) {
					effects.push(`<span class="change positive">facial structure to soften`);
					faceInc = 1 + hormonePower;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						faceInc *= 2;
					}
					faceIncreaseAction(PC, faceInc);
				}

				if (PC.voice.isBetween(0, 3)) {
					effects.push(`<span class="change positive">voice to heighten`);
					PC.voice++;
				}

				if (PC.muscles > 30 && PC.diet !== PCDiet.MUSCLE && PC.drugs !== Drug.STEROID && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
					effects.push(`<span class="change negative">muscles to lose mass`);
					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					}
				}
				if (PC.waist > -10) {
					effects.push(`<span class="change positive">waist to narrow`);
					PC.waist = Math.clamp(PC.waist - (2 + hormonePower), -10, 100);
				}

				if (PC.geneMods.NCS === 0) {
					if (boobSize < 0.8 * normBreasts) {
						/* Grow to 80% of expected */
						effects.push(`<span class="change positive">breasts to slightly grow`);
						PC.boobs += 25;
					}
					if (PC.nipples === NippleShape.TINY) {
						effects.push(`<span class="change positive">tiny nipples to enlarge`);
						PC.nipples = NippleShape.CUTE;
					}
					if (buttSize < Math.trunc(4 * normButt) / 5) {
						/* 80% of normButt, rounded down to the next increment of .2 */
						effects.push(`<span class="change positive">butt to swell`);
						PC.butt += 0.2;
					}
				}
				if (PC.vagina !== -1 && PC.ovaries !== 0 && PC.vaginaLube < 2) {
					effects.push(`<span class="change positive">pussy to produce more lubricant`);
					PC.vaginaLube++;
				}

				if (V.hormoneUpgradeShrinkage === 0) {
					if (PC.dick > 1) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.dick > 2) {
							effects.push(`<span class="change negative">dick to greatly shrink`);
							PC.dick -= 1;
						} else {
							effects.push(`<span class="change negative">dick to shrink`);
						}
						PC.dick--;
					}
					if (PC.balls > 1) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.balls > 2) {
							effects.push(`<span class="change negative">testicles to heavily atrophy`);
							PC.balls -= 1;
						} else {
							effects.push(`<span class="change negative">testicles to atrophy`);
						}
						PC.balls--;
					}
					if (PC.clit > 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.clit > 1) {
							effects.push(`<span class="change negative">clit to greatly shrink`);
							PC.clit -= 1;
						} else {
							effects.push(`<span class="change negative">clit to shrink`);
						}
						PC.clit--;
					}
				}
			} else if (PC.hormoneBalance >= 250) {
				if (PC.faceImplant < 5) {
					if (PC.faceShape === FaceShape.MASC) {
						faceShape = FaceShape.ANDRO;
					} else if (PC.faceShape === FaceShape.ANDRO && PC.geneticQuirks.androgyny !== 2) {
						faceShape = FaceShape.NORMAL;
					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === FaceShape.NORMAL) {
						faceShape = FaceShape.CUTE;
					}
				}
				if (faceValue < 10 && PC.face < 30) {
					effects.push(`<span class="change positive">facial structure to soften`);
					faceInc = 1 + hormonePower;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						faceInc *= 2;
					}
					faceIncreaseAction(PC, faceInc);
				}

				if (PC.voice.isBetween(0, 2)) {
					effects.push(`<span class="change positive">voice to heighten`);
					PC.voice++;
				}

				if (PC.muscles > 30 && PC.diet !== PCDiet.MUSCLE && PC.drugs !== Drug.STEROID && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
					effects.push(`<span class="change negative">muscles to lose mass`);
					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					}
				}
				if (PC.waist > 0) {
					effects.push(`<span class="change positive">waist to narrow`);
					PC.waist = Math.clamp(PC.waist - (2 + hormonePower), 0, 100);
				}

				if (PC.geneMods.NCS === 0) {
					if (boobSize < 0.7 * normBreasts) {
						/* Grow to 70% of expected */
						effects.push(`<span class="change positive">breasts to slightly grow`);
						PC.boobs += 25;
					}
					if (PC.nipples === NippleShape.TINY) {
						effects.push(`<span class="change positive">tiny nipples to enlarge`);
						PC.nipples = NippleShape.CUTE;
					}
					if (buttSize < Math.trunc(3.5 * normButt) / 5) {
						/* 70% of normButt, rounded down to the next increment of .2 */
						effects.push(`<span class="change positive">butt to swell`);
						PC.butt += 0.2;
					}
				}
				if (PC.vagina !== -1 && PC.ovaries !== 0 && PC.vaginaLube < 1) {
					effects.push(`<span class="change positive">pussy to produce more lubricant`);
					PC.vaginaLube++;
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (PC.dick > 2) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">dick to greatly shrink`);
							PC.dick -= 1;
						} else {
							effects.push(`<span class="change negative">dick to shrink`);
						}
						PC.dick--;
					}
					if (PC.balls > 2) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">testicles to heavily atrophy`);
							PC.balls -= 1;
						} else {
							effects.push(`<span class="change negative">testicles to atrophy`);
						}
						PC.balls--;
					}
					if (PC.clit > 1) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">clit to greatly shrink`);
							PC.clit -= 1;
						} else {
							effects.push(`<span class="change negative">clit to shrink`);
						}
						PC.clit--;
					}
				}
			} else if (PC.hormoneBalance >= 200) {
				if (PC.faceImplant < 5) {
					if (PC.faceShape === FaceShape.MASC) {
						faceShape = FaceShape.ANDRO;
					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === FaceShape.ANDRO && PC.geneticQuirks.androgyny !== 2) {
						faceShape = FaceShape.NORMAL;
					}
				}
				if (faceValue < 0 && PC.face < 0) {
					r.push(`<span class="change positive">facial structure to soften`);
					faceInc = 1 + hormonePower;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						faceInc *= 2;
					}
					faceIncreaseAction(PC, faceInc);
				}

				if (PC.voice.isBetween(0, 2)) {
					r.push(`<span class="change positive">voice to heighten`);
					PC.voice++;
				}

				if (PC.muscles > 30 && PC.diet !== PCDiet.MUSCLE && PC.drugs !== Drug.STEROID && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
					r.push(`<span class="change negative">muscles to lose mass`);
					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
					}
				}
				if (PC.waist > 10) {
					r.push(`<span class="change positive">waist to narrow`);
					PC.waist = Math.clamp(PC.waist - (2 + hormonePower), 10, 100);
				}

				if (PC.geneMods.NCS === 0) {
					if (boobSize < 0.6 * normBreasts) {
						/* Grow to 60% of expected */
						effects.push(`<span class="change positive">breasts to slightly grow`);
						PC.boobs += 25;
					}
					if (PC.nipples === NippleShape.TINY) {
						effects.push(`<span class="change positive">tiny nipples to enlarge`);
						PC.nipples = NippleShape.CUTE;
					}
					if (buttSize < Math.trunc(3 * normButt) / 5) {
						/* 60% of normButt, rounded down to the next increment of .2 */
						effects.push(`<span class="change positive">butt to swell`);
						PC.butt += 0.2;
					}
				}
				if (PC.vagina !== -1 && PC.ovaries !== 0 && PC.vaginaLube < 1) {
					effects.push(`<span class="change positive">pussy to produce more lubricant`);
					PC.vaginaLube++;
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (PC.dick > 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">dick to greatly shrink`);
							PC.dick -= 1;
						} else {
							effects.push(`<span class="change negative">dick to shrink`);
							PC.dick--;
						}
					}
					if (PC.balls > 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">testicles to heavily atrophy`);
							PC.balls -= 1;
						} else {
							effects.push(`<span class="change negative">testicles to atrophy`);
						}
						PC.balls--;
					}
					if (PC.clit > 2) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">clit to greatly shrink`);
							PC.clit -= 1;
						} else {
							effects.push(`<span class="change negative">clit to shrink`);
						}
						PC.clit--;
					}
				}
			} else if (PC.hormoneBalance >= 100) {
				if (PC.faceImplant < 5) {
					if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === FaceShape.MASC) {
						faceShape = FaceShape.ANDRO;
					}
				}

				if (PC.geneMods.NCS === 0) {
					if (boobSize < 0.5 * normBreasts) {
						/* Grow to 50% of expected */
						r.push(`<span class="change positive">breasts to slightly grow`);
						PC.boobs += 25;
					}
				}
			} else if (PC.hormoneBalance >= 50) {
				// possible attraction stuff here
			} else if (PC.hormoneBalance <= -350) {
				if (PC.geneMods.NCS === 1) {
					if (PC.hips + Math.abs(PC.hipsImplant) > -1 && PC.hips > -2 && (random(1, 100) <= 20 + (10 * hormonePower))) {
						effects.push(`<span class="change positive">hips to narrow`);
						PC.hips--;
					}
				} else if (PC.physicalAge < 25) {
					if ((PC.shoulders - (Math.abs(PC.shouldersImplant)) < 1) && (PC.shoulders < 2) && (random(1, 100) < 20 + (10 * hormonePower))) {
						effects.push(`<span class="change positive">shoulders to widen`);
						PC.shoulders++;
					}
					if ((PC.hips + (Math.abs(PC.hipsImplant)) > -1) && (PC.hips > -2) && (random(1, 100) <= 20 + (10 * hormonePower))) {
						effects.push(`<span class="change positive">hips to narrow`);
						PC.hips--;
					}
				}

				if (PC.geneMods.NCS === 0) {
					if (PC.faceImplant < 5) {
						if (PC.geneticQuirks.androgyny !== 2) {
							if (PC.faceShape === FaceShape.ANDRO) {
								faceShape = FaceShape.MASC;
							} else if (PC.faceShape !== FaceShape.MASC) {
								faceShape = FaceShape.ANDRO;
							}
						}
					}
					if (faceValue.isBetween(0, 100)) {
						effects.push(`<span class="change positive">facial structure to harden`);
						const faceDec = 1 + hormonePower;
						PC.face = Math.clamp(PC.face - faceDec, -100, 100);
					}
					if (PC.voice > 1) {
						effects.push(`<span class="change positive">voice to deepen`);
						PC.voice--;
					}
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (buttSize > 1 && rearLipedemaMod === 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && buttSize > 2) {
							effects.push(`<span class="change negative">butt to greatly diminish`);
							PC.butt--;
						} else {
							effects.push(`<span class="change negative">butt to diminish`);
						}
						PC.butt--;
					}
					if (boobSize > 100 * gigantomastiaMod && gigantomastiaMod !== 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && boobSize > 200) {
							effects.push(`<span class="change negative">breasts to shrink`);
							PC.boobs -= 10 + (15 * hormonePower);
						} else {
							effects.push(`<span class="change negative">breasts to slightly shrink`);
						}
						PC.boobs -= 10 + (15 * hormonePower);
					}
				}
				if (PC.geneMods.NCS === 1 && PC.nipples === NippleShape.TINY) {
					/* nothing, just don't advance to cute */
				} else if (PC.nipples !== NippleShape.TINY && PC.nipples !== NippleShape.FUCKABLE && PC.nipples !== NippleShape.FLAT) {
					effects.push(`<span class="change positive">nipples to become more masculine`);
					PC.nipples = NippleShape.TINY;
				}

				if (PC.geneMods.NCS === 0) {
					if (PC.dick.isBetween(0, 5)) {
						effects.push(`<span class="change positive">dick to swell`);
						PC.dick++;
					}
					if (PC.balls.isBetween(0, 5)) {
						effects.push(`<span class="change positive">balls to grow`);
						PC.balls++;
					}

					if (PC.clit < 5 && PC.dick === 0 && PC.vagina !== -1) {
						effects.push(`<span class="change positive">clit to swell`);
						PC.clit++;
					}
					if (PC.vagina > -1 && PC.vaginaLube > 0) {
						effects.push(`<span class="change negative">vagina to dry out`);
						PC.vaginaLube--;
					}

					if (PC.muscles <= 50 && PC.diet !== PCDiet.SLIM) {
						effects.push(`<span class="change negative">muscles to gain mass`);
						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
					}
					if (PC.waist < 80) {
						effects.push(`<span class="change positive">waist to broaden`);
						PC.waist = Math.clamp(PC.waist + 2 + hormonePower, -100, 80);
					}
				}
			} else if (PC.hormoneBalance <= -300) {
				if (PC.geneMods.NCS === 0) {
					if (PC.faceImplant < 5) {
						if (PC.geneticQuirks.androgyny !== 2) {
							if (PC.faceShape === FaceShape.ANDRO) {
								faceShape = FaceShape.MASC;
							} else if (PC.faceShape !== FaceShape.MASC) {
								faceShape = FaceShape.ANDRO;
							}
						}
					}

					if (PC.voice > 1) {
						effects.push(`<span class="change positive">voice to deepen`);
						PC.voice--;
					}
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (buttSize > 1 && rearLipedemaMod === 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && buttSize > 2) {
							effects.push(`<span class="change negative">butt to greatly diminish`);
							PC.butt--;
						} else {
							effects.push(`<span class="change negative">butt to diminish`);
						}
						PC.butt--;
					}
					if (boobSize > 300 * gigantomastiaMod && gigantomastiaMod !== 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">breasts to shrink`);
							PC.boobs -= 10 + (15 * hormonePower);
						} else {
							effects.push(`<span class="change negative">breasts to slightly shrink`);
						}
						PC.boobs -= 10 + (15 * hormonePower);
					}
				}
				if (PC.geneMods.NCS === 1 && PC.nipples === NippleShape.TINY) {
					/* nothing, just don't advance to cute */
				} else if (PC.nipples !== NippleShape.TINY && PC.nipples !== NippleShape.FUCKABLE && PC.nipples !== NippleShape.FLAT) {
					effects.push(`<span class="change positive">nipples to become more masculine`);
					PC.nipples = NippleShape.TINY;
				}

				if (PC.geneMods.NCS === 0) {
					if (PC.dick.isBetween(0, 5)) {
						effects.push(`<span class="change positive">dick to swell`);
						PC.dick++;
					}
					if (PC.balls.isBetween(0, 5) && PC.ballType !== "sterile") {
						effects.push(`<span class="change positive">balls to grow`);
						PC.balls++;
					}

					if (PC.clit < 4 && PC.dick === 0 && PC.vagina !== -1) {
						effects.push(`<span class="change positive">clit to swell`);
						PC.clit++;
					}
					if (PC.vagina > -1 && PC.vaginaLube > 0) {
						effects.push(`<span class="change negative">vagina to dry out`);
						PC.vaginaLube--;
					}

					if (PC.muscles <= 50 && PC.diet !== PCDiet.SLIM) {
						effects.push(`<span class="change negative">muscles to gain mass`);
						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
					}
					if (PC.waist < 40) {
						effects.push(`<span class="change positive">waist to broaden`);
						PC.waist = Math.clamp(PC.waist + 2 + hormonePower, -100, 40);
					}
				}
			} else if (PC.hormoneBalance <= -250) {
				if (PC.geneMods.NCS === 0) {
					if (PC.faceImplant < 5) {
						if (PC.faceShape !== FaceShape.MASC && PC.faceShape !== FaceShape.ANDRO) {
							faceShape = FaceShape.ANDRO;
						}
					}

					if (PC.voice > 1) {
						effects.push(`<span class="change positive">voice to deepen`);
						PC.voice--;
					}
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (buttSize > 2 && rearLipedemaMod === 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">butt to greatly diminish`);
							PC.butt--;
						} else {
							effects.push(`<span class="change negative">butt to diminish`);
						}
						PC.butt--;
					}
					if (boobSize > 400 * gigantomastiaMod && gigantomastiaMod !== 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">breasts to shrink`);
							PC.boobs -= 10 + (15 * hormonePower);
						} else {
							effects.push(`<span class="change negative">breasts to slightly shrink`);
						}
						PC.boobs -= 10 + (15 * hormonePower);
					}
				}
				if (PC.geneMods.NCS === 1 && PC.nipples === NippleShape.TINY) {
					/* nothing, just don't advance to cute */
				} else if (PC.nipples !== NippleShape.TINY && PC.nipples !== NippleShape.FUCKABLE && PC.nipples !== NippleShape.FLAT) {
					effects.push(`<span class="change positive">nipples to become more masculine`);
					PC.nipples = NippleShape.TINY;
				}

				if (PC.geneMods.NCS === 0) {
					if (PC.dick.isBetween(0, 4)) {
						effects.push(`<span class="change positive">dick to swell`);
						PC.dick++;
					}
					if (PC.balls.isBetween(0, 4) && PC.ballType !== "sterile") {
						effects.push(`<span class="change positive">balls to grow`);
						PC.balls++;
					}

					if (PC.clit < 3 && PC.dick === 0 && PC.vagina !== -1) {
						effects.push(`<span class="change positive">clit to swell`);
						PC.clit++;
					}
					if (PC.vagina > -1 && PC.vaginaLube > 0) {
						effects.push(`<span class="change negative">vagina to dry out`);
						PC.vaginaLube--;
					}

					if (PC.muscles <= 35 && PC.diet !== PCDiet.SLIM) {
						effects.push(`<span class="change negative">muscles to gain mass`);
						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
					}
					if (PC.waist < 25) {
						effects.push(`<span class="change positive">waist to broaden`);
						PC.waist = Math.clamp(PC.waist + 2 + hormonePower, -100, 25);
					}
				}
			} else if (PC.hormoneBalance <= -200) {
				if (PC.geneMods.NCS === 0) {
					if (PC.faceImplant < 5) {
						if (PC.faceShape !== FaceShape.MASC && PC.faceShape !== FaceShape.ANDRO) {
							faceShape = FaceShape.ANDRO;
						}
					}

					if (PC.voice > 2) {
						effects.push(`<span class="change positive">voice to deepen`);
						PC.voice--;
					}
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (buttSize > 3 && rearLipedemaMod === 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">butt to greatly diminish`);
							PC.butt--;
						} else {
							effects.push(`<span class="change negative">butt to diminish`);
						}
						PC.butt--;
					}
					if (boobSize > 600 * gigantomastiaMod && gigantomastiaMod !== 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">breasts to shrink`);
							PC.boobs -= 10 + (15 * hormonePower);
						} else {
							effects.push(`<span class="change negative">breasts to slightly shrink`);
						}
						PC.boobs -= 10 + (15 * hormonePower);
					}
				}
				if (PC.nipples === NippleShape.HUGE || PC.nipples === NippleShape.PUFFY) {
					effects.push(`<span class="change positive">nipples to become more masculine`);
					PC.nipples = NippleShape.CUTE;
				}

				if (PC.geneMods.NCS === 0) {
					if (PC.dick.isBetween(0, 3)) {
						effects.push(`<span class="change positive">dick to swell`);
						PC.dick++;
					}
					if (PC.balls.isBetween(0, 3) && PC.ballType !== "sterile") {
						effects.push(`<span class="change positive">balls to grow`);
						PC.balls++;
					}

					if (PC.clit < 2 && PC.dick === 0 && PC.vagina !== -1) {
						effects.push(`<span class="change positive">clit to swell`);
						PC.clit++;
					}
					if (PC.vagina > -1 && PC.vaginaLube > 0) {
						effects.push(`<span class="change negative">vagina to dry out`);
						PC.vaginaLube--;
					}

					if (PC.muscles <= 15 && PC.diet !== PCDiet.SLIM) {
						effects.push(`<span class="change negative">muscles to gain mass`);
						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
					}
					if (PC.waist < 9) {
						effects.push(`<span class="change positive">waist to broaden`);
						PC.waist = Math.clamp(PC.waist + 2 + hormonePower, -100, 9);
					}
				}
			} else if (PC.hormoneBalance <= -100) {
				if (PC.geneMods.NCS === 0) {
					if (PC.voice > 2) {
						effects.push(`<span class="change positive">voice to deepen`);
						PC.voice--;
					}
				}

				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
					if (buttSize > 4 && rearLipedemaMod === 0) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">butt to greatly diminish`);
							PC.butt--;
						} else {
							effects.push(`<span class="change negative">butt to diminish`);
						}
						PC.butt--;
					}
					if (boobSize > 800 * gigantomastiaMod && gigantomastiaMod !== 3) {
						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
							effects.push(`<span class="change negative">breasts to shrink`);
							PC.boobs -= 10 + (15 * hormonePower);
						} else {
							effects.push(`<span class="change negative">breasts to slightly shrink`);
						}
						PC.boobs -= 10 + (15 * hormonePower);
					}
				}

				if (PC.geneMods.NCS === 0) {
					if (PC.muscles < 0 && PC.diet !== PCDiet.SLIM) {
						effects.push(`<span class="change negative">muscles to gain mass`);
						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
					}

					if (PC.waist < 0) {
						effects.push(`<span class="change positive">waist to broaden`);
						PC.waist = Math.clamp(PC.waist + 2 + hormonePower, -100, 0);
					}

					if (PC.dick.isBetween(0, 2)) {
						effects.push(`<span class="change positive">dick to grow`);
						PC.dick++;
					}
					if (PC.balls.isBetween(0, 2)) {
						effects.push(`<span class="change positive">balls to drop`);
						PC.balls++;
					}

					if (PC.clit < 1 && PC.dick === 0 && PC.vagina >= 0) {
						effects.push(`<span class="change positive">clit to swell`);
						PC.clit++;
					}
					if (PC.vagina > -1 && PC.vaginaLube > 1) {
						effects.push(`<span class="change negative">vagina to dry out`);
						PC.vaginaLube--;
					}
				}
			} else if (PC.hormoneBalance <= -50) {
				// possible attraction stuff here
			}
		}

		if (effects.length > 0) {
			r.push(`Hormonal effects cause your`);
			r.push(effectsListToText(effects));
			r.push(`${r.pop()}.</span>`);
		}
		if (faceShape !== 0) {
			if (effects.length > 0) {
				r.push(`More importantly, they cause`);
			} else {
				r.push(`Hormonal effects cause`);
			}
			if (PC.faceShape === FaceShape.MASC && faceShape === FaceShape.ANDRO) {
				r.push(`<span class="change positive">your face to soften into a state of`);
				if (PC.geneMods.NCS === 1) {
					r.push(`childlike`);
				}
				r.push(`androgyny.</span>`);
			} else if (PC.faceShape === FaceShape.ANDRO && faceShape === FaceShape.NORMAL) {
				r.push(`<span class="change positive">your face to soften into`);
				if (PC.geneMods.NCS === 1) {
					r.push(`childlike normalcy.</span>`);
				} else {
					r.push(`femininity.</span>`);
				}
			} else if (PC.faceShape === FaceShape.ANDRO && faceShape === FaceShape.MASC) {
				r.push(`<span class="change negative">your face to harden into masculinity.</span>`);
			} else if (PC.faceShape === FaceShape.NORMAL && faceShape === FaceShape.CUTE) {
				r.push(`<span class="change positive">your face to soften into a state of sheer cuteness.</span>`);
			} else if (PC.faceShape !== FaceShape.MASC && PC.faceShape !== FaceShape.ANDRO && faceShape === FaceShape.ANDRO) {
				r.push(`<span class="change negative">your face to harden into a state of androgyny.</span>`);
			}
			PC.faceShape = faceShape;
		}
		if ((faceValue >= 50 || PC.face >= 75) && faceInc !== 0) {
			r.push(`Your face is has become quite beautiful, though hormonal treatments <span class="noteworthy">are unlikely to be able to improve it further.</span>`);
		}
	}

	function effectsListToText(effectsList) {
		return effectsList.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? '</span> and ' : ',</span> ') + ch);
	}
};


code:
App.EndWeek.Player.inflation = function(PC = V.PC) {
	const r = [];

	const gigantomastiaMod = PC.geneticQuirks.gigantomastia === 2 ? (PC.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
	const boobSize = PC.boobs - PC.boobsImplant - PC.boobsMilk;
	const buttSize = PC.butt - PC.buttImplant;
	const rearLipedemaMod = PC.geneticQuirks.rearLipedema === 2 ? 2 : 0;
	const rearQuirkDivider = rearLipedemaMod === 0 ? 1 : rearLipedemaMod;
	const dairyL = App.Entity.facilities.dairy.employeesIDs().size;
	let distensionTerm;
	let quantityTerm;
	let stateTerm;
	let cow;
	let harvest;

	if (PC.inflationMethod === 3) {
		cow = PC.inflationType === InflationLiquid.MILK ? getSlave(PC.milkSource) : getSlave(PC.cumSource);
	}

	inflationCancellation();
	if (PC.inflation > 0) {
		fillUp();
	}
	if (PC.inflationType === InflationLiquid.MILK || PC.inflationType === InflationLiquid.FOOD) {
		foodMeansFat();
	}
	if (PC.cervixImplant >= 2) {
		cervixImplantFluidConversion();
	}
	// Temp inflation, IE binging in an event, cumflation, etc.
	if (PC.inflation === 0 && PC.inflationType !== InflationLiquid.NONE) {
		bloating();
	}

	return r.join(" ");

	function inflationCancellation() {
		if (PC.inflationType === InflationLiquid.MILK && (PC.inflationMethod === 1 || PC.inflationMethod === 2) && (dairyL === 0 || V.dairy === 0) && V.arcologies[0].FSPastoralistLaw !== 1) {
			r.push(`You no longer have a functional dairy. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
			deflate(PC);
		} else if (PC.inflationType === InflationLiquid.MILK && PC.inflationMethod === 3 && cow.lactation === 0) {
			r.push(`${cow.slaveName} is no longer lactating and thus can no longer satisfy your predilections. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
			deflate(PC);
		} else if (PC.inflationType === InflationLiquid.CUM && (PC.inflationMethod === 1 || PC.inflationMethod === 2) && (dairyL === 0 || cumSlaves().length === 0 || V.dairy === 0) && V.arcologies[0].FSPastoralistLaw !== 1) {
			r.push(`You no longer have a functional cum dairy. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
			deflate(PC);
		} else if (PC.inflationType === InflationLiquid.CUM && PC.inflationMethod === 3 && cow.balls === 0) {
			r.push(`${cow.slaveName} no longer has testicles and thus can no longer satisfy your predilections. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
			deflate(PC);
		} else if (PC.bellyImplant >= 1500 || PC.bellyPreg >= 1500) {
			if (PC.inflationType === "undigested food") {
				if (PC.diet !== PCDiet.WEANING) {
					deflate(PC);
				} else {
					r.push(`You were already feeling full before your diet started backing up inside you; <span class="health dec">now it's just agonizing.</span>`);
					healthDamage(PC, 5);
				}
			} else if (PC.inflation > 1) {
				r.push(`You feel a bit too full already to inflate yourself as large as you'd like, so <span class="yellow">you'll have to settle for a lesser filling.</span>`);
				PC.inflation = 1;
				SetBellySize(PC);
			} else if (PC.inflation > 0) {
				PC.bellyFluid = 2000;
				SetBellySize(PC);
			}
		} else if ((PC.inflationType === InflationLiquid.MILK || PC.inflationType === InflationLiquid.CUM) && PC.inflationMethod === 3) {
			harvest = (PC.inflationType === InflationLiquid.MILK) ? Math.trunc(milkAmount(cow) / 14) : Math.trunc(cumAmount(cow) / 70);
			if (PC.inflation === 3 && harvest < 8) {
				r.push(`${cow.slaveName} is having trouble producing enough ${PC.inflationType} to satisfy`);
				if (harvest < 2) {
					r.push(`you at all. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
				} else if (harvest < 4) {
					r.push(`you, so you'll have to settle for a meager two liters of the stuff.`);
				} else {
					r.push(`you, so you'll have to settle for a mere four liters of the stuff.`);
				}
			} else if (PC.inflation === 2 && harvest < 4) {
				if (harvest < 2) {
					r.push(`you at all. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
				} else {
					r.push(`you, so you'll have to settle for a mere two liters of the stuff.`);
				}
			} else if (PC.inflation === 1 && harvest < 2) {
				r.push(`you at all. <span class="yellow">You are unable continue to inflate yourself by this means.</span>`);
			}
		} else if (PC.inflationType === "undigested food" && PC.diet !== PCDiet.WEANING) {
			if (PC.digestiveSystem === "normal") { // successfully weaned - backup in case cheating player skips weaningDuration 10-13 period
				r.push(`Having weaned yourself from slave food, your strengthened digestive system is finally able to break down the mass of undigested food inside you, leaving you with a flat belly.`);
			} else { // gave up on weaning
				r.push(`Since you started eating slave food again, the food backing up in your system has broken down, once again <span class="yellow">leaving you with a flat belly.</span>`);
			}
			PC.bellyFluid = 0; // necessary because deflate() and SetBellySize() don't handle undigested food
			deflate(PC);
			PC.weaningDuration = 0;
		}
	}

	function fillUp() { // weaning food is not handled here!
		if (PC.inflation === 3) {
			distensionTerm = `leaving you looking ready to burst`;
			quantityTerm = `two gallons`;
			stateTerm = `<span class="health dec">It's painful,</span> yet satisfying, to be so full.`;
		} else if (PC.inflation === 2) {
			distensionTerm = `leaving you looking pregnant`;
			quantityTerm = `four liters`;
			stateTerm = `You're so full, the contents of your distended belly wobble heavily with your every motion.`;
		} else {
			distensionTerm = `leaving your belly noticeably distended`;
			quantityTerm = `two liters`;
			stateTerm = `You feel swollen and heavy, but it's not very visible to others.`;
		}

		switch (PC.inflationType) {
			case InflationLiquid.WATER:
			case InflationLiquid.URINE:
				r.push(`You fill your rear with nearly ${quantityTerm} of ${PC.inflationType} to sate your predilections, ${distensionTerm}, whenever you have the chance. ${stateTerm}`);
				if (PC.inflation === 3) {
					healthDamage(PC, 10);
				}
				break;
			case InflationLiquid.APHRO:
				r.push(`You fill your rear with nearly ${quantityTerm} of an aphrodisiac solution, ${distensionTerm},`);
				if (PC.addict > 0) {
					r.push(`sating your addictive itch for now.`);
				} else {
					r.push(`whenever you have the chance.`);
				}
				r.push(stateTerm);
				if (PC.inflation === 3) {
					r.push(`Having your body packed full of aphrodisiacs speeds up your absorption of them,`);
					healthDamage(PC, 10);
				} else if (PC.inflation === 2) {
					r.push(`Being bloated with aphrodisiacs helps to amplify their effects,`);
				} else if (PC.inflation === 1) {
					r.push(`Allowing your body to directly absorb aphrodisiacs amplifies their effects,`);
				}
				if (PC.energy <= 95) {
					r.push(`<span class="libido inc">sending your sex drive into overdrive.</span>`);
					PC.energy += 5 * PC.inflation;
				} else if (canAchieveErection(PC)) {
					r.push(`leaving you with an insatiable erection and the inability to think of things other than fucking.`);
				} else {
					r.push(`leaving you insatiably horny and unable to think of anything other than sex.`);
				}
				if (V.arcologies[0].FSBodyPuristLaw === 0 && V.healthyDrugsUpgrade === 0) {
					r.push(`Maintaining such a high dosage <span class="health dec">isn't healthy for you.</span>`);
					healthDamage(PC, 5);
				}
				PC.chem += 2 * PC.inflation;
				if (PC.geneticQuirks.galactorrhea === 2 && random(1, 100) < PC.hormoneBalance && PC.lactation === 0) {
					PC.inappropriateLactation = 1;
				}
				if (PC.addict > 0) {
					PC.addict += PC.inflation * 3;
				} else if (jsRandom(1, 100) < 40 + (20 * PC.inflation)) {
					r.push(`One thing is clear now; you need to keep doing this. <span class="cyan">You are now an aphrodisiac addict!</span>`);
					PC.addict = 1;
				}
				break;
			case InflationLiquid.MILK:
				if (PC.inflationMethod === 1) {
					r.push(`You chug nearly`);
				} else if (PC.inflationMethod === 2) {
					r.push(`You fill your rear with nearly`);
				} else if (PC.inflationMethod === 3) {
					r.push(`You suckle from ${cow.slaveName} until you've drank nearly`);
					cow.lactationDuration = 2;
					cow.boobs -= cow.boobsMilk;
					cow.boobsMilk = 0;
				}
				r.push(`${quantityTerm} of ${PC.inflationType} to sate your predilections, ${distensionTerm}, whenever you get the chance. ${stateTerm}`);
				if (PC.inflation === 3) {
					healthDamage(PC, 10);
				}
				break;
			case InflationLiquid.CUM:
				if (PC.inflationMethod === 1) {
					r.push(`You guzzle nearly`);
				} else if (PC.inflationMethod === 2) {
					r.push(`You pump your rear full of nearly`);
				} else if (PC.inflationMethod === 3) {
					r.push(`You suck ${cow.slaveName} off until you've guzzled nearly`);
				}
				r.push(`${quantityTerm} of ${PC.inflationType} to sate your predilections, ${distensionTerm}, whenever you get the chance. ${stateTerm}`);
				if (PC.inflation === 3) {
					healthDamage(PC, 10);
				}
				break;
			case InflationLiquid.FOOD:
				r.push(`You gorge yourself whenever you feel your gut`);
				if (PC.inflation === 3) {
					r.push(`isn't stuffed to bursting with enough food to sate your predilections. ${stateTerm}`);
					healthDamage(PC, 10);
				} else if (PC.inflation === 2) {
					r.push(`isn't stuffed with enough food`);
					// gender overhaul stuff
					if (PC.vagina >= 0) { // female appearance
						r.push(`to give you a prominent food baby to sate your predilections.`);
					} else {
						r.push(`to bulge prominently ahead of you to sate your predilections.`);
					}
					r.push(`You're so full, your distended belly groans angrily as it struggles to digest all that you've eaten.`);
				} else if (PC.inflation === 1) {
					r.push(`isn't stuffed with enough food to be noticeably distended to sate your predilections. ${stateTerm}`);
				}
				break;
		}
	}

	function foodMeansFat() {
		if (PC.inflationType === InflationLiquid.MILK) {
			if (PC.weight < 200) {
				r.push(`Your body <span class="lime">grows a little softer</span> as it absorbs the milk contained in your digestive track.`);
				PC.weight += 2;
				if (PC.weightDirection === 1) {
					PC.weight += 2;
				}
			}
			if (jsRandom(1, 100) > 50 / gigantomastiaMod && boobSize < 3000 * gigantomastiaMod) {
				r.push(`Your breasts <span class="lime">swell</span> with added fat as you digest the milk you've consumed.`);
				PC.boobs += 200;
			}
			if (jsRandom(1, 100) > (50 / rearQuirkDivider) && buttSize < 7 + ((7 / 2) * rearLipedemaMod)) {
				r.push(`Your butt <span class="lime">swells</span> with added fat as you digest the milk you've consumed.`);
				PC.butt += 1;
			}
		} else if (PC.inflationType === InflationLiquid.FOOD) {
			if (PC.weight < 200) {
				r.push(`It should surprise nobody that you <span class="lime">rapidly gain weight</span> with all the binge eating.`);
				PC.weight += 4;
				if (PC.weightDirection === 1) {
					PC.weight += 2;
				}
			}
			if (jsRandom(1, 100) > 50 / gigantomastiaMod && boobSize < 3000 * gigantomastiaMod) {
				r.push(`Your breasts <span class="lime">swell</span> with added fat as your body attempts to handle all the food inside you.`);
				PC.boobs += 200;
			}
			if (jsRandom(1, 100) > (50 / rearQuirkDivider) && buttSize < 7 + ((7 / 2) * rearLipedemaMod)) {
				r.push(`Your butt <span class="lime">swells</span> with added fat as your body attempts to handle all the food inside you.`);
				PC.butt += 1;
			}
		}
	}

	function cervixImplantFluidConversion() {
		if (PC.inflationMethod === 2) {
			r.push(`Your rectal micropump implant filters out some fluid from the ${PC.inflationType} you're holding inside you during the week, <span class="change positive">adding it to your abdominal implant.</span>`);
			PC.bellyImplant += 200;
		}
	}

	function bloating() {
		deflate(PC);
	}
};