From 8dcd6674281888133b60c059e619682738263e5a Mon Sep 17 00:00:00 2001
From: kopareigns <kopareigns@gmail.com>
Date: Sun, 29 Jul 2018 20:10:49 -0400
Subject: [PATCH] JSify CheckForGingering, RemoveGingering, and
 RandomizeAttraction

---
 devNotes/twine JS.txt                    | 173 +++++++++++++++++++++++
 src/js/slaveGenerationJS.tw              | 173 +++++++++++++++++++++++
 src/uncategorized/bulkSlaveGenerate.tw   |   2 +-
 src/uncategorized/bulkSlaveIntro.tw      |   2 +-
 src/uncategorized/generateXXSlave.tw     |   2 +-
 src/uncategorized/generateXYSlave.tw     |   2 +-
 src/uncategorized/lawCompliance.tw       |   2 +-
 src/uncategorized/newSlaveIntro.tw       |   2 +-
 src/uncategorized/reRelativeRecruiter.tw |   4 +-
 src/utility/slaveCreationWidgets.tw      | 150 --------------------
 10 files changed, 354 insertions(+), 158 deletions(-)

diff --git a/devNotes/twine JS.txt b/devNotes/twine JS.txt
index 616717cbfb9..5ecfe65a175 100644
--- a/devNotes/twine JS.txt	
+++ b/devNotes/twine JS.txt	
@@ -24386,3 +24386,176 @@ window.nationalityToAccent = function nationalityToAccent(slave) {
 		slave.accent = jsEither([0, 0, 0, 1]);
 	}
 };
+
+/*
+Backup and then apply gingering modifiers to $activeSlave - no changes should be made to $activeSlave until after calling removeGingering() to restore the backup
+Called from lawCompliance
+*/
+window.checkForGingering = function checkForGingering() {
+	const V = State.variables;
+	let r = "";
+	const pronouns = getPronouns(V.activeSlave);
+	const he = pronouns.pronoun;
+	const him = pronouns.object;
+	const his = pronouns.possessive;
+	const He = capFirstChar(he);
+	const His = capFirstChar(his);
+
+	/* reset in case gingered slaves were viewed but not purchased (no newSlaveIntro) */
+	V.gingering = 0, V.gingeringDetected = 0, V.gingeringDetection = 0, V.toSearch = V.activeSlave.origin;
+	if (V.applyLaw === 1 && V.HonestySMR === 1) {
+		/* SMR prohibits gingering and is enforced for this slave - do nothing */
+	} else if (V.activeSlave.indenture > 0) {
+		/* indentured servants cannot be gingered */
+	} else if (V.toSearch !== 0 && V.toSearch.indexOf("Shelter") !== -1) {
+		/* is a Shelter slave - do nothing */
+	} else {
+		V.beforeGingering = clone(V.activeSlave);
+		if (V.activeSlave.trust < -20 && jsRandom(1, 3) === 1) {
+			V.gingering = "antidepressant";
+			V.activeSlave.trust += jsRandom(10, 40);
+		} else if (V.activeSlave.devotion < -20 && jsRandom(1, 3) === 1) {
+			V.gingering = "depressant";
+			V.activeSlave.devotion += jsRandom(10, 40);
+		} else if (V.activeSlave.health < 60 && jsRandom(1, 3) === 1) {
+			V.gingering = "stimulant";
+			V.activeSlave.health += jsRandom(20, 40);
+		} else if (V.activeSlave.balls > 0 && V.activeSlave.dick > 2 && jsRandom(1, 3) === 1) {
+			V.gingering = "vasoconstrictor";
+			V.activeSlave.dick -= jsRandom(1, 2);
+		} else if (V.activeSlave.balls > 0 && V.activeSlave.dick < 5 && jsRandom(1, 3) === 1) {
+			V.gingering = "vasodilator";
+			V.activeSlave.dick += jsRandom(1, 2);
+		} else if (V.activeSlave.attrKnown === 0 && jsRandom(1, 3) === 1) {
+			V.gingering = "aphrodisiac";
+			V.activeSlave.aphrodisiacs = 2;
+			V.activeSlave.attrKnown = 1;
+			V.activeSlave.attrXX = jsRandom(60, 90);
+			V.activeSlave.attrXY = jsRandom(60, 90);
+			V.activeSlave.energy = jsRandom(50, 90);
+		} else if (V.activeSlave.anus > 0 && V.activeSlave.fetishKnown === 0 && jsRandom(1, 3) === 1) {
+			V.gingering = "ginger";
+			V.activeSlave.fetish = "buttslut";
+			V.activeSlave.fetishKnown = 1;
+			V.activeSlave.fetishStrength = 65;
+		}
+	}
+	if (V.gingering !== 0) {
+		if (V.PC.slaving >= 100) {
+			V.gingeringDetected = 1, V.gingeringDetection = "slaver";
+			switch (V.gingering) {
+				case "antidepressant":
+					r += `${He} is acting dazed and unfocused. ${He}'s obviously been given antidepressants to make ${him} appear less fearful, and will be considerably less trusting than ${he} seems.`;
+					break;
+				case "depressant":
+					r += `${He} is acting languid and drugged. ${He}'s obviously been given a depressant to make ${him} appear less hateful, and will be considerably less accepting of slavery than ${he} seems.`;
+					break;
+				case "stimulant":
+					r += `${He} is acting twitchy and hyperactive. ${He}'s obviously been given a stimulant to make ${him} seem healthier and more energetic, and is a lot less healthy than ${he} looks.`;
+					break;
+				case "vasoconstrictor":
+					r += `${His} lips have the slightest blue tinge, making it obvious ${he}'s been given a vasoconstrictor. ${His} cock is a lot less of a girldick than it looks right now.`;
+					break;
+				case "vasodilator":
+					r += `${He} has an impressive erection, but it seems quite unconnected to the rest of ${him}, as	if ${he} doesn't know what to do with it. ${He}'s obviously been given a vasodilator to make ${his} dick seem a little less pathetic.`;
+					break;
+				case "aphrodisiac":
+					r += `${His} pupils are slightly dilated, ${his} breath comes in fast pants, and ${his} skin is flushed. ${He}'s obviously been given as big of a dose of aphrodisiacs as ${he} can handle without a heart attack.`;
+					break;
+				default:
+					r += `${He} is acting oddly, presenting ${his} ass in an awkward way and acting uncomfortable. ${He}'s obviously had an irritant shoved up ${his} butt to make ${him} act like an anal whore.`;
+			}
+			r += ` It's a trick you're very familiar with, given your <span class="springgreen">training as a slaver.</span>`;
+		} else {
+			/* not slaver */
+			if (V.PC.warfare >= 100 && jsRandom(1, 2) === 1) {
+				V.gingeringDetected = 1, V.gingeringDetection = "mercenary";
+			} else if (V.PC.rumor === "force" && jsRandom(1, 2) === 1) {
+				V.gingeringDetected = 1, V.gingeringDetection = "force";
+			} else if (jsRandom(1, 3) === 1) {
+				V.gingeringDetected = 1;
+			}
+			if (V.gingeringDetected === 1) {
+				switch (V.gingering) {
+					case "antidepressant":
+						r += `${He} is acting dazed and unfocused, like she's been given antidepressants to make ${him} appear less fearful. She may be considerably less trusting than ${he} seems. `;
+						break;
+					case "depressant":
+						r += `${He} is acting languid and drugged, like she's been given a depressant to make ${him} appear less hateful. She may be considerably less accepting of slavery than ${he} seems. `;
+						break;
+					case "stimulant":
+						r += `${He} is acting twitchy and hyperactive, like she's been given a stimulant to make ${him} seem healthier and more energetic. She may be considerably less vital than ${he} seems. `;
+						break;
+					case "vasoconstrictor":
+						r += `${His} lips have the slightest blue tinge, suggesting that ${he} may have been given a vasoconstrictor. If ${he} has, ${his} cock may be considerably less feminine and demure than it now seems. `;
+						break;
+					case "vasodilator":
+						r += `${He} has an impressive erection, but it seems quite unconnected to the rest of ${him}, as if ${he} doesn't know what to do with it. She may have been given a vasodilator. If ${he} has, ${his} cock may be considerably less impressive than it now seems. `;
+						break;
+					case "aphrodisiac":
+						r += `${His} pupils are slightly dilated, ${his} breath comes in fast pants, and ${his} skin is flushed. These are the characteristic symptoms of a dose of aphrodisiacs limited only by a desire to avoid giving ${him} a heart attack. `;
+						break;
+					default:
+						r += `${He} is acting oddly, presenting ${his} ass in an awkward way and acting uncomfortable. ${He} may be considerably less interested in anal sex than ${he} seems. `;
+				}
+				if (V.gingeringDetection === "mercenary") {
+					r += `The nervous seller confirms this in response to a direct inquiry. Your intimidating reputation from your <span class="springgreen">extensive combat training</span> has its uses.`;
+				} else if (V.gingeringDetection === "force") {
+					r += `The nervous seller confirms this in response to a direct inquiry. Your reputation as a <span class="springgreen"> ${V.PCTitle ? "man" : "woman"} of blood</span> has its uses.`;
+				}
+			}
+		} /* gingering detected */
+	} /* gingering !== 0 */
+	return r;
+};
+
+/*
+Retrieve original $activeSlave without gingering modifiers
+Call as removeGingering()
+Called from newSlaveIntro, bulkSlaveGenerate
+*/
+window.removeGingering = function removeGingering() {
+	const V = State.variables;
+	if (V.gingering !== 0 && V.beforeGingering !== 0 && V.activeSlave !== 0 && V.beforeGingering.ID === V.activeSlave.ID) {
+		/* extra checks to ensure gingering state is not left over from a different slave that was inspected but not purchased */
+		V.activeSlave = V.beforeGingering, V.beforeGingering = 0;
+	} else {
+		/* clear left over state from a different slave without modifying activeSlave */
+		V.gingering = 0, V.beforeGingering = 0;
+	}
+};
+
+window.randomizeAttraction = function randomizeAttraction(slave) {
+	const sexuality = jsRandom(0, 100);
+	let attraction = Math.clamp(slave.energy * 2, 60, 180);
+
+	if (slave.balls > 0) {
+		if (sexuality > 90) {
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXY;
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+		} else if (sexuality > 70) {
+			slave.attrXY = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+			slave.attrXX = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+		} else {
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXX;
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+		}
+	} else {
+		if (sexuality > 90) {
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXX;
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+		} else if (sexuality > 60) {
+			slave.attrXY = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+			slave.attrXX = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+		} else {
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXY;
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+		}
+	}
+	slave.attrXX = Math.clamp(slave.attrXX + jsRandom(-5, 5), 0, 100);
+	slave.attrXY = Math.clamp(slave.attrXY + jsRandom(-5, 5), 0, 100);
+};
diff --git a/src/js/slaveGenerationJS.tw b/src/js/slaveGenerationJS.tw
index e672c692d16..f31d081533c 100644
--- a/src/js/slaveGenerationJS.tw
+++ b/src/js/slaveGenerationJS.tw
@@ -1089,3 +1089,176 @@ window.nationalityToAccent = function nationalityToAccent(slave) {
 		slave.accent = jsEither([0, 0, 0, 1]);
 	}
 };
+
+/*
+Backup and then apply gingering modifiers to $activeSlave - no changes should be made to $activeSlave until after calling removeGingering() to restore the backup
+Called from lawCompliance
+*/
+window.checkForGingering = function checkForGingering() {
+	const V = State.variables;
+	let r = "";
+	const pronouns = getPronouns(V.activeSlave);
+	const he = pronouns.pronoun;
+	const him = pronouns.object;
+	const his = pronouns.possessive;
+	const He = capFirstChar(he);
+	const His = capFirstChar(his);
+
+	/* reset in case gingered slaves were viewed but not purchased (no newSlaveIntro) */
+	V.gingering = 0, V.gingeringDetected = 0, V.gingeringDetection = 0, V.toSearch = V.activeSlave.origin;
+	if (V.applyLaw === 1 && V.HonestySMR === 1) {
+		/* SMR prohibits gingering and is enforced for this slave - do nothing */
+	} else if (V.activeSlave.indenture > 0) {
+		/* indentured servants cannot be gingered */
+	} else if (V.toSearch !== 0 && V.toSearch.indexOf("Shelter") !== -1) {
+		/* is a Shelter slave - do nothing */
+	} else {
+		V.beforeGingering = clone(V.activeSlave);
+		if (V.activeSlave.trust < -20 && jsRandom(1, 3) === 1) {
+			V.gingering = "antidepressant";
+			V.activeSlave.trust += jsRandom(10, 40);
+		} else if (V.activeSlave.devotion < -20 && jsRandom(1, 3) === 1) {
+			V.gingering = "depressant";
+			V.activeSlave.devotion += jsRandom(10, 40);
+		} else if (V.activeSlave.health < 60 && jsRandom(1, 3) === 1) {
+			V.gingering = "stimulant";
+			V.activeSlave.health += jsRandom(20, 40);
+		} else if (V.activeSlave.balls > 0 && V.activeSlave.dick > 2 && jsRandom(1, 3) === 1) {
+			V.gingering = "vasoconstrictor";
+			V.activeSlave.dick -= jsRandom(1, 2);
+		} else if (V.activeSlave.balls > 0 && V.activeSlave.dick < 5 && jsRandom(1, 3) === 1) {
+			V.gingering = "vasodilator";
+			V.activeSlave.dick += jsRandom(1, 2);
+		} else if (V.activeSlave.attrKnown === 0 && jsRandom(1, 3) === 1) {
+			V.gingering = "aphrodisiac";
+			V.activeSlave.aphrodisiacs = 2;
+			V.activeSlave.attrKnown = 1;
+			V.activeSlave.attrXX = jsRandom(60, 90);
+			V.activeSlave.attrXY = jsRandom(60, 90);
+			V.activeSlave.energy = jsRandom(50, 90);
+		} else if (V.activeSlave.anus > 0 && V.activeSlave.fetishKnown === 0 && jsRandom(1, 3) === 1) {
+			V.gingering = "ginger";
+			V.activeSlave.fetish = "buttslut";
+			V.activeSlave.fetishKnown = 1;
+			V.activeSlave.fetishStrength = 65;
+		}
+	}
+	if (V.gingering !== 0) {
+		if (V.PC.slaving >= 100) {
+			V.gingeringDetected = 1, V.gingeringDetection = "slaver";
+			switch (V.gingering) {
+				case "antidepressant":
+					r += `${He} is acting dazed and unfocused. ${He}'s obviously been given antidepressants to make ${him} appear less fearful, and will be considerably less trusting than ${he} seems.`;
+					break;
+				case "depressant":
+					r += `${He} is acting languid and drugged. ${He}'s obviously been given a depressant to make ${him} appear less hateful, and will be considerably less accepting of slavery than ${he} seems.`;
+					break;
+				case "stimulant":
+					r += `${He} is acting twitchy and hyperactive. ${He}'s obviously been given a stimulant to make ${him} seem healthier and more energetic, and is a lot less healthy than ${he} looks.`;
+					break;
+				case "vasoconstrictor":
+					r += `${His} lips have the slightest blue tinge, making it obvious ${he}'s been given a vasoconstrictor. ${His} cock is a lot less of a girldick than it looks right now.`;
+					break;
+				case "vasodilator":
+					r += `${He} has an impressive erection, but it seems quite unconnected to the rest of ${him}, as	if ${he} doesn't know what to do with it. ${He}'s obviously been given a vasodilator to make ${his} dick seem a little less pathetic.`;
+					break;
+				case "aphrodisiac":
+					r += `${His} pupils are slightly dilated, ${his} breath comes in fast pants, and ${his} skin is flushed. ${He}'s obviously been given as big of a dose of aphrodisiacs as ${he} can handle without a heart attack.`;
+					break;
+				default:
+					r += `${He} is acting oddly, presenting ${his} ass in an awkward way and acting uncomfortable. ${He}'s obviously had an irritant shoved up ${his} butt to make ${him} act like an anal whore.`;
+			}
+			r += ` It's a trick you're very familiar with, given your <span class="springgreen">training as a slaver.</span>`;
+		} else {
+			/* not slaver */
+			if (V.PC.warfare >= 100 && jsRandom(1, 2) === 1) {
+				V.gingeringDetected = 1, V.gingeringDetection = "mercenary";
+			} else if (V.PC.rumor === "force" && jsRandom(1, 2) === 1) {
+				V.gingeringDetected = 1, V.gingeringDetection = "force";
+			} else if (jsRandom(1, 3) === 1) {
+				V.gingeringDetected = 1;
+			}
+			if (V.gingeringDetected === 1) {
+				switch (V.gingering) {
+					case "antidepressant":
+						r += `${He} is acting dazed and unfocused, like she's been given antidepressants to make ${him} appear less fearful. She may be considerably less trusting than ${he} seems. `;
+						break;
+					case "depressant":
+						r += `${He} is acting languid and drugged, like she's been given a depressant to make ${him} appear less hateful. She may be considerably less accepting of slavery than ${he} seems. `;
+						break;
+					case "stimulant":
+						r += `${He} is acting twitchy and hyperactive, like she's been given a stimulant to make ${him} seem healthier and more energetic. She may be considerably less vital than ${he} seems. `;
+						break;
+					case "vasoconstrictor":
+						r += `${His} lips have the slightest blue tinge, suggesting that ${he} may have been given a vasoconstrictor. If ${he} has, ${his} cock may be considerably less feminine and demure than it now seems. `;
+						break;
+					case "vasodilator":
+						r += `${He} has an impressive erection, but it seems quite unconnected to the rest of ${him}, as if ${he} doesn't know what to do with it. She may have been given a vasodilator. If ${he} has, ${his} cock may be considerably less impressive than it now seems. `;
+						break;
+					case "aphrodisiac":
+						r += `${His} pupils are slightly dilated, ${his} breath comes in fast pants, and ${his} skin is flushed. These are the characteristic symptoms of a dose of aphrodisiacs limited only by a desire to avoid giving ${him} a heart attack. `;
+						break;
+					default:
+						r += `${He} is acting oddly, presenting ${his} ass in an awkward way and acting uncomfortable. ${He} may be considerably less interested in anal sex than ${he} seems. `;
+				}
+				if (V.gingeringDetection === "mercenary") {
+					r += `The nervous seller confirms this in response to a direct inquiry. Your intimidating reputation from your <span class="springgreen">extensive combat training</span> has its uses.`;
+				} else if (V.gingeringDetection === "force") {
+					r += `The nervous seller confirms this in response to a direct inquiry. Your reputation as a <span class="springgreen"> ${V.PCTitle ? "man" : "woman"} of blood</span> has its uses.`;
+				}
+			}
+		} /* gingering detected */
+	} /* gingering !== 0 */
+	return r;
+};
+
+/*
+Retrieve original $activeSlave without gingering modifiers
+Call as removeGingering()
+Called from newSlaveIntro, bulkSlaveGenerate
+*/
+window.removeGingering = function removeGingering() {
+	const V = State.variables;
+	if (V.gingering !== 0 && V.beforeGingering !== 0 && V.activeSlave !== 0 && V.beforeGingering.ID === V.activeSlave.ID) {
+		/* extra checks to ensure gingering state is not left over from a different slave that was inspected but not purchased */
+		V.activeSlave = V.beforeGingering, V.beforeGingering = 0;
+	} else {
+		/* clear left over state from a different slave without modifying activeSlave */
+		V.gingering = 0, V.beforeGingering = 0;
+	}
+};
+
+window.randomizeAttraction = function randomizeAttraction(slave) {
+	const sexuality = jsRandom(0, 100);
+	let attraction = Math.clamp(slave.energy * 2, 60, 180);
+
+	if (slave.balls > 0) {
+		if (sexuality > 90) {
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXY;
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+		} else if (sexuality > 70) {
+			slave.attrXY = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+			slave.attrXX = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+		} else {
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXX;
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+		}
+	} else {
+		if (sexuality > 90) {
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXX;
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+		} else if (sexuality > 60) {
+			slave.attrXY = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+			slave.attrXX = Math.clamp(attraction + jsRandom(-5, 5), 0, 100);
+		} else {
+			slave.attrXY = Math.clamp(attraction, 0, 100);
+			attraction -= slave.attrXY;
+			slave.attrXX = Math.clamp(attraction, 0, 100);
+		}
+	}
+	slave.attrXX = Math.clamp(slave.attrXX + jsRandom(-5, 5), 0, 100);
+	slave.attrXY = Math.clamp(slave.attrXY + jsRandom(-5, 5), 0, 100);
+};
diff --git a/src/uncategorized/bulkSlaveGenerate.tw b/src/uncategorized/bulkSlaveGenerate.tw
index e2629b667a1..87c780b5812 100644
--- a/src/uncategorized/bulkSlaveGenerate.tw
+++ b/src/uncategorized/bulkSlaveGenerate.tw
@@ -97,7 +97,7 @@
 			<<include "Law Compliance">> /* includes CheckForGingering - slave stats may change, affecting price */
 		<</silently>>
 		<<slaveCost $activeSlave>>
-		<<RemoveGingering>> /* remove gingered state, if applied, so we can apply it again later */
+		<<run removeGingering()>> /* remove gingered state, if applied, so we can apply it again later */
 		<<set $activeSlave = _backup>> /* restore backup so we can apply Law Compliance again later */
 	<</if>>
 
diff --git a/src/uncategorized/bulkSlaveIntro.tw b/src/uncategorized/bulkSlaveIntro.tw
index be9ced8684e..01f6a046cdf 100644
--- a/src/uncategorized/bulkSlaveIntro.tw
+++ b/src/uncategorized/bulkSlaveIntro.tw
@@ -86,7 +86,7 @@
 	<br>
 	
 	/* Use existing New Slave Intro */
-	<<include "New Slave Intro">> /* calls <<RemoveGingering>> if needed */
+	<<include "New Slave Intro">> /* calls removeGingering() if needed */
 	
 	/* Override nextButton setting from New Slave Intro */
 	<<set $nextButton = "Continue">>
diff --git a/src/uncategorized/generateXXSlave.tw b/src/uncategorized/generateXXSlave.tw
index 18694ad202c..ed69f34fcca 100644
--- a/src/uncategorized/generateXXSlave.tw
+++ b/src/uncategorized/generateXXSlave.tw
@@ -70,7 +70,7 @@
 <<set $activeSlave.whoreSkill = random(0,15)>>
 
 <<set $activeSlave.energy = random(1,85)>>
-<<RandomizeAttraction>>
+<<run randomizeAttraction($activeSlave)>>
 <<set $activeSlave.fetishStrength = random(0,90)>>
 <<set $activeSlave.fetish = either("none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "submissive", "submissive", "cumslut", "humiliation", "humiliation", "buttslut", "boobs", "pregnancy", "dom", "sadist", "masochist")>>
 
diff --git a/src/uncategorized/generateXYSlave.tw b/src/uncategorized/generateXYSlave.tw
index 30a4c243eda..b92d6c2648a 100644
--- a/src/uncategorized/generateXYSlave.tw
+++ b/src/uncategorized/generateXYSlave.tw
@@ -69,7 +69,7 @@
 <<set $activeSlave.whoreSkill = random(0,15)>>
 
 <<set $activeSlave.energy = random(15,90)>>
-<<RandomizeAttraction>>
+<<<run randomizeAttraction($activeSlave)>>
 <<set $activeSlave.fetishStrength = random(0,90)>>
 <<set $activeSlave.fetish = either("none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "submissive", "cumslut", "humiliation", "buttslut", "buttslut", "boobs", "dom", "sadist", "masochist")>>
 
diff --git a/src/uncategorized/lawCompliance.tw b/src/uncategorized/lawCompliance.tw
index cae29ea3be1..2c7466883ae 100644
--- a/src/uncategorized/lawCompliance.tw
+++ b/src/uncategorized/lawCompliance.tw
@@ -480,5 +480,5 @@ a physical exam, and more.
 <</if>>
 <</if>>
 
-<<CheckForGingering>> /* may store a backup of $activeSlave and make temporary changes; call <<RemoveGingering>> to retrieve backup before making changes to $activeSlave */
+<<= checkForGingering()>> /* may store a backup of $activeSlave and make temporary changes; call removeGingering() to retrieve backup before making changes to $activeSlave */
 
diff --git a/src/uncategorized/newSlaveIntro.tw b/src/uncategorized/newSlaveIntro.tw
index aa2ea2775be..c41e2d01526 100644
--- a/src/uncategorized/newSlaveIntro.tw
+++ b/src/uncategorized/newSlaveIntro.tw
@@ -77,7 +77,7 @@ The legalities completed, ''__@@.pink;<<= SlaveFullName($activeSlave)>>@@__'' <<
 	<</if>>
 <</if>>
 
-<<RemoveGingering>> /* retrieve original $activeSlave without gingering effects */
+<<run removeGingering()>> /* retrieve original $activeSlave without gingering effects */
 
 <<set $activeSlave.oldDevotion = $activeSlave.devotion>>
 <<set $activeSlave.oldTrust = $activeSlave.trust>>
diff --git a/src/uncategorized/reRelativeRecruiter.tw b/src/uncategorized/reRelativeRecruiter.tw
index 538fdd00fea..c7a582d441a 100644
--- a/src/uncategorized/reRelativeRecruiter.tw
+++ b/src/uncategorized/reRelativeRecruiter.tw
@@ -120,7 +120,7 @@
 		<<set $activeSlave.bellySag = 0, $activeSlave.bellySagPreg = 0>>
 		<<set $activeSlave.birthsTotal = 0>>
 		<<set $activeSlave.prostate = 0>>
-		<<RandomizeAttraction>>
+		<<<run randomizeAttraction($activeSlave)>>
 		<<ResyncHeight $activeSlave>>
 	<</if>>
 	<<if $activeSlave.nipples == "fuckable">>
@@ -1030,7 +1030,7 @@ She waits anxiously for your decision.
 <<set $activeSlave.sexualFlaw = either("none", "none", "none", "none", "hates oral", "hates anal", "hates penetration")>>
 <<set $activeSlave.behavioralFlaw = either("none", "none", "none", "arrogant", "bitchy", "odd", "anorexic", "hates men", "hates women", "hates women")>>
 <<set $activeSlave.weekAcquired = $week>>
-<<RandomizeAttraction>>
+<<<run randomizeAttraction($activeSlave)>>
 <<if $activeSlave.nipples == "fuckable">>
 	<<set $activeSlave.nipples = either("cute", "puffy", "inverted", "partially inverted")>>
 <</if>>
diff --git a/src/utility/slaveCreationWidgets.tw b/src/utility/slaveCreationWidgets.tw
index a60994ab63e..9a545edbf52 100644
--- a/src/utility/slaveCreationWidgets.tw
+++ b/src/utility/slaveCreationWidgets.tw
@@ -9,119 +9,6 @@
 	<<set $activeSlave = {slaveName: "blank", slaveSurname: 0, birthName: "blank", birthSurname: 0, genes: "XX", pronoun: "she", possessive: "her", possessivePronoun: "hers", objectReflexive: "herself", object: "her", noun: "girl", weekAcquired: 0, origin: 0, career: 0, ID: 0, prestige: 0, pornFeed: 0, pornFame: 0, pornFameSpending: 0, pornPrestige: 0, pornPrestigeDesc: 0, pornFameType: "none", pornFocus: "none", pornTypeGeneral: 0, pornTypeFuckdoll: 0, pornTypeRape: 0, pornTypePreggo: 0, pornTypeBBW: 0, pornTypeGainer: 0, pornTypeStud: 0, pornTypeLoli: 0, pornTypeDeepThroat: 0, pornTypeStruggleFuck: 0, pornTypePainal: 0, pornTypeTease: 0, pornTypeRomantic: 0, pornTypePervert: 0, pornTypeCaring: 0, pornTypeUnflinching: 0, pornTypeSizeQueen: 0, pornTypeNeglectful: 0, pornTypeCumAddict: 0, pornTypeAnalAddict: 0, pornTypeAttentionWhore: 0, pornTypeBreastGrowth: 0, pornTypeAbusive: 0, pornTypeMalicious: 0, pornTypeSelfHating: 0, pornTypeBreeder: 0, pornTypeSub: 0, pornTypeCumSlut: 0, pornTypeAnal: 0, pornTypeHumiliation: 0, pornTypeBoobs: 0, pornTypeDom: 0, pornTypeSadist: 0, pornTypeMasochist: 0, pornTypePregnancy: 0, prestigeDesc: 0, recruiter: 0, relation: 0, relationTarget: 0, relationship: 0, relationshipTarget: 0, rivalry: 0, rivalryTarget: 0, subTarget: 0, father: 0, mother: 0, daughters: 0, sisters: 0, canRecruit: 0, choosesOwnAssignment: 0, assignment: "rest", assignmentVisible: 1, sentence: 0, training: 0, toyHole: "all her holes", indenture: -1, indentureRestrictions: 0, birthWeek: random(0,51), actualAge: 18, visualAge: 18, physicalAge: 18, ovaryAge: 18, ageImplant: 0, health: 0, minorInjury: 0, trust: 0, oldTrust: 0, devotion: 0, oldDevotion: 0, weight: 0, muscles: 0, height: 170, heightImplant: 0, nationality: "slave", race: "white", markings: "none", eyes: 1, eyeColor: "brown", origEye: "brown", eyewear: "none", origHColor: "brown", hColor: "brown", pubicHColor: "brown", skin: "light", hLength: 60, hStyle: "short", pubicHStyle: "neat", waist: 0, corsetPiercing: 0, PLimb: 0, amp: 0, heels:0, voice: 2, voiceImplant: 0, accent: 0, shoulders: 0, shouldersImplant: 0, boobs: 0, boobsImplant: 0, boobsImplantType: 0, boobShape: "normal", nipples: "cute",  nipplesPiercing: 0, nipplesAccessory: 0, areolae: 0, areolaePiercing: 0, boobsTat: 0, lactation: 0, lactationAdaptation: 0, milk: 0, cum: 0, hips: 0, hipsImplant: 0, butt: 0, buttImplant: 0, buttImplantType: 0, buttTat: 0, face: 0, faceImplant: 0, faceShape: "normal", lips: 15, lipsImplant: 0, lipsPiercing: 0, lipsTat: 0, teeth: "normal", tonguePiercing: 0, vagina: 0, vaginaLube: 0, vaginaPiercing: 0, vaginaTat: 0, preg: -1, pregSource: 0, pregType: 0, pregAdaptation: 50, broodmother: 0, broodmotherFetuses: 0, broodmotherOnHold: 0, broodmotherCountDown: 0, labor: 0, births: 0, cSec: 0, bellyAccessory: "none", labia: 0, clit: 0, clitPiercing: 0, clitSetting: "vanilla", foreskin: 0, anus: 0, dick: 0, analArea: 1, dickPiercing: 0, dickTat: 0, prostate: 0, balls: 0, scrotum: 0, ovaries: 0, anusPiercing: 0, anusTat: 0, makeup: 0, nails: 0, brand: 0, brandLocation: 0, earPiercing: 0, nosePiercing: 0, eyebrowPiercing: 0, navelPiercing: 0, shouldersTat: 0, armsTat: 0, legsTat: 0, backTat: 0, stampTat: 0, vaginalSkill: 0, oralSkill: 0, analSkill: 0, whoreSkill: 0, entertainSkill: 0, combatSkill: 0, livingRules: "spare", speechRules: "restrictive", releaseRules: "restrictive", relationshipRules: "restrictive", standardPunishment: "situational", standardReward: "situational", useRulesAssistant: 1, diet: "healthy", dietCum: 0, dietMilk: 0, tired: 0, hormones: 0, drugs: "no drugs", curatives: 0, chem: 0, aphrodisiacs: 0, addict: 0, fuckdoll: 0, choosesOwnClothes: 0, clothes: "no clothing", collar: "none", shoes: "none", vaginalAccessory: "none", dickAccessory: "none", legAccessory: "none", buttplug: "none", buttplugAttachment: "none", intelligence: 0, intelligenceImplant: 0, energy: 50, need: 0, attrXX: 0, attrXY: 0, attrKnown: 0, fetish: "none", fetishStrength: 70, fetishKnown: 0, behavioralFlaw: "none", behavioralQuirk: "none", sexualFlaw: "none", sexualQuirk: "none", oralCount: 0, vaginalCount: 0, analCount: 0, mammaryCount: 0, penetrativeCount: 0, publicCount: 0, pitKills: 0, customTat: "", customLabel: "", customDesc: "", customTitle: "", customTitleLisp: "", rudeTitle: 0, customImage: 0, currentRules: [], bellyTat: 0, induce: 0, mpreg: 0, inflation: 0, inflationType: "none", inflationMethod: 0, milkSource: 0, cumSource: 0, burst: 0, pregKnown: 0, pregWeek: 0, belly: 0, bellyPreg: 0, bellyFluid: 0, bellyImplant: -1, bellySag: 0, bellySagPreg: 0, bellyPain: 0, cervixImplant: 0, birthsTotal: 0, pubertyAgeXX: 13, pubertyAgeXY: 13, scars: 0, breedingMark: 0, underArmHStyle: "waxed", bodySwap: 0, HGExclude: 0, ballType: "human", eggType: "human", reservedChildren: 0, choosesOwnChastity: 0, pregControl: "none", readyLimbs: [], ageAdjust: 0, bald: 0, origBodyOwner: "", origBodyOwnerID: 0, death: "", hormoneBalance: 0, onDiet: 0, breastMesh: 0, slavesFathered: 0, PCChildrenFathered: 0, slavesKnockedUp: 0, PCKnockedUp: 0, origSkin: "white", vasectomy: 0, haircuts: 0, newGamePlus: 0, skillHG: 0, skillRC: 0, skillBG: 0, skillMD: 0, skillDJ: 0, skillNU: 0, skillTE: 0, skillAT: 0, skillST: 0, skillMM: 0, skillWA: 0, skillS: 0, skillE: 0, skillW: 0, tankBaby: 0, inducedNCS: 0, NCSyouthening: 0}>>
 <</widget>>
 
-/%
-	Backup and then apply gingering modifiers to $activeSlave - no changes should be made to $activeSlave until after calling <<RemoveGingering>> to restore the backup
-	Call as <<CheckForGingering>>
-	Called from newSlaveIntro, lawCompliance
-%/
-<<widget "CheckForGingering">>
-	<<set $gingering = 0, $gingeringDetected = 0, $gingeringDetection = 0, $toSearch = $activeSlave.origin>> /* reset in case gingered slaves were viewed but not purchased (no newSlaveIntro) */
-	<<if ($applyLaw == 1) && ($HonestySMR == 1)>> /* SMR prohibits gingering and is enforced for this slave - do nothing */
-	<<elseif ($activeSlave.indenture > 0)>> /* indentured servants cannot be gingered */
-	<<elseif ($toSearch != 0) && ($toSearch.indexOf("Shelter") != -1)>> /* is a Shelter slave - do nothing */
-	<<else>>
-		<<set $beforeGingering = $activeSlave>>
-
-		<<if ($activeSlave.trust < -20) && (random(1,3) == 1)>>
-			<<set $gingering = "antidepressant">>
-			<<set $activeSlave.trust += random(10,40)>>
-		<<elseif ($activeSlave.devotion < -20) && (random(1,3) == 1)>>
-			<<set $gingering = "depressant">>
-			<<set $activeSlave.devotion += random(10,40)>>
-		<<elseif ($activeSlave.health < 60) && (random(1,3) == 1)>>
-			<<set $gingering = "stimulant">>
-			<<set $activeSlave.health += random(20,40)>>
-		<<elseif ($activeSlave.balls > 0) && ($activeSlave.dick > 2) && (random(1,3) == 1)>>
-			<<set $gingering = "vasoconstrictor">>
-			<<set $activeSlave.dick -= random(1,2)>>
-		<<elseif ($activeSlave.balls > 0) && ($activeSlave.dick < 5) && (random(1,3) == 1)>>
-			<<set $gingering = "vasodilator">>
-			<<set $activeSlave.dick += random(1,2)>>
-		<<elseif ($activeSlave.attrKnown == 0) && (random(1,3) == 1)>>
-			<<set $gingering = "aphrodisiac">>
-			<<set $activeSlave.aphrodisiacs = 2>>
-			<<set $activeSlave.attrKnown = 1>>
-			<<set $activeSlave.attrXX = random(60.90)>>
-			<<set $activeSlave.attrXY = random(60,90)>>
-			<<set $activeSlave.energy = random(50,90)>>
-		<<elseif ($activeSlave.anus > 0) && ($activeSlave.fetishKnown == 0) && (random(1,3) == 1)>>
-			<<set $gingering = "ginger">>
-			<<set $activeSlave.fetish = "buttslut">>
-			<<set $activeSlave.fetishKnown = 1>>
-			<<set $activeSlave.fetishStrength = 65>>
-		<</if>>
-	<</if>>
-
-	<<if ($gingering != 0)>>
-		<<if ($PC.slaving >= 100)>>
-			<<set $gingeringDetected = 1, $gingeringDetection = "slaver">>
-			<<switch $gingering>>
-			<<case "antidepressant">>
-				She is acting dazed and unfocused. She's obviously been given antidepressants to make her appear less fearful, and will be considerably less trusting than she seems.
-			<<case "depressant">>
-				She is acting languid and drugged. She's obviously been given a depressant to make her appear less hateful, and will be considerably less accepting of slavery than she seems.
-			<<case "stimulant">>
-				She is acting twitchy and hyperactive. She's obviously been given a stimulant to make her seem healthier and more energetic, and is a lot less healthy than she looks.
-			<<case "vasoconstrictor">>
-				Her lips have the slightest blue tinge, making it obvious she's been given a vasoconstrictor. Her cock is a lot less of a girldick than it looks right now.
-			<<case "vasodilator">>
-				She has an impressive erection, but it seems quite unconnected to the rest of her, as if she doesn't know what to do with it. She's obviously been given a vasodilator to make her dick seem a little less pathetic.
-			<<case "aphrodisiac">>
-				Her pupils are slightly dilated, her breath comes in fast pants, and her skin is flushed. She's obviously been given as big of a dose of aphrodisiacs as she can handle without a heart attack.
-			<<default>>
-				She is acting oddly, presenting her ass in an awkward way and acting uncomfortable. She's obviously had an irritant shoved up her butt to make her act like an anal whore.
-			<</switch>>
-			It's a trick you're very familiar with, given your @@.springgreen;training as a slaver.@@
-		<<else>> /* not slaver */
-			<<if ($PC.warfare >= 100) && (random(1,2) == 1)>>
-				<<set $gingeringDetected = 1, $gingeringDetection = "mercenary">>
-			<<elseif ($PC.rumor == "force") && (random(1,2) == 1)>>
-				<<set $gingeringDetected = 1, $gingeringDetection = "force">>
-			<<elseif (random(1,3) == 1)>>
-				<<set $gingeringDetected = 1>>
-			<</if>>
-			<<if ($gingeringDetected == 1)>>
-				<<switch $gingering>>
-				<<case "antidepressant">>
-					She is acting dazed and unfocused, like she's been given antidepressants to make her appear less fearful. She may be considerably less trusting than she seems.
-				<<case "depressant">>
-					She is acting languid and drugged, like she's been given a depressant to make her appear less hateful. She may be considerably less accepting of slavery than she seems.
-				<<case "stimulant">>
-					She is acting twitchy and hyperactive, like she's been given a stimulant to make her seem healthier and more energetic. She may be considerably less vital than she seems.
-				<<case "vasoconstrictor">>
-					Her lips have the slightest blue tinge, suggesting that she may have been given a vasoconstrictor. If she has, her cock may be considerably less feminine and demure than it now seems.
-				<<case "vasodilator">>
-					She has an impressive erection, but it seems quite unconnected to the rest of her, as if she doesn't know what to do with it. She may have been given a vasodilator. If she has, her cock may be considerably less impressive than it now seems.
-				<<case "aphrodisiac">>
-					Her pupils are slightly dilated, her breath comes in fast pants, and her skin is flushed. These are the characteristic symptoms of a dose of aphrodisiacs limited only by a desire to avoid giving her a heart attack.
-				<<default>>
-					She is acting oddly, presenting her ass in an awkward way and acting uncomfortable. She may be considerably less interested in anal sex than she seems.
-				<</switch>>
-				<<if ($gingeringDetection == "mercenary")>>
-					The nervous seller confirms this in response to a direct inquiry. Your intimidating reputation from your @@.springgreen;extensive combat training@@ has its uses.
-				<<elseif ($gingeringDetection == "force")>>
-					The nervous seller confirms this in response to a direct inquiry. Your reputation as a @@.springgreen;<<if ($PC.title == 1)>>man<<else>>woman<</if>> of blood@@ has its uses.
-				<</if>>
-			<</if>> /* gingering detected */
-		<</if>>
-	<</if>> /* gingering != 0 */
-
-<</widget>>
-
-/%
-	Retrieve original $activeSlave without gingering modifiers
-	Call as <<RemoveGingering>>
-	Called from newSlaveIntro, lawCompliance
-%/
-<<widget "RemoveGingering">>
-	<<if $gingering != 0 && $beforeGingering != 0 && $activeSlave != 0 && $beforeGingering.ID == $activeSlave.ID>> /* extra checks to ensure gingering state is not left over from a different slave that was inspected but not purchased */
-		<<set $activeSlave = $beforeGingering, $beforeGingering = 0>>
-	<<else>>
-		<<set $gingering = 0, $beforeGingering = 0>> /* clear left over state from a different slave without modifying activeSlave */
-	<</if>>
-<</widget>>
-
-
 /%
  Call as <<StartingGirlsWorkaround>>
 %/
@@ -1440,43 +1327,6 @@
 <</if>>
 <</widget>>
 
-/%
- Call as <<RandomizeAttraction>>
-%/
-<<widget "RandomizeAttraction">>
-
-<<set _attraction = Math.clamp($activeSlave.energy*2, 60, 180), _sexuality = random(0,100)>>
-<<if $activeSlave.balls > 0>>
-	<<if _sexuality > 90>>
-		<<set $activeSlave.attrXY = Math.clamp(_attraction, 0, 100)>>
-		<<set _attraction -= $activeSlave.attrXY>>
-		<<set $activeSlave.attrXX = Math.clamp(_attraction, 0, 100)>>
-	<<elseif _sexuality > 70>>
-		<<set $activeSlave.attrXY = Math.clamp(_attraction+random(-5,5), 0, 100)>>
-		<<set $activeSlave.attrXX = Math.clamp(_attraction+random(-5,5), 0, 100)>>
-	<<else>>
-		<<set $activeSlave.attrXX = Math.clamp(_attraction, 0, 100)>>
-		<<set _attraction -= $activeSlave.attrXX>>
-		<<set $activeSlave.attrXY = Math.clamp(_attraction, 0, 100)>>
-	<</if>>
-<<else>>
-	<<if _sexuality > 90>>
-		<<set $activeSlave.attrXX = Math.clamp(_attraction, 0, 100)>>
-		<<set _attraction -= $activeSlave.attrXX>>
-		<<set $activeSlave.attrXY = Math.clamp(_attraction, 0, 100)>>
-	<<elseif _sexuality > 60>>
-		<<set $activeSlave.attrXY = Math.clamp(_attraction+random(-5,5), 0, 100)>>
-		<<set $activeSlave.attrXX = Math.clamp(_attraction+random(-5,5), 0, 100)>>
-	<<else>>
-		<<set $activeSlave.attrXY = Math.clamp(_attraction, 0, 100)>>
-		<<set _attraction -= $activeSlave.attrXY>>
-		<<set $activeSlave.attrXX = Math.clamp(_attraction, 0, 100)>>
-	<</if>>
-<</if>>
-<<set $activeSlave.attrXX = Math.clamp($activeSlave.attrXX+random(-5,5), 0, 100), $activeSlave.attrXY = Math.clamp($activeSlave.attrXY+random(-5,5), 0, 100)>>
-
-<</widget>>
-
 /%
  Call as <<CustomSlaveAge>>
 %/
-- 
GitLab