From cb408bbc815803b7d83fce1616402c39ee2dce37 Mon Sep 17 00:00:00 2001
From: Olaroll <>
Date: Sun, 14 Aug 2022 01:30:38 +0300
Subject: [PATCH 01/50] Added backcomp to the Start2 passage

---
 game/01-config/start.twee                     |  2 ++
 .../04-Variables/variables-passageHeader.twee | 21 ++++++++++++-------
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/game/01-config/start.twee b/game/01-config/start.twee
index de16a4d00a..c403f1b605 100644
--- a/game/01-config/start.twee
+++ b/game/01-config/start.twee
@@ -60,6 +60,8 @@ If you want to avoid trouble, dress modestly and stick to safe, well-lit areas.
 <</if>>
 <br><br>
 
+<<doVersionCheck>>
+
 <<link [[Next|Orphanage Intro]]>><</link>>
 
 <br><br>
diff --git a/game/04-Variables/variables-passageHeader.twee b/game/04-Variables/variables-passageHeader.twee
index 21f2b99c43..9f8daf1298 100644
--- a/game/04-Variables/variables-passageHeader.twee
+++ b/game/04-Variables/variables-passageHeader.twee
@@ -3,6 +3,18 @@
 <<set $passage to passage()>><<set $tags to tags()>>
 
 <<if !["Start", "Start2", "Clothes Testing", "Renderer Test Page", "Tips"].includes($passage) && !$bypassHeader>>
+	<<doVersionCheck>>
+<</if>>
+
+/* Catch time desyncs for debugging*/
+<<if $debug is 1>>
+	<<checkTimeSystem "Header">>
+<</if>>
+
+<<unset $bypassHeader>>
+
+:: Widgets VersionCheck [widget]
+<<widget "doVersionCheck">>
 	/* Run stuff on every save load */
 	<<if onLoadUpdateCheck>>
 		<<set $saveVersion to ($saveVersions ? $saveVersions.last() : "ancient")>> /*update save version */
@@ -34,11 +46,4 @@
 	<<if setup.majorAreas.includes($passage)>>
 		<<set $safePassage to $passage>>
 	<</if>>
-<</if>>
-
-/* Catch time desyncs for debugging*/
-<<if $debug is 1>>
-	<<checkTimeSystem "Header">>
-<</if>>
-
-<<unset $bypassHeader>>
+<</widget>>
-- 
GitLab


From 5b3a32d6ca7afe8862ca030db6419b16e40823aa Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Sun, 21 Aug 2022 19:35:44 +0000
Subject: [PATCH 02/50] Style clean-up of sexshop JS files

---
 game/03-JavaScript/sexShopMenu.js      | 561 ++++++++++++++++---------
 game/03-JavaScript/sexToysInventory.js | 287 ++++++++-----
 2 files changed, 532 insertions(+), 316 deletions(-)

diff --git a/game/03-JavaScript/sexShopMenu.js b/game/03-JavaScript/sexShopMenu.js
index 4ff1baa61b..13de9184b5 100644
--- a/game/03-JavaScript/sexShopMenu.js
+++ b/game/03-JavaScript/sexShopMenu.js
@@ -4,35 +4,38 @@
  * **Do not** change the indexes, and do not move any objects in setup.sextoys array
  * If you need to add new items, add them at the end of the list, and set their index equal to their place in the array. First item has index 0, second item index 1 etc.
  * to be completed.
-*/
+ */
 
 setup.sextoyFunctions = {
-	notExists: (name) => V.player.inventory.sextoys[name] === undefined,
-	owned: function (name) {
+	notExists: name => V.player.inventory.sextoys[name] === undefined,
+	owned(name) {
 		if (setup.sextoyFunctions.notExists(name)) return 0;
 		return V.player.inventory.sextoys[name].length();
 	},
-	isCarried: function (name) {
+	isCarried(name) {
 		if (setup.sextoyFunctions.notExists(name)) return false;
 		return V.player.inventory.sextoys[name].some(item => item.carried);
 	},
-	isWorn: function (name) {
+	isWorn(name) {
 		if (setup.sextoyFunctions.notExists(name)) return false;
-		if (V.player.inventory.sextoys[name].type.includes("strap-on")){
-			return V.worn.under_lower.type.includes("strap-on")
+		if (V.player.inventory.sextoys[name].type.includes("strap-on")) {
+			return V.worn.under_lower.type.includes("strap-on");
 		} else {
 			return V.player.inventory.sextoys[name].some(item => item.worn);
 		}
 	},
-	unWear: function (name) {
+	unWear(name) {
 		if (setup.sextoyFunctions.notExists(name)) return;
-		V.player.inventory.sextoys[name].forEach(item => item.worn = 0);
+		V.player.inventory.sextoys[name].forEach(item => (item.worn = 0));
 	},
-	unCarry: function (name) {
+	unCarry(name) {
 		if (setup.sextoyFunctions.notExists(name)) return;
-		V.player.inventory.sextoys[name].forEach(item => item.worn = 0, item.carried = 0);
+		V.player.inventory.sextoys[name].forEach(item => {
+			item.worn = 0;
+			item.carried = 0;
+		});
 	},
-}
+};
 
 setup.sextoys = [
 	{
@@ -48,14 +51,25 @@ setup.sextoys = [
 		type: ["dildo"],
 		icon: "img/misc/icon/sexToys/dildo.png",
 		colour: 1,
-		colour_options: ["black","blue","teal","lime-green","light-pink","purple","tan","brown","red"],
+		colour_options: [
+			"black",
+			"blue",
+			"teal",
+			"lime-green",
+			"light-pink",
+			"purple",
+			"tan",
+			"brown",
+			"red",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 1,
 		name: "small dildo",
 		namecap: "Small dildo",
@@ -68,44 +82,67 @@ setup.sextoys = [
 		type: ["dildo"],
 		icon: "img/misc/icon/sexToys/dildo_small.png",
 		colour: 1,
-		colour_options: ["black","blue","teal","lime-green","light-pink","purple","tan","brown","red"],
+		colour_options: [
+			"black",
+			"blue",
+			"teal",
+			"lime-green",
+			"light-pink",
+			"purple",
+			"tan",
+			"brown",
+			"red",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 2,
 		name: "anal beads",
 		namecap: "Anal beads",
 		name_underscore: "anal_beads",
 		description: "For anal play. This item can be worn in your bottom or played with.",
 		cost: 8000,
-		type: ["dildo","anal"],
+		type: ["dildo", "anal"],
 		category: "butt_plug",
 		wearable: 1,
 		size: 2,
 		icon: "img/misc/icon/sexToys/analbeads.png",
 		colour: 1,
-		colour_options: ["black","blue","teal","lime-green","light-pink","purple","tan","brown","red"],
+		colour_options: [
+			"black",
+			"blue",
+			"teal",
+			"lime-green",
+			"light-pink",
+			"purple",
+			"tan",
+			"brown",
+			"red",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 3,
 		name: "bullet vibe",
 		namecap: "Bullet vibe",
 		name_underscore: "bullet_vibe",
-		description: "The vibrations produced from this item give powerful orgasms. Good for people new to sex toys.",
+		description:
+			"The vibrations produced from this item give powerful orgasms. Good for people new to sex toys.",
 		cost: 12000,
 		wearable: 0,
 		size: 0,
 		category: "vibrator",
-		type: ["dildo","vibrator"],
+		type: ["dildo", "vibrator"],
 		icon: "img/misc/icon/sexToys/bulletvibe.png",
 		colour: 0,
 		colour_options: [],
@@ -115,8 +152,9 @@ setup.sextoys = [
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 4,
 		name: "butt plug",
 		namecap: "Butt plug",
@@ -126,17 +164,28 @@ setup.sextoys = [
 		wearable: 1,
 		size: 2,
 		category: "butt_plug",
-		type: ["dildo","anal"],
+		type: ["dildo", "anal"],
 		icon: "img/misc/icon/sexToys/buttplug.png",
 		colour: 1,
-		colour_options: ["black","blue","teal","lime-green","light-pink","purple","tan","brown","red"],
+		colour_options: [
+			"black",
+			"blue",
+			"teal",
+			"lime-green",
+			"light-pink",
+			"purple",
+			"tan",
+			"brown",
+			"red",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 5,
 		name: "strap-on",
 		namecap: "Strap-on",
@@ -147,18 +196,30 @@ setup.sextoys = [
 		wearable: 1,
 		size: 2,
 		category: "strap-on",
-		type: ["strap-on","fetish"],
+		type: ["strap-on", "fetish"],
 		icon: "img/misc/icon/clothes/strap-on.png",
 		colour: 1,
 		shape: "cock",
-		colour_options: ["black", "blue", "green", "pink", "purple", "red", "white", "yellow", "tan", "brown"],
+		colour_options: [
+			"black",
+			"blue",
+			"green",
+			"pink",
+			"purple",
+			"red",
+			"white",
+			"yellow",
+			"tan",
+			"brown",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 6,
 		name: "strap-on horse cock",
 		namecap: "Strap-on horse cock",
@@ -169,18 +230,30 @@ setup.sextoys = [
 		wearable: 1,
 		size: 4,
 		category: "strap-on",
-		type: ["strap-on","fetish"],
+		type: ["strap-on", "fetish"],
 		icon: "img/misc/icon/clothes/strap-on_horse_cock.png",
 		colour: 1,
 		shape: "horse cock",
-		colour_options: ["black", "blue", "green", "pink", "purple", "red", "white", "yellow", "tan", "brown"],
+		colour_options: [
+			"black",
+			"blue",
+			"green",
+			"pink",
+			"purple",
+			"red",
+			"white",
+			"yellow",
+			"tan",
+			"brown",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 7,
 		name: "strap-on knotted cock",
 		namecap: "Strap-on knotted cock",
@@ -191,18 +264,30 @@ setup.sextoys = [
 		wearable: 1,
 		size: 3,
 		category: "strap-on",
-		type: ["strap-on","fetish"],
+		type: ["strap-on", "fetish"],
 		icon: "img/misc/icon/clothes/strap-on_knotted_cock.png",
 		colour: 1,
-		colour_options: ["black", "blue", "green", "pink", "purple", "red", "white", "yellow", "tan", "brown"],
+		colour_options: [
+			"black",
+			"blue",
+			"green",
+			"pink",
+			"purple",
+			"red",
+			"white",
+			"yellow",
+			"tan",
+			"brown",
+		],
 		shape: "knotted cock",
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 8,
 		name: "lube",
 		namecap: "Lube",
@@ -224,7 +309,8 @@ setup.sextoys = [
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
 		display_condition: () => 1,
-	}, {
+	},
+	{
 		index: 9,
 		name: "stroker",
 		namecap: "stroker",
@@ -236,19 +322,31 @@ setup.sextoys = [
 		type: ["stroker"],
 		icon: "img/misc/icon/sexToys/onahole.png",
 		colour: 1,
-		colour_options: ["black","blue","teal","lime-green","light-pink","purple","tan","brown","red"],
+		colour_options: [
+			"black",
+			"blue",
+			"teal",
+			"lime-green",
+			"light-pink",
+			"purple",
+			"tan",
+			"brown",
+			"red",
+		],
 		owned: setup.sextoyFunctions.owned,
 		isCarried: setup.sextoyFunctions.isCarried,
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}, {
+		display_condition: () => 1,
+	},
+	{
 		index: 10,
 		name: "aphrodisiac pills",
 		namecap: "Aphrodisiac pills",
 		name_underscore: "aphrodisiac_pills",
-		description: "A pack of three aphrodisiac pills. The instructions say to take 'a suitable number' before sex for an enhanced experience.",
+		description:
+			"A pack of three aphrodisiac pills. The instructions say to take 'a suitable number' before sex for an enhanced experience.",
 		cost: 4000,
 		wearable: 0,
 		size: 3,
@@ -264,90 +362,115 @@ setup.sextoys = [
 		isWorn: setup.sextoyFunctions.isWorn,
 		unWear: setup.sextoyFunctions.unWear,
 		unCarry: setup.sextoyFunctions.unCarry,
-		display_condition: () => 1
-	}
+		display_condition: () => 1,
+	},
 ];
 
-window.sexShopGridInit = function(){
-	$(function(){
-		for (let item of setup.sextoys){
-			if (item.display_condition())
-				window.sexShopGridAddItemBox(item)
+function sexShopGridInit() {
+	$(function () {
+		for (const item of setup.sextoys) {
+			if (item.display_condition()) window.sexShopGridAddItemBox(item);
 		}
-	})
+	});
 }
+window.sexShopGridInit = sexShopGridInit;
 
-window.sexShopGridAddItemBox = function(item) {
+function sexShopGridAddItemBox(item) {
 	document.getElementById("sexShopMenuContainer").innerHTML += `
-	<div class="ssm_item" id="ssm_item_${item.name_underscore}" onclick="window.sexShopOnItemClick(${item.index})">
+	<div class="ssm_item" id="ssm_item_${item.name_underscore}" onclick="window.sexShopOnItemClick(${
+		item.index
+	})">
 		<div class="ssm_icon">
-			<img id="ssm_item_icon_${item.name_underscore}" src="${item.icon}" class="${(item.colour == 1 ? "clothes-" + item.colour_options.random() : "")}">
+			<img id="ssm_item_icon_${item.name_underscore}" src="${item.icon}" class="${
+		item.colour === 1 ? "clothes-" + item.colour_options.random() : ""
+	}">
 		</div>
 		<div class="ssm_details">
 			<div class="ssm_item_name">
 				${item.namecap}
 			</div>
 			<div class="ssm_already_owned">
-				${(item.owned() > 0 ? `<span class="ssm_owned_text">owned</span>` : "")}
+				${item.owned() > 0 ? '<span class="ssm_owned_text">owned</span>' : ""}
 			</div>
 		</div>
 	</div>
 	`;
 }
+window.sexShopGridAddItemBox = sexShopGridAddItemBox;
 
-window.sexShopOnColourClick = function(colour){
-	for (let elem of document.getElementsByClassName("colour-button div-link "))
+function sexShopOnColourClick(colour) {
+	for (const elem of document.getElementsByClassName("colour-button div-link "))
 		elem.classList.remove("active");
 	document.querySelectorAll(`[colour-name="${colour}"]`)[0].classList.add("active");
-	document.getElementById("ssm_desc_img").className = "clothes-"+colour
+	document.getElementById("ssm_desc_img").className = "clothes-" + colour;
 }
+window.sexShopOnColourClick = sexShopOnColourClick;
+
+function removeClassNameAt(id) {
+	const elements = document.getElementsByClassName(id);
+	for (const element of elements) {
+		element.classList.remove(id);
+	}
+}
+
+function sexShopOnCloseDesc(id) {
+	const element = document.getElementById(id);
+	if (element == null) {
+		// TODO: Log
+		return;
+	}
+	element.style.display = "none";
 
-window.sexShopOnCloseDesc = function (elem_id) {
-	document.getElementById(elem_id).style.display = 'none';
 	/* grid item box class changes */
-	try{
-		document.getElementsByClassName("ssm_selected_a")[0].classList.remove("ssm_selected_a");
-		document.getElementsByClassName("ssm_selected_b")[0].classList.remove("ssm_selected_b");
-		document.getElementsByClassName("ssm_selected_c")[0].classList.remove("ssm_selected_c");
-	}catch{;}
+	removeClassNameAt("ssm_selected_a");
+	removeClassNameAt("ssm_selected_b");
+	removeClassNameAt("ssm_selected_c");
 }
+window.sexShopOnCloseDesc = sexShopOnCloseDesc;
 
-window.sexShopOnItemClick = function (index) {
-	let item = setup.sextoys[index]
-	let coloring_div = "";
+function sexShopOnItemClick(index) {
+	const item = setup.sextoys[index];
+	let coloringDiv = "";
 
 	/* clear "Bought!/Buy it" fade in setTimeout from window.sexShopOnBuyClick */
-	if (window.sexShopOnGiftClick.counter !== undefined && window.sexShopOnGiftClick.counter != "off"){
-		clearTimeout(window.sexShopOnGiftClick.counter)
-		window.sexShopOnGiftClick.counter = "off"
+	if (sexShopOnGiftClick.counter !== undefined && sexShopOnGiftClick.counter !== "off") {
+		clearTimeout(sexShopOnGiftClick.counter);
+		sexShopOnGiftClick.counter = "off";
 	}
-	if (window.sexShopOnBuyClick.counter !== undefined && window.sexShopOnBuyClick.counter != "off"){
-		clearTimeout(window.sexShopOnBuyClick.counter)
-		window.sexShopOnBuyClick.counter = "off"
+	if (sexShopOnBuyClick.counter !== undefined && sexShopOnBuyClick.counter !== "off") {
+		clearTimeout(window.sexShopOnBuyClick.counter);
+		sexShopOnBuyClick.counter = "off";
 	}
 	/* grid item box class changes */
-	try{
-		document.getElementsByClassName("ssm_selected_a")[0].classList.remove("ssm_selected_a")
-		document.getElementsByClassName("ssm_selected_b")[0].classList.remove("ssm_selected_b")
-		document.getElementsByClassName("ssm_selected_c")[0].classList.remove("ssm_selected_c")
-	}catch{;}
-	$(`#ssm_item_${item.name_underscore}`)[0].classList.add("ssm_selected_a")
-	$(`#ssm_item_${item.name_underscore} > .ssm_details > .ssm_item_name`)[0].classList.add("ssm_selected_b")
-	$(`#ssm_item_${item.name_underscore} > .ssm_details > .ssm_already_owned`)[0].classList.add("ssm_selected_c")
+	removeClassNameAt("ssm_selected_a");
+	removeClassNameAt("ssm_selected_b");
+	removeClassNameAt("ssm_selected_c");
+	$(`#ssm_item_${item.name_underscore}`)[0].classList.add("ssm_selected_a");
+	$(`#ssm_item_${item.name_underscore} > .ssm_details > .ssm_item_name`)[0].classList.add(
+		"ssm_selected_b"
+	);
+	$(`#ssm_item_${item.name_underscore} > .ssm_details > .ssm_already_owned`)[0].classList.add(
+		"ssm_selected_c"
+	);
 	/* description/buying box */
-	for (let index in item.colour_options) {
-		coloring_div +=
-			(index == 0 ? `<br><span style="color: #e0e0e0">Colours to choose from : </span><div id="ssm_colour_panel" class="colour-options-div"><br> ` : "") + `
+	for (const index in item.colour_options) {
+		coloringDiv +=
+			(index === 0
+				? `<br><span style="color: #e0e0e0">Colours to choose from : </span><div id="ssm_colour_panel" class="colour-options-div"><br> `
+				: "") +
+			`
 			<div colour-name="${item.colour_options[index]}" onclick="window.sexShopOnColourClick(\`${item.colour_options[index]}\`)" class="colour-button div-link">
 				<div class="bg-${item.colour_options[index]}">
 					<span class="capitalize colour-name-span">${item.colour_options[index]}</span>
 					<a tabindex="0"></a>
 				</div>
-			</div>`
+			</div>`;
 	}
-	coloring_div += "</div>";
-	document.getElementById("ssm_descContainer").innerHTML = `
-	<div id="ssm_desc_img" class="` + document.getElementById("ssm_item_icon_" + item.name_underscore).className + `">
+	coloringDiv += "</div>";
+	document.getElementById("ssm_descContainer").innerHTML =
+		`<div id="ssm_desc_img" class="` +
+		document.getElementById("ssm_item_icon_" + item.name_underscore).className +
+		`">
 		<img style="" src="${item.icon}">
 	</div>
 	<div class="ssm_desc_border">
@@ -357,153 +480,185 @@ window.sexShopOnItemClick = function (index) {
 				</div>
 			</div>
 			<span style="color: #bcbcbc">${item.description}</span>
-			<div id="ssm_desc_action">${coloring_div}<div style="text-align: center;">
+			<div id="ssm_desc_action">${coloringDiv}<div style="text-align: center;">
 				<br>
-				` + (V.money >= item.cost ? `<a id="ssmBuyButton" onclick="window.sexShopOnBuyClick(${item.index})" class="ssm_buy_button">
+				` +
+		(V.money >= item.cost
+			? `<a id="ssmBuyButton" onclick="window.sexShopOnBuyClick(${item.index})" class="ssm_buy_button">
 					Buy it
-				</a> (<span class="gold">£` + item.cost / 100 + `</span>)` : `<span class="ssm_not_enough_money">Not enough money</span>` ) +
-				(item.type.includes("strap-on") ? window.determineRecipient(item.index) : "") +
-				`</div>
+				</a> (<span class="gold">£` +
+			  item.cost / 100 +
+			  `</span>)`
+			: `<span class="ssm_not_enough_money">Not enough money</span>`) +
+		(item.type.includes("strap-on") ? determineRecipient(item.index) : "") +
+		`</div>
 			</div>
 		</div>
 	</div>
-	`
-	document.getElementById("ssmDescPillContainer").style.display = ""
+	`;
+	document.getElementById("ssmDescPillContainer").style.display = "";
 }
+window.sexShopOnItemClick = sexShopOnItemClick;
+
+// conditions for gifting items to people
+function determineRecipient(index) {
+	const item = setup.sextoys[index];
+	let optionBuilder = "";
+
+	const giftBr = document.getElementById("giftBr");
+	if (giftBr != null) giftBr.remove();
 
-window.determineRecipient = function(index) { // conditions for gifting items to people
-	let item = setup.sextoys[index];
-	let builder;
-	let option_builder = '';
+	// Add 15$ for gifting paperwrap
+	if (V.money < item.cost + 15 * 100) return "";
 
-	if (document.getElementById("giftBr"))
-		document.getElementById("giftBr").remove()
-	if (V.money < (item.cost + (15 * 100))) // Add 15$ for gifting paperwrap
-		return "";
-	
-	for (let li of ["Alex", "Eden", "Kylar", "Robin", "Sydney"]){
-		if (V.loveInterest.primary == li || V.loveInterest.secondary == li || V.loveInterest.tertiary == li){
-			option_builder += (`<option value="${li}">${li}</option>`)
+	for (const li of ["Alex", "Eden", "Kylar", "Robin", "Sydney"]) {
+		if (
+			V.loveInterest.primary === li ||
+			V.loveInterest.secondary === li ||
+			V.loveInterest.tertiary === li
+		) {
+			optionBuilder += `<option value="${li}">${li}</option>`;
 		}
 	}
-	if (option_builder == "") // if no possible recipient, return.
-		return ""
-	builder = `<br id="giftBr"><a id="ssmGiftButton" onclick="window.sexShopOnGiftClick(${item.index})" class="ssm_gift_button">
-	Make a gift for :  </a><select name="recipient" id="recipientList">${option_builder}</select>
-	<div id="spanGift">(<span class="gold">£${(item.cost / 100) + 15}</span>)</div>`
-	return builder
+	// if no possible recipient, return.
+	if (optionBuilder === "") return "";
+	const builder = `<br id="giftBr"><a id="ssmGiftButton" onclick="window.sexShopOnGiftClick(${
+		item.index
+	})" class="ssm_gift_button">
+	Make a gift for :  </a><select name="recipient" id="recipientList">${optionBuilder}</select>
+	<div id="spanGift">(<span class="gold">£${item.cost / 100 + 15}</span>)</div>`;
+	return builder;
 }
+window.determineRecipient = determineRecipient;
 
-window.sexShopOnGiftClick = function (index) {
-	let item = setup.sextoys[index];
-	let icon_class_name = document.getElementById("ssm_desc_img").className
+function sexShopOnGiftClick(index) {
+	const item = setup.sextoys[index];
+	const iconClassName = document.getElementById("ssm_desc_img").className;
 	let recipient = document.getElementById("recipientList").value.toLowerCase();
 
-	recipient = window.findIndexInNPCNameVar(recipient)
-	if (recipient == undefined ) return;
-	
-	window.sexShopOnGiftClick.counter = window.sexShopOnGiftClick.counter || "off"
+	// Leaving window in because of file order, that I don't want to deal with.
+	recipient = window.findIndexInNPCNameVar(recipient);
+	if (recipient === undefined) return;
+
+	sexShopOnGiftClick.counter = sexShopOnGiftClick.counter || "off";
 	/* add item to NPC's inventory */
-	if (V.NPCName[recipient].sextoys == undefined)
-		V.NPCName[recipient].sextoys = {}
-	if (V.NPCName[recipient].sextoys[item.name] == undefined)
-		V.NPCName[recipient].sextoys[item.name] = []
-	let obj = {
-		"index": item.index,
-		"name": item.name,
-		"namecap": item.namecap,
-		"colour": (icon_class_name == '' ? item.default_colour : icon_class_name.substring(icon_class_name.indexOf("-") + 1)),
-		"worn": false,
-		"size": item.size,
-		"carried": false,
-		"state": "worn",
-		"state_base": "worn",
-		"gift_state": "held",
-		"uses": (item.uses ? item.uses : undefined),
-		"shape": (item.shape ? item.shape : undefined)
-	}
-	if (item.category == "strap-on") {
-		obj.clothes_index = item.clothes_index
+	if (V.NPCName[recipient].sextoys == null) V.NPCName[recipient].sextoys = {};
+	if (V.NPCName[recipient].sextoys[item.name] == null)
+		V.NPCName[recipient].sextoys[item.name] = [];
+	const obj = {
+		index: item.index,
+		name: item.name,
+		namecap: item.namecap,
+		colour:
+			iconClassName === ""
+				? item.default_colour
+				: iconClassName.substring(iconClassName.indexOf("-") + 1),
+		worn: false,
+		size: item.size,
+		carried: false,
+		state: "worn",
+		state_base: "worn",
+		gift_state: "held",
+		uses: item.uses ? item.uses : undefined,
+		shape: item.shape ? item.shape : undefined,
+	};
+	if (item.category === "strap-on") {
+		obj.clothes_index = item.clothes_index;
 	}
 	V.NPCName[recipient].sextoys[item.name].push(obj);
 	/* withdraw money from player */
-	V.money -= (item.cost + (15 * 100))
+	V.money -= item.cost + 15 * 100;
 
 	/* update sidebar money */
-	window.updateSideBarMoney()
+	updateSideBarMoney();
 
 	/* fade in/out bought green text indicator */
-	document.getElementById("ssmGiftButton").outerHTML = `<span class="ssm_gift_button ssm_fade_in" id="ssmGiftButton" style="color:#97de97">Bought!</span>`
-	document.getElementById("recipientList").remove()
-	document.getElementById("spanGift").remove()
-	if (window.sexShopOnGiftClick.counter == "off"){
-		window.sexShopOnGiftClick.counter = window.setTimeout(function(){
-			document.getElementById("ssmGiftButton").outerHTML = window.determineRecipient(index);
-		window.sexShopOnGiftClick.counter = "off"
-		}, 1400)
+	document.getElementById(
+		"ssmGiftButton"
+	).outerHTML = `<span class="ssm_gift_button ssm_fade_in" id="ssmGiftButton" style="color:#97de97">Bought!</span>`;
+	document.getElementById("recipientList").remove();
+	document.getElementById("spanGift").remove();
+	if (sexShopOnGiftClick.counter === "off") {
+		sexShopOnGiftClick.counter = setTimeout(function () {
+			document.getElementById("ssmGiftButton").outerHTML = determineRecipient(index);
+			sexShopOnGiftClick.counter = "off";
+		}, 1400);
 	}
 }
+window.sexShopOnGiftClick = sexShopOnGiftClick;
 
-window.sexShopOnBuyClick = function (index) {
-	let item = setup.sextoys[index]
-	let icon_class_name = document.getElementById("ssm_desc_img").className
-	window.sexShopOnBuyClick.counter = window.sexShopOnBuyClick.counter || "off"
+function sexShopOnBuyClick(index) {
+	const item = setup.sextoys[index];
+	const iconClassName = document.getElementById("ssm_desc_img").className;
+	sexShopOnBuyClick.counter = sexShopOnBuyClick.counter || "off";
 	/* add item to player inventory */
-	if (V.player.inventory.sextoys[item.name] == undefined)
-		V.player.inventory.sextoys[item.name] = []
-	let obj = {
-		"index": item.index,
-		"colour": (icon_class_name == '' ? item.default_colour : icon_class_name.substring(icon_class_name.indexOf("-") + 1)),
-		"name": item.name,
-		"namecap": item.namecap,
-		"worn": false,
-		"type": item.type,
-		"size": item.size,
-	//	"sizeDesc": {0: "", 1: "", 2: "", 3: "large", 4: "massive"}[item.size],
-	//	"desc": (this.sizeDesc + " " + this.colour + " " + this.name),
-		"carried": false,
-		"state": "removed",
-		"state_base": "worn",
-		"shape": (item.shape ? item.shape : undefined),
-		"uses": (item.uses ? item.uses : undefined)
-	}
-	if (item.category == "strap-on") {
-		obj.clothes_index = item.clothes_index
+	if (V.player.inventory.sextoys[item.name] === undefined)
+		V.player.inventory.sextoys[item.name] = [];
+	const obj = {
+		index: item.index,
+		colour:
+			iconClassName === ""
+				? item.default_colour
+				: iconClassName.substring(iconClassName.indexOf("-") + 1),
+		name: item.name,
+		namecap: item.namecap,
+		worn: false,
+		type: item.type,
+		size: item.size,
+		// "sizeDesc": {0: "", 1: "", 2: "", 3: "large", 4: "massive"}[item.size],
+		// "desc": (this.sizeDesc + " " + this.colour + " " + this.name),
+		carried: false,
+		state: "removed",
+		state_base: "worn",
+		shape: item.shape ? item.shape : undefined,
+		uses: item.uses ? item.uses : undefined,
+	};
+	if (item.category === "strap-on") {
+		obj.clothes_index = item.clothes_index;
 	}
-	V.player.inventory.sextoys[item.name].push(obj)
+	V.player.inventory.sextoys[item.name].push(obj);
 	/* withdraw money from player */
-	V.money -= item.cost
+	V.money -= item.cost;
 	/* update sidebar money */
-	window.updateSideBarMoney()
+	updateSideBarMoney();
 	/* fade in "owned" icon */
-	document.getElementById("ssm_item_" + item.name_underscore).getElementsByClassName("ssm_already_owned")[0].innerHTML = `<span class="ssm_owned_text ssm_fade_in">owned</span>`
+	document
+		.getElementById("ssm_item_" + item.name_underscore)
+		.getElementsByClassName(
+			"ssm_already_owned"
+		)[0].innerHTML = `<span class="ssm_owned_text ssm_fade_in">owned</span>`;
 	/* fade in/out bought green text indicator */
-	document.getElementById("ssmBuyButton").outerHTML = `<span class="ssm_buy_button ssm_fade_in" id="ssmBuyButton" style="color:#97de97">Bought!</span>`
-	if (window.sexShopOnBuyClick.counter == "off"){
-		window.sexShopOnBuyClick.counter = window.setTimeout(function(){
+	document.getElementById(
+		"ssmBuyButton"
+	).outerHTML = `<span class="ssm_buy_button ssm_fade_in" id="ssmBuyButton" style="color:#97de97">Bought!</span>`;
+	if (sexShopOnBuyClick.counter === "off") {
+		sexShopOnBuyClick.counter = setTimeout(function () {
 			if (document.getElementById("ssmBuyButton"))
-			document.getElementById("ssmBuyButton").outerHTML = `<a id="ssmBuyButton" onclick="window.sexShopOnBuyClick(` + index + `)" class="ssm_buy_button ssm_fade_in_fast">
+				document.getElementById("ssmBuyButton").outerHTML =
+					`<a id="ssmBuyButton" onclick="window.sexShopOnBuyClick(` +
+					index +
+					`)" class="ssm_buy_button ssm_fade_in_fast">
 			Buy it
 		</a>`;
-		window.sexShopOnBuyClick.counter = "off"
-		}, 1400)
+			sexShopOnBuyClick.counter = "off";
+		}, 1400);
 	}
 }
+window.sexShopOnBuyClick = sexShopOnBuyClick;
 
-window.createInventoryObject = function(){ // create Inventory object if it doesn't exist
-	var recipient;
-
-	if (V.player.inventory == undefined)
-		V.player.inventory = {}
-	if (V.player.inventory.sextoys == undefined)
-		V.player.inventory.sextoys = {}
-	for (let li of ["alex", "eden", "kylar", "robin", "sydney"]){
-		recipient = window.findIndexInNPCNameVar(li)
-		if (V.NPCName[recipient].sextoys == undefined)
-			V.NPCName[recipient].sextoys = {}
+// create Inventory object if it doesn't exist
+function createInventoryObject() {
+	let recipient;
+	if (V.player.inventory == null) V.player.inventory = {};
+	if (V.player.inventory.sextoys == null) V.player.inventory.sextoys = {};
+	for (const li of ["alex", "eden", "kylar", "robin", "sydney"]) {
+		recipient = window.findIndexInNPCNameVar(li);
+		if (V.NPCName[recipient].sextoys == null) V.NPCName[recipient].sextoys = {};
 	}
 }
+window.createInventoryObject = createInventoryObject;
 
-window.updateSideBarMoney = function(){
-	new Wikifier(null, '<<updatesidebarmoney>>');
-}
\ No newline at end of file
+function updateSideBarMoney() {
+	Wikifier.wikifyEval("<<updatesidebarmoney>>");
+}
+window.updateSideBarMoney = updateSideBarMoney;
diff --git a/game/03-JavaScript/sexToysInventory.js b/game/03-JavaScript/sexToysInventory.js
index 7b6198e1c6..3670ae8b39 100644
--- a/game/03-JavaScript/sexToysInventory.js
+++ b/game/03-JavaScript/sexToysInventory.js
@@ -1,34 +1,38 @@
-const max_carried = 5; // maximum player can carry
+const maxCarried = 5; // maximum player can carry
 
 function sexToysInventoryInit() {
-	$(function() {
-		const min_cells = 12;
-		const main_grid = document.getElementById("sti_grid");
+	$(function () {
+		const minCells = 12;
+		const mainGrid = document.getElementById("sti_grid");
+		if (mainGrid == null) return; // TODO: Log
 		Object.keys(V.player.inventory.sextoys).forEach(category => {
 			const setupItem = setup.sextoys.find(toy => toy.name === category);
-			V.player.inventory.sextoys[category].forEach((item, index) => { // look for each items owned of a particular type
+			// look for each items owned of a particular type
+			V.player.inventory.sextoys[category].forEach((item, index) => {
 				if (setupItem) {
-					const item_class_name = category.replace(/\s/g, '_') + "_" + index;
-					const itemStatus = (item.worn ? "worn" : item.carried ? "carried" : "");
-					const itemColour = (setupItem.colour === 1 ? "clothes-" + item.colour : "");
-					main_grid.innerHTML +=
-						`<div id="sti_item_${item_class_name}" class="sti_cell sti_full" onclick="window.sexToysInventoryOnItemClick(${index},\`${category}\`)" class="">
+					const itemClassName = category.replace(/\s/g, "_") + "_" + index;
+					const itemStatus = item.worn ? "worn" : item.carried ? "carried" : "";
+					const itemColour = setupItem.colour === 1 ? "clothes-" + item.colour : "";
+					mainGrid.innerHTML += `<div id="sti_item_${itemClassName}" class="sti_cell sti_full" onclick="window.sexToysInventoryOnItemClick(${index},\`${category}\`)" class="">
 							<div style="position:relative;z-index: 1;">
 								<div class="sti_already_owned">
-								<span data-category="${category}" data-index="${index}" id="sti_already_owned_${item_class_name}" class="sti_owned_text">${itemStatus}</span>
+								<span data-category="${category}" data-index="${index}" id="sti_already_owned_${itemClassName}" class="sti_owned_text">${itemStatus}</span>
 								</div>
 							</div>
-							<img id="sti_item_icon_${item_class_name}" src="${setupItem.icon}" class="${itemColour}"></img>
+							<img id="sti_item_icon_${itemClassName}" src="${setupItem.icon}" class="${itemColour}"></img>
 							</div>
 						</div>`;
 				}
 			});
 		});
-		while ((main_grid.childElementCount - 1) < min_cells || (main_grid.childElementCount - 1) % 4 != 0) { // minimum of 12 cells. minimum 4 cells per row
-			main_grid.innerHTML += '<div class="sti_cell sti_empty"></div>';
+		while (
+			mainGrid.childElementCount - 1 < minCells ||
+			(mainGrid.childElementCount - 1) % 4 !== 0
+		) {
+			// minimum of 12 cells. minimum 4 cells per row
+			mainGrid.innerHTML += '<div class="sti_cell sti_empty"></div>';
 		}
-		main_grid.innerHTML +=
-			`<div style="position: relative;">
+		mainGrid.innerHTML += `<div style="position: relative;">
 				<div id="carryCount" class="sti_grid_carried_count"></div>
 			</div>`;
 		updateCarryCountUI();
@@ -46,7 +50,9 @@ function sexToysInventoryOnItemClick(index, category) {
 	if (selectedBox) selectedBox.classList.remove("sti_selected");
 
 	const invItem = V.player.inventory.sextoys[category][index];
-	const invItemClassName = document.getElementById(`sti_item_icon_${item.name_underscore}_${index}`).className;
+	const invItemClassName = document.getElementById(
+		`sti_item_icon_${item.name_underscore}_${index}`
+	).className;
 
 	$(`#sti_item_${item.name_underscore}_${index}`)[0].classList.add("sti_selected");
 	/* description box */
@@ -62,12 +68,12 @@ function sexToysInventoryOnItemClick(index, category) {
 			<span style="color:#bcbcbc">${item.description}</span>
 			<div id="sti_desc_action">
 				<br><a id="stiCarryButton" onclick="window.sexToysInventoryOnCarryClick(${index},'${category}')" class="sti_carry_button">
-					${(invItem.carried ? "Put it back" : "Carry it")}
+					${invItem.carried ? "Put it back" : "Carry it"}
 				</a>
-				${(setup.sextoys[invItem.index].wearable == 1 ? "<br>" : "")}
-				<a style="${(setup.sextoys[invItem.index].wearable == 1 ? "" : "display: none;")}" id="stiWearButton"
+				${setup.sextoys[invItem.index].wearable === 1 ? "<br>" : ""}
+				<a style="${setup.sextoys[invItem.index].wearable === 1 ? "" : "display: none;"}" id="stiWearButton"
 					onclick="window.sexToysInventoryOnWearClick(${index},'${category}')" class="sti_wear_button">
-						${(invItem.worn ? "Take it off" : "Wear it")}
+						${invItem.worn ? "Take it off" : "Wear it"}
 				</a>
 				<br><a id="stiThrowButton" onclick="window.sexToysInventoryOnThrowClick(${index},'${category}')" class="sti_throw_button">
 					Throw it away
@@ -82,29 +88,37 @@ window.sexToysInventoryOnItemClick = sexToysInventoryOnItemClick;
 
 /**
  * Top button.
+ *
  * @param {number} index Position in category.
  * @param {string} category Type within sextoy inventory.
- * @returns void
+ * @returns {void}
  */
 function sexToysInventoryOnCarryClick(index, category) {
 	const toy = V.player.inventory.sextoys[category][index];
 	const setupToy = setup.sextoys[toy.index];
 	const setupCategory = setupToy.category;
 
-	if (!toy.carried && countCarriedSextoys() >= max_carried) // if player has reached maximum item carried, stop the function
-		return;
-		toy.carried = !toy.carried;
-	if (toy.worn && setupCategory != "strap-on")
-		delete V.worn[setupCategory];
-	if (!toy.carried) // if player chose "Put back in the cupboard"
-		toy.worn = false; // also unwear the item
-	document.getElementById("stiWearButton").textContent = (toy.worn) ? "Take off" : "Wear it"; // update button text value
-	document.getElementById("stiCarryButton").textContent = (toy.carried != true ? "Carry it" : "Put back in the cupboard"); // update button text value
+	// if player has reached maximum item carried, stop the function
+	if (!toy.carried && countCarriedSextoys() >= maxCarried) return;
+	toy.carried = !toy.carried;
+
+	if (toy.worn && setupCategory !== "strap-on") delete V.worn[setupCategory];
+
+	// if player chose "Put back in the cupboard", also unwear the item
+	if (!toy.carried) toy.worn = false;
+	document.getElementById("stiWearButton").textContent = toy.worn ? "Take off" : "Wear it"; // update button text value
+	document.getElementById("stiCarryButton").textContent = toy.carried
+		? "Carry it"
+		: "Put back in the cupboard"; // update button text value
 	// update worn/carried tag on cell
-	document.getElementById("sti_already_owned_" + category.replace(/\s/g, '_') + "_" + index).textContent = (toy.worn ? "worn" : toy.carried ? "carried" : "");
-	if (setupCategory == "strap-on" && !toy.worn) { // this is an exception for strap-ons. Upon "wearing", also set them in under_lower as they don't have their own category yet.
+	document.getElementById(
+		"sti_already_owned_" + category.replace(/\s/g, "_") + "_" + index
+	).textContent = toy.worn ? "worn" : toy.carried ? "carried" : "";
+
+	// this is an exception for strap-ons. Upon "wearing", also set them in under_lower as they don't have their own category yet.
+	if (setupCategory === "strap-on" && !toy.worn) {
 		V.worn.under_lower = setup.clothes.under_lower[0];
-		Wikifier.wikifyEval(' <<updatesidebarimg>>');
+		Wikifier.wikifyEval(" <<updatesidebarimg>>");
 	}
 	updateCarryCountUI();
 	greyButtonsIfCarryLimitReached(index, category);
@@ -112,74 +126,100 @@ function sexToysInventoryOnCarryClick(index, category) {
 window.sexToysInventoryOnCarryClick = sexToysInventoryOnCarryClick;
 
 /**
- * Mid button.
- * @param {number} index Position
+ * Mid button - "Wear it" / "Take off".
+ *
+ * @param {number} index Position.
  * @param {string} category Category within the inventory of sextoys.
- * @returns void
+ * @returns {void}
  */
-function sexToysInventoryOnWearClick(index, category) { // "Wear it" / "Take off"
+function sexToysInventoryOnWearClick(index, category) {
 	const toy = V.player.inventory.sextoys[category][index];
 	const setupToy = setup.sextoys[toy.index];
 	const setupCategory = setupToy.category;
 
-	if (setupCategory === "strap-on" && V.worn.under_lower.cursed === 1) { // if player tries to wear a strapon but that under_lower is cursed
-		document.getElementById("stiCursedText").outerHTML = `<div id="stiCursedText" class="ssm_fade_in">You try to remove the ` + V.worn.under_lower.name + ` but fail</div>`;
+	// if player tries to wear a strapon but that under_lower is cursed
+	if (setupCategory === "strap-on" && V.worn.under_lower.cursed === 1) {
+		document.getElementById("stiCursedText").outerHTML =
+			`<div id="stiCursedText" class="ssm_fade_in">You try to remove the ` +
+			V.worn.under_lower.name +
+			` but fail</div>`;
 		return;
 	}
 
 	if (setupCategory === "butt_plug") {
 		if (V.worn.genitals.cursed === 1 && V.worn.genitals.anal_shield === 1) {
 			// if player tries to wear a butt plug but there is a cursed chastity belt fitted with an anal shield
-			document.getElementById("stiCursedText").outerHTML = `<div id="stiCursedText" class="ssm_fade_in">You can't push the ` + toy.name + ` past the ` + V.worn.genitals.name + `'s anal shield</div>`;
+			document.getElementById("stiCursedText").outerHTML =
+				`<div id="stiCursedText" class="ssm_fade_in">You can't push the ` +
+				toy.name +
+				` past the ` +
+				V.worn.genitals.name +
+				`'s anal shield</div>`;
 			return;
 		}
 	}
 
-	if (!toy.carried && countCarriedSextoys() >= max_carried) { 
+	if (!toy.carried && countCarriedSextoys() >= maxCarried) {
 		// if player has reached maximum item carried, stop the function
 		return;
 	}
 
-	if (setupCategory != "strap-on" && toy.worn) {
+	if (setupCategory !== "strap-on" && toy.worn) {
 		delete V.worn[setupCategory];
 	}
-	if (!toy.worn) { // If player chose "Wear it"
-		for (let s_item of setup.sextoys) { // retrieve main category of our item in setup.sextoys
-			if (s_item.name == category)
-				var cat = s_item.category;
+	// If player chose "Wear it"
+	let cat;
+	if (!toy.worn) {
+		// retrieve main category of our item in setup.sextoys
+		for (const sItem of setup.sextoys) {
+			if (sItem.name === category) cat = sItem.category;
 		}
-		for (let s_item of setup.sextoys) {// search for items with same main category
-			if (s_item.category == cat) { // we find item with same main category than the item we try to wear
-				for (let i_item in V.player.inventory.sextoys[s_item.name]) // we go through each of this item owned in player inventory
-					V.player.inventory.sextoys[s_item.name][i_item].worn = false; // we unwear each of them.
+		// search for items with same main category
+		for (const sItem of setup.sextoys) {
+			// we find item with same main category than the item we try to wear
+			if (sItem.category === cat) {
+				// we go through each of this item owned in player inventory
+				for (const iItem in V.player.inventory.sextoys[sItem.name]) {
+					// we unwear each of them.
+					V.player.inventory.sextoys[sItem.name][iItem].worn = false;
+				}
 			}
 		}
 	}
-	toy.worn = !toy.worn; // then wear chose item.
-	if (setupCategory != "strap-on") {
+	// then wear chose item.
+	toy.worn = !toy.worn;
+	if (setupCategory !== "strap-on") {
 		V.worn[setupCategory] = toy;
 		V.worn[setupCategory].state = "worn";
 	}
 	toy.carried = true; // also carry the item if not done alreadys
-	document.getElementById("stiWearButton").textContent = (toy.worn) ? "Take off" : "Wear it"; // update button text value
-	document.getElementById("stiCarryButton").textContent = (!toy.carried ? "Carry it" : "Put back in the cupboard"); // update button text value
-	document.getElementById("sti_already_owned_" + category.replace(/\s/g, '_') + "_" + index).textContent = (toy.worn ? "worn" : toy.carried ? "carried" : "");
+	document.getElementById("stiWearButton").textContent = toy.worn ? "Take off" : "Wear it"; // update button text value
+	document.getElementById("stiCarryButton").textContent = !toy.carried
+		? "Carry it"
+		: "Put back in the cupboard"; // update button text value
+	document.getElementById(
+		"sti_already_owned_" + category.replace(/\s/g, "_") + "_" + index
+	).textContent = toy.worn ? "worn" : toy.carried ? "carried" : "";
 	$("[id*='sti_already_owned_']").each(function (i, element) {
-		let c = element.getAttribute("data-category");
-		let ind = element.getAttribute("data-index");
-		element.textContent = (V.player.inventory.sextoys[c][ind].worn ? "worn" : V.player.inventory.sextoys[c][ind].carried ? "carried" : "");
+		const c = element.getAttribute("data-category");
+		const ind = element.getAttribute("data-index");
+		element.textContent = V.player.inventory.sextoys[c][ind].worn
+			? "worn"
+			: V.player.inventory.sextoys[c][ind].carried
+			? "carried"
+			: "";
 	});
-	if (setupCategory == "strap-on") { // this is an exception for strap-ons. Upon "wearing", also set them in under_lower as they don't have their own category yet.
+	// this is an exception for strap-ons. Upon "wearing", also set them in under_lower as they don't have their own category yet.
+	if (setupCategory === "strap-on") {
 		if (toy.worn) {
 			Wikifier.wikifyEval(' <<underlowerundress "wardrobe">>');
-			V.worn.under_lower = {
-				...setup.clothes.under_lower[toy.clothes_index],
-				...{ colour: toy.colour }
-			};
+			V.worn.under_lower = Object.assign({}, setup.clothes.under_lower[toy.clothes_index], {
+				colour: toy.colour,
+			});
+		} else {
+			V.worn.under_lower = setup.clothes.under_lower[0];
 		}
-		else
-			V.worn.under_lower = setup.clothes.under_lower[0]
-		Wikifier.wikifyEval(' <<updatesidebarimg>>');
+		Wikifier.wikifyEval(" <<updatesidebarimg>>");
 	}
 	updateCarryCountUI();
 	greyButtonsIfCarryLimitReached(index, category);
@@ -189,15 +229,17 @@ window.sexToysInventoryOnWearClick = sexToysInventoryOnWearClick;
 function sexToysInventoryOnThrowClick(index, category) {
 	const playerItem = V.player.inventory.sextoys[category][index];
 	const setupCategory = setup.sextoys[playerItem.index].category;
-	const last_index = document.getElementById("sti_grid").childElementCount - 1;
-	const category_name = category.replace(/\s/g, '_');
+	const lastIndex = document.getElementById("sti_grid").childElementCount - 1;
+	const categoryName = category.replace(/\s/g, "_");
 	/* remove div */
-	document.getElementById(`sti_item_${category_name}_${index}`).remove();
+	document.getElementById(`sti_item_${categoryName}_${index}`).remove();
 	/* add new empty div */
-	document.getElementById("sti_grid").children[last_index - 2].outerHTML += `<div class="sti_cell sti_empty"></div>`;
+	document.getElementById("sti_grid").children[
+		lastIndex - 2
+	].outerHTML += `<div class="sti_cell sti_empty"></div>`;
 	/* close description */
 	sextoysOnCloseDesc("stiDescPillContainer");
-	if (playerItem.worn && setupCategory != "strap-on") {
+	if (playerItem.worn && setupCategory !== "strap-on") {
 		delete V.worn[setupCategory];
 	}
 	/* handle strapons */
@@ -207,47 +249,60 @@ function sexToysInventoryOnThrowClick(index, category) {
 	}
 	/* remove item from inventory object */
 	V.player.inventory.sextoys[category].splice(index, 1);
-	$("[id*='sti_item']").each(function (i, element) { updateNumberInString(element, index, category) });
-	$("[id*='sti_already_owned']").each(function (i, element) { updateNumberInString(element, index, category) });
+	$("[id*='sti_item']").each(function (i, element) {
+		updateNumberInString(element, index, category);
+	});
+	$("[id*='sti_already_owned']").each(function (i, element) {
+		updateNumberInString(element, index, category);
+	});
 	updateCarryCountUI();
 }
 window.sexToysInventoryOnThrowClick = sexToysInventoryOnThrowClick;
 
-function sextoysOnCloseDesc(elem_id) {
-	document.getElementById(elem_id).style.display = 'none';
+function sextoysOnCloseDesc(id) {
+	document.getElementById(id).style.display = "none";
 	/* grid item box class changes */
 	const selectedBox = document.getElementsByClassName("sti_selected")[0];
 	if (selectedBox) selectedBox.classList.remove("sti_selected");
 }
 window.sextoysOnCloseDesc = sextoysOnCloseDesc;
 
-function updateNumberInString(element, index_min, category) {
-	if (!element.id.contains(category.replace(/\s/g, '_'))) return; //No need to update, this element is unrelated.
+function updateNumberInString(element, indexMin, category) {
+	// No need to update, this element is unrelated.
+	if (!element.id.contains(category.replace(/\s/g, "_"))) return;
 
-	const index = parseInt(element.id.match(/\d+$/)[0]); //extract the index from the element's ID and force it into a number.
+	// extract the index from the element's ID and force it into a number.
+	const index = parseInt(element.id.match(/\d+$/)[0]);
 
-	if (index === NaN) throw new Error(`Misconfigured sex toy ID: ${element.id}`);
-	if (index < index_min || index <= 0) return; //No need to update, this element comes BEFORE the removed item, so its index is unaffected.
+	if (isNaN(index)) throw new Error(`Misconfigured sex toy ID: ${element.id}`);
+	// No need to update, this element comes BEFORE the removed item, so its index is unaffected.
+	if (index < indexMin || index <= 0) return;
 
 	element.id = element.id.replace(/\d+/, index - 1);
 	if (element.getAttribute("onclick"))
-		element.setAttribute("onclick", `window.sexToysInventoryOnItemClick(${index - 1},\`${category}\`)`);
+		element.setAttribute(
+			"onclick",
+			`window.sexToysInventoryOnItemClick(${index - 1},\`${category}\`)`
+		);
 }
 
-function checkSextoysGift(npc_name) {
-	const npc = V.NPCName.find(n => n.nam === npc_name);
+function checkSextoysGift(npcName) {
+	const npc = V.NPCName.find(n => n.nam === npcName);
 	if (!npc) {
 		throw new Error("Invalid NPC name given!");
 	} else {
-		return Object.values(npc.sextoys).some(category => category.some(item => item.gift_state === "held"));
+		return Object.values(npc.sextoys).some(category =>
+			category.some(item => item.gift_state === "held")
+		);
 	}
 }
 window.checkSextoysGift = checkSextoysGift;
 
 function listUniqueCarriedSextoys() {
-	const list = []
+	const list = [];
 	Object.values(V.player.inventory.sextoys).forEach(category =>
-		category.filter(item => item.carried).forEach(item => list.push(item)));
+		category.filter(item => item.carried).forEach(item => list.push(item))
+	);
 	return list;
 }
 window.listUniqueCarriedSextoys = listUniqueCarriedSextoys;
@@ -267,20 +322,26 @@ function straponExceptionWearOff() {
 window.straponExceptionWearOff = straponExceptionWearOff;
 
 function patchStraponsWearStatus() {
-	Object.values(V.player.inventory.sextoys).forEach(category => category.filter(strapon => strapon.type.includes("strap-on")).forEach(strapon => {
-		if (strapon.name !== V.worn.under_lower.name) strapon.worn = false;
-		else if (strapon.colour == V.worn.under_lower.colour) strapon.worn = true;
-	}));
+	Object.values(V.player.inventory.sextoys).forEach(category =>
+		category
+			.filter(strapon => strapon.type.includes("strap-on"))
+			.forEach(strapon => {
+				if (strapon.name !== V.worn.under_lower.name) strapon.worn = false;
+				else if (strapon.colour === V.worn.under_lower.colour) strapon.worn = true;
+			})
+	);
 }
 window.patchStraponsWearStatus = patchStraponsWearStatus;
 
-function checkIfNPCHasCategorySextoy(npc_name, category) {
-	const npc = V.NPCName.find(n => n.nam === npc_name);
+function checkIfNPCHasCategorySextoy(npcName, category) {
+	const npc = V.NPCName.find(n => n.nam === npcName);
 	if (!npc) {
 		throw new Error("Invalid NPC name given!");
 	}
 
-	const categoryToyNames = Object.values(setup.sextoys).filter(n => n.category === category).map(n => n.name);
+	const categoryToyNames = Object.values(setup.sextoys)
+		.filter(n => n.category === category)
+		.map(n => n.name);
 	if (categoryToyNames.length === 0) {
 		throw new Error("Invalid sex toy category given!");
 	}
@@ -288,7 +349,7 @@ function checkIfNPCHasCategorySextoy(npc_name, category) {
 	const npcSexToys = [];
 	Object.values(npc.sextoys).forEach(category => {
 		category.forEach(item => {
-			if (categoryToyNames.includes(item.name) && item.gift_state != "held")
+			if (categoryToyNames.includes(item.name) && item.gift_state !== "held")
 				npcSexToys.push(item);
 		});
 	});
@@ -296,8 +357,8 @@ function checkIfNPCHasCategorySextoy(npc_name, category) {
 }
 window.checkIfNPCHasCategorySextoy = checkIfNPCHasCategorySextoy;
 
-function handSextoysGiftToNPC(npc_name) {
-	const npc = V.NPCName.find(n => n.nam === npc_name);
+function handSextoysGiftToNPC(npcName) {
+	const npc = V.NPCName.find(n => n.nam === npcName);
 	if (!npc) {
 		throw new Error("Invalid NPC name given!");
 	}
@@ -309,10 +370,9 @@ function handSextoysGiftToNPC(npc_name) {
 }
 window.handSextoysGiftToNPC = handSextoysGiftToNPC;
 
-function findIndexInNPCNameVar(npc_name) {
-	for (let npc in V.NPCName) {
-		if (V.NPCName[npc].nam.toLowerCase() == npc_name.toLowerCase())
-			return npc;
+function findIndexInNPCNameVar(npcName) {
+	for (const npc in V.NPCName) {
+		if (V.NPCName[npc].nam.toLowerCase() === npcName.toLowerCase()) return npc;
 	}
 }
 window.findIndexInNPCNameVar = findIndexInNPCNameVar;
@@ -328,27 +388,29 @@ function countCarriedSextoys() {
 window.countCarriedSextoys = countCarriedSextoys;
 
 function updateCarryCountUI() {
-	const colour = (countCarriedSextoys() >= max_carried ? "red" : "");
-	document.getElementById("carryCount").outerHTML =
-		`<div id="carryCount" class="sti_grid_carried_count">
-		Items carried: <span class="${colour}">${countCarriedSextoys()}/${max_carried}</span>
+	const colour = countCarriedSextoys() >= maxCarried ? "red" : "";
+	document.getElementById(
+		"carryCount"
+	).outerHTML = `<div id="carryCount" class="sti_grid_carried_count">
+		Items carried: <span class="${colour}">${countCarriedSextoys()}/${maxCarried}</span>
 	</div>`;
 }
 window.updateCarryCountUI = updateCarryCountUI;
 
 function greyButtonsIfCarryLimitReached(index, category) {
-	if (countCarriedSextoys() >= max_carried) {
+	if (countCarriedSextoys() >= maxCarried) {
 		const item = V.player.inventory.sextoys[category][index];
 		if (!item.carried) {
 			document.getElementById("stiCarryButton").classList.add("sti_carry_limit_reached");
-			if (!item.worn) document.getElementById("stiWearButton").classList.add("sti_carry_limit_reached");
+			if (!item.worn)
+				document.getElementById("stiWearButton").classList.add("sti_carry_limit_reached");
 		}
 	}
 }
 window.greyButtonsIfCarryLimitReached = greyButtonsIfCarryLimitReached;
 
-function wardrobeStripStraponException(item_name) {
-	V.player.inventory.sextoys[item_name].forEach(item => item.worn = false);
+function wardrobeStripStraponException(itemName) {
+	V.player.inventory.sextoys[itemName].forEach(item => (item.worn = false));
 	V.worn.under_lower = setup.clothes.under_lower[0];
 }
 window.wardrobeStripStraponException = wardrobeStripStraponException;
@@ -364,15 +426,14 @@ function setLowerVisibility(desiredVisibility) {
 	if (!T.lowerVisible) {
 		const tmp = V.worn.lower;
 		V.worn.lower = setup.clothes.lower[0];
-		Wikifier.wikifyEval('<<updatesidebarimg>>');
+		Wikifier.wikifyEval("<<updatesidebarimg>>");
 		V.worn.lower = tmp;
 	} else {
-		Wikifier.wikifyEval('<<updatesidebarimg>>');
+		Wikifier.wikifyEval("<<updatesidebarimg>>");
 	}
 
 	const elem = document.querySelector("#stiShowUnderwear > .link-internal");
-	if (elem !== null)
-		elem.text = (!T.lowerVisible ? "Show lower clothing" : "Hide lower clothing");
+	if (elem !== null) elem.text = !T.lowerVisible ? "Show lower clothing" : "Hide lower clothing";
 
 	Links.generateLinkNumbers($(".passage"));
 }
-- 
GitLab


From a88152f57ae51083398bd90f81606145f3e0976c Mon Sep 17 00:00:00 2001
From: xao <33469-xao321@users.noreply.gitgud.io>
Date: Sun, 21 Aug 2022 21:06:29 +0000
Subject: [PATCH 03/50] Locker room clothing rework

---
 game/03-JavaScript/base.js                    |  2 +-
 game/03-JavaScript/ingame.js                  | 30 ++++++
 game/04-Variables/variables-static.twee       | 11 +++
 .../04-Variables/variables-versionUpdate.twee |  5 +
 game/base-clothing/clothing-sets.twee         | 78 ++++++++++++---
 game/base-clothing/init.twee                  |  1 +
 game/base-clothing/wardrobes.twee             | 10 +-
 game/base-clothing/widgets.twee               | 95 ++++++++++++++++---
 game/base-combat/struggle.twee                |  2 +-
 game/base-debug/clothesTesting.twee           |  4 +-
 game/base-system/feats.twee                   |  2 +-
 game/base-system/time.twee                    |  2 +
 game/overworld-forest/loc-lake/widgets.twee   | 66 ++++++-------
 game/overworld-plains/loc-bird/widgets.twee   |  2 +-
 .../overworld-town/loc-dance-studio/main.twee | 46 +--------
 .../loc-dance-studio/widgets.twee             | 54 +++++++++++
 .../loc-school/changing-rooms.twee            | 40 ++++----
 .../loc-school/classes/swimming.twee          | 14 +--
 game/overworld-town/loc-school/main.twee      |  8 +-
 game/overworld-town/loc-school/widgets.twee   | 82 ++++++++++++++++
 game/overworld-town/loc-shop/clothing-v2.twee |  2 +-
 game/overworld-town/loc-shop/tailor.twee      |  2 +-
 game/overworld-town/loc-shop/tryOn.twee       | 12 +--
 game/overworld-town/loc-shop/widgets.twee     |  2 +-
 modules/02-array-extensions.js                | 27 +++++-
 25 files changed, 445 insertions(+), 154 deletions(-)
 create mode 100644 game/overworld-town/loc-dance-studio/widgets.twee

diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index f76ca35a60..b04b23cab1 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -349,7 +349,7 @@ window.outfitChecks = function(){
  * @return {boolean} whether or not any main-body clothing is out of place or wet
  */
  window.checkForExposedClothing = function(){
-	return ["over_upper", "upper", "under_upper", "over_lower", "lower", "under_lower"].some( clothingLayer => {
+	return setup.clothingLayer.torso.some( clothingLayer => {
 		let wetstage = V[clothingLayer.replace("_","") + "wetstage"];
 		return (V.worn[clothingLayer].state !== setup.clothes[clothingLayer][clothesIndex(clothingLayer, V.worn[clothingLayer])].state_base || wetstage >= 3);
 	})
diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index 62e4de80bf..f20a3f7b0b 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -1117,6 +1117,36 @@ function resetClothingState(slot) {
 }
 window.resetClothingState = resetClothingState;
 
+/* Returns array of clothing items that are stored in [loc] */
+window.clothingInStorage = function(loc) {
+	if(loc == null) return;
+	let clothing = [];
+	for(const slot of setup.clothingLayer.all) {
+		let item = V.store[slot].find(item => item.location === loc);
+		if(item && !item.outfitSecondary) {
+			item["slot"] = slot;
+			clothing.push(item);
+		}
+	}
+	return clothing;
+}
+
+/* Returns name of the current worn outfit, or "none" if no matches are found */
+window.currentOutfit = function() {
+	let compareOutfit = (outfit) => {
+		for(const slot of setup.clothingLayer.all) {
+			if(V.worn[slot].name != (outfit[slot] || "naked"))
+				return false;
+		}
+		return true;
+	}
+	for(const outfit of V.outfit) {
+		if(compareOutfit(outfit))
+			return outfit.name;
+	}
+	return "none";
+}
+
 function isConnectedToHood(slot) {
 	// Note: this function currently only works on hoods in the "head" slot, NOT the "over_head" slot.
 
diff --git a/game/04-Variables/variables-static.twee b/game/04-Variables/variables-static.twee
index 9908e3b3d5..51070cd8a7 100644
--- a/game/04-Variables/variables-static.twee
+++ b/game/04-Variables/variables-static.twee
@@ -483,6 +483,17 @@ and are required for processing for loops, default objects, etc.*/
 
 <<set setup.bodyparts to ["forehead", "left_cheek", "right_cheek", "left_shoulder", "right_shoulder", "breasts", "back", "left_bottom", "right_bottom", "pubic", "left_thigh", "right_thigh"]>>
 
+<<set setup.clothingLayer to {
+	"all": ["over_upper","over_lower","over_head","upper","lower","under_upper","under_lower","head","face","neck","hands","legs","feet"],
+	"body": ["upper","lower","under_upper","under_lower","head","face","neck","hands","legs","feet"],
+	"torso": ["over_upper","over_lower","upper","lower","under_upper","under_lower"],
+	"torso_inner": ["upper","lower","under_upper","under_lower"],
+	"torso_outer": ["over_upper","over_lower","upper","lower"],
+	"over": ["over_upper","over_lower","over_head"],
+	"upper": ["upper", "under_upper"],
+	"lower": ["lower","under_lower"]
+}>>
+
 <<set setup.actionsTypes to {
 	'personTypes': [
 		'Everyone', 'Strangers', 'Acquaintances', 'Alternative', 'Defiant', 'Submissive', 'Animals', 'Tentacles', 'Bailey', 'Robin', 'Whitney', 'Kylar', 'Sydney', 'Eden', 'Avery', 'Leighton'
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index f05ca7dfd3..966c531c99 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -3636,4 +3636,9 @@
 			   "enemytrust", "turnCount"].forEach( v => V[v] ? true : V[v] = 0)>>
 	<</if>>
 
+	<!-- v0.3.11.4 -->
+	<<if $outfitTmp is undefined>>
+		<<set $outfitTmp to {}>>
+	<</if>>
+
 <</widget>>
diff --git a/game/base-clothing/clothing-sets.twee b/game/base-clothing/clothing-sets.twee
index 368ca4c909..39f99a8829 100644
--- a/game/base-clothing/clothing-sets.twee
+++ b/game/base-clothing/clothing-sets.twee
@@ -23,14 +23,26 @@
 
 <<widget "listoutfitsPassage">>
 	<<set $wardrobe_location to _args[0]>>
+	<<set _store_location to _args[1] || _args[0]>>
 	<<wardrobeSelection true>>
-	<<for _index, $_outfit range $outfit>>
-		<<if ($_outfit.location and $_outfit.location isnot $wardrobe_location) or $_outfit.type.includes("swim") or $_outfit.type.includes("sleep")>>
+	<<for _index, _outfit range $outfit>>
+		<<if (_outfit.location and _outfit.location isnot $wardrobe_location) or _outfit.type.includes("swim") or _outfit.type.includes("sleep")>>
 			<<continue>>
 		<</if>>
-		<<capture _index>>
-			<<set _outfitname to $_outfit.name + ($_outfit.colors is false ? "" : " [C]")>>
-			<<link [["Wear "+_outfitname|$passage]]>><<set $eventskip to 1>><<set $wear_outfit to _index>><</link>>
+		<<capture _index _outfit>>
+			<<if _outfit.name is currentOutfit()>>
+				<span class="grey"><<print _outfit.name>> (Equipped)</span>
+			<<else>>
+				<<link [["Wear "+_outfit.name|$passage]]>>
+					<<if clothingInStorage(_store_location).length is 0>>
+						<<storesave _store_location>>
+					<</if>>
+					<<set $wearoutfittext to _outfit.name + " clothes">>
+					<<set $eventskip to 1>>
+					<<set $wear_outfit to _index>>
+					<<set $storeLocation to _args[0]>>
+				<</link>>
+			<</if>>
 			<br>
 		<</capture>>
 	<</for>>
@@ -84,14 +96,54 @@
 
 <<widget "listswimoutfits">>
 	<<set $wardrobe_location to _args[0]>>
+	<<set _store_location to _args[1] || _args[0]>>
 	<<wardrobeSelection true>>
-	<<for _index, $_outfit range $outfit>>
-		<<if ($_outfit.location and $_outfit.location isnot $wardrobe_location) or !$_outfit.type.includes("swim")>>
+	<<for _index, _outfit range $outfit>>
+		<<if (_outfit.location and _outfit.location isnot $wardrobe_location) or !_outfit.type.includes("swim")>>
 			<<continue>>
 		<</if>>
-		<<capture _index>>
-			<<set _outfitname to $_outfit.name + ($_outfit.colors is false ? "" : " [C]")>>
-			<<link [["Wear "+_outfitname|$passage]]>><<set $eventskip to 1>><<set $wear_outfit to _index>><<set $storeLocation to _args[0]>><</link>>
+		<<capture _index _outfit>>
+			<<if _outfit.name is currentOutfit()>>
+				<span class="grey"><<print _outfit.name>> (Equipped)</span>
+			<<else>>
+				<<link [["Wear "+_outfit.name|$passage]]>>
+					<<if clothingInStorage(_store_location).length is 0>>
+						<<storesave _store_location>>
+					<</if>>
+					<<set $wearoutfittext to _outfit.name>>
+					<<set $eventskip to 1>>
+					<<set $wear_outfit to _index>>
+					<<set $storeLocation to _args[0]>>
+				<</link>>
+			<</if>>
+			<br>
+		<</capture>>
+	<</for>>
+<</widget>>
+
+<<widget "listdancingclothes">>
+	<<set _store_location to _args[0]>>
+	<<set _slot to "under_upper">>
+	<<for _index, _outfit range $wardrobe[_slot].sort((a, b) => (a.name > b.name) ? 1 : -1)>>
+		<<if !_outfit.type.includes("dance")>>
+			<<continue>>
+		<</if>>
+		<<capture _outfit>>
+			<<if !$wardrobe['under_lower'].find(item => item.variable is _outfit.variable)>>
+				<span class="grey"><<print _outfit.name>> (Broken)</span>
+			<<elseif _outfit.name is currentOutfit()>>
+				<span class="grey"><<print _outfit.name>> (Equipped)</span>
+			<<else>>
+				<<link [["Wear "+_outfit.name|$passage]]>>
+					<<if clothingInStorage(_store_location).length is 0>>
+						<<storesave _store_location>>
+						<<set $wearoutfittext to 1>>
+					<</if>>
+					<<set $eventskip to 1>>
+					<<set _item_index to $wardrobe[_slot].indexOf(_outfit)>>
+					<<generalWearFromWardrobe _slot _item_index>>
+				<</link>>
+			<</if>>
 			<br>
 		<</capture>>
 	<</for>>
@@ -139,7 +191,7 @@
 	<<if $wear_outfit is "clotheson">>
 		<<storeon $storeLocation>>
 	<<elseif $wear_outfit isnot "none">>
-		<<set _equip to ["over_upper","over_lower","upper", "lower", "under_upper", "under_lower","over_head","head", "face", "neck", "hands", "legs", "feet"]>>
+		<<set _equip to setup.clothingLayer.all>>
 		<<set _equipSkip to {"over_upper":false, "over_lower":false, "upper":false, "lower":false, "under_upper":false, "under_lower":false, "over_head":false, "head":false, "face":false, "neck":false, "hands":false, "legs":false, "feet":false}>>
 		<<set _storeItemSkip to {"over_upper":false, "over_lower":false, "upper":false, "lower":false, "under_upper":false, "under_lower":false, "over_head":false, "head":false, "face":false, "neck":false, "hands":false, "legs":false, "feet":false}>>
 		<<set _equipDamageValue to {"over_upper":3, "over_lower":3, "upper":3, "lower":3, "under_upper":3, "under_lower":3, "over_head":1, "head":1, "face":1, "neck":1, "hands":1, "legs":1, "feet":1}>>
@@ -458,7 +510,7 @@
 
 <<widget "overwriteoutfit">>
 	<<if $delete_outfit is 2 and $wear_outfit isnot "none">>
-		<<set _equip to ["over_head","over_upper","over_lower","upper", "lower", "under_upper", "under_lower","head", "face", "neck", "hands", "legs", "feet"]>>
+		<<set _equip to setup.clothingLayer.all>>
 		<<set _outfit to $outfit[$wear_outfit]>>
 		<<for $_slot range _equip>>
 			<<set _outfit[$_slot] to $worn[$_slot].name>>
@@ -753,7 +805,7 @@ Page <<print _outfitEditorPages.page>>/<<print _outfitEditorPages.maxPages>> |
 <<capture _args[0]>>
 	<<for $_label, $_value range setup.clothes>>
 		<<set $_itemName to $outfit[_args[0]][$_label]>>
-		<<if $_itemName and !["over_upper","over_lower","over_head"].includes($_label)>>
+		<<if $_itemName and !setup.clothingLayer.over.includes($_label)>>
 			<label class="outfitEditorItemClothes">
 				<<set $_options to []>>
 				<<for $_value2 range $_value>>
diff --git a/game/base-clothing/init.twee b/game/base-clothing/init.twee
index 9828ef1869..335b67fedf 100644
--- a/game/base-clothing/init.twee
+++ b/game/base-clothing/init.twee
@@ -46,6 +46,7 @@
 <<set $store to {}>>
 <<set $outfit to []>>
 <<set $carried to {}>>
+<<set $outfitTmp to {}>>
 
 <<set $worn.over_upper to clone(setup.clothes.over_upper[0])>>
 <<set $worn.over_lower to clone(setup.clothes.over_lower[0])>>
diff --git a/game/base-clothing/wardrobes.twee b/game/base-clothing/wardrobes.twee
index e02dd672e4..3956435fda 100644
--- a/game/base-clothing/wardrobes.twee
+++ b/game/base-clothing/wardrobes.twee
@@ -654,8 +654,8 @@ Type: <label>Everyday <<radiobutton "$outfit_type" 0 checked>></label> | <label>
 	<<else>>
 		<<set _wear to "wear_"+_wardrobe_list>>
 
-		<<set _outfitTypes to ["upper","lower","under_upper","under_lower"]>>
-		<<set _loweroutfitCheck to ["lower","under_lower"]>>
+		<<set _outfitTypes to setup.clothingLayer.torso_inner>>
+		<<set _loweroutfitCheck to setup.clothingLayer.lower>>
 
 		__<<print _wardrobe_list[0].toUpperCase() + _wardrobe_list.substring(1)>>__ <i>_selectedWardrobe[_wardrobe_list].length / _selectedWardrobe.space</i>
 		<<if _wardrobe_list is "upper">>(Outfits will also take a lower slot)<</if>>
@@ -1137,7 +1137,7 @@ Type: <label>Everyday <<radiobutton "$outfit_type" 0 checked>></label> | <label>
 <</widget>>
 
 <<widget "wardrobeGetRepairedClothes">>
-<<set _equip to ["over_upper","over_lower","upper","lower","under_upper","under_lower","over_head","head","face","neck","hands","legs","feet"]>>
+<<set _equip to setup.clothingLayer.all >>
 <<set _takenAway to 0>>
 <<for $_i to 0; $_i lt _equip.length; $_i++>>
 	<<if $wardrobeRepair[_equip[$_i]] is undefined>>
@@ -1478,7 +1478,7 @@ It will earn you <<printmoney `_value + 5000`>>.
 
 <<set $tailorMonthlyService to 30>>
 <<set _value to 0>>
-<<set _equip to ["over_upper","over_lower","upper","lower","under_upper","under_lower","over_head","head","face","neck","hands","legs","feet"]>>
+<<set _equip to setup.clothingLayer.all>>
 <<for $_i to 0; $_i lt _equip.length; $_i++>>
 	<<set _toDelete to []>>
 	<<for $_j to 0; $_j lt $wardrobe[_equip[$_i]].length; $_j++>>
@@ -1553,7 +1553,7 @@ It will cost you
 
 <<set $tailorMonthlyService to 30>>
 <<set $wardrobeRepair to {timeLeft: 1}>>
-<<set _equip to ["over_upper","over_lower","upper","lower","under_upper","under_lower","over_head","head","face","neck","hands","legs","feet"]>>
+<<set _equip to setup.clothingLayer.all>>
 <<set _value to 0>>
 <<for $_i to 0; $_i lt _equip.length; $_i++>>
 	<<set _toDelete to []>>
diff --git a/game/base-clothing/widgets.twee b/game/base-clothing/widgets.twee
index 6d624fa84d..a8e00d89d0 100644
--- a/game/base-clothing/widgets.twee
+++ b/game/base-clothing/widgets.twee
@@ -682,13 +682,13 @@
 /*The "...on" widgets put on clothing removed with the "...strip" widgets.*/
 
 <<widget "outfiton">>
-	<<for $_slot range ["over_upper","over_lower","upper","lower"]>>
+	<<for $_slot range setup.clothingLayer.torso_inner>>
 		<<generalOn $_slot>>
 	<</for>>
 <</widget>>
 
 <<widget "clotheson">>
-	<<for $_slot range ["over_upper","over_lower","upper","lower","under_upper","under_lower","over_head","head","face","neck","hands","legs","feet"]>>
+	<<for $_slot range setup.clothingLayer.all>>
 		<<generalOn $_slot>>
 	<</for>>
 	<<buttplugon>>
@@ -815,14 +815,14 @@
 
 <<widget "steal">>
 	<<set _temp_steal to _args[0]>>
-	<<for $_slot range ["upper","lower","under_upper","under_lower","head","face","neck","hands","legs","feet"]>>
+	<<for $_slot range setup.clothingLayer.body>>
 		<<generalSteal $_slot _temp_steal>>
 	<</for>>
 <</widget>>
 
 <<widget "stealclothes">>
 	<<set _temp_steal to _args[0]>>
-	<<for $_slot range ["upper","lower","under_upper","under_lower"]>>
+	<<for $_slot range setup.clothingLayer.torso_inner>>
 		<<generalSteal $_slot _temp_steal>>
 	<</for>>
 <</widget>>
@@ -917,14 +917,14 @@
 
 <<widget "undress">>
 	<<set $_location to _args[0]>>
-	<<for $_slot range ["over_upper","over_lower","over_head","upper","lower","under_upper","under_lower","head","face","neck","hands","legs","feet"]>>
+	<<for $_slot range setup.clothingLayer.all>>
 		<<generalUndress $_location $_slot>>
 	<</for>>
 <</widget>>
 
 <<widget "undressKeepFace">>
 	<<set $_location to _args[0]>>
-	<<for $_slot range ["over_upper","over_lower","over_head","upper","lower","under_upper","under_lower","head","neck","hands","legs","feet"]>>
+	<<for $_slot range setup.clothingLayer.all.except("face")>>
 		<<generalUndress $_location $_slot>>
 	<</for>>
 <</widget>>
@@ -944,14 +944,14 @@
 
 <<widget "undressOverClothes">>
 	<<set $_location to _args[0]>>
-	<<for $_slot range ["over_upper","over_lower","over_head"]>>
+	<<for $_slot range setup.clothingLayer.over>>
 		<<generalUndress $_location $_slot>>
 	<</for>>
 <</widget>>
 
 <<widget "undressclothes">>
 	<<set $_location to _args[0]>>
-	<<for $_slot range ["over_upper","over_lower","upper","lower","under_upper","under_lower"]>>
+	<<for $_slot range setup.clothingLayer.torso>>
 		<<generalUndress $_location $_slot>>
 	<</for>>
 <</widget>>
@@ -1143,13 +1143,76 @@
 	<<generalUndress _args[0] "feet">>
 <</widget>>
 
-/*The "storeon..." widgets retrieve the clothing stored with the "...undress" widgets, that weren't put in a wardrobe. Requires the same argument that was used to store the clothing in order to correctly identify. Optionally accepts a second argument. Inputting "delete" will destroy the stored item, rather than wear it. Inputting "check" will set _store_check to 1, for when you want to check whether or not an item exists in a given location.*/
+/* Returns stored items that are a part of an outfit (wear_outfit) to the wardrobe so that they can be used by another outfit. */
+/* args[0] specifies the location identifier */
+<<widget "storereturn">>
+	<<if !isNaN($wear_outfit) and _args[0] isnot undefined>>
+		<<for $_slot range setup.clothingLayer.all>>
+			<<set $_name to $outfit[$wear_outfit][$_slot]>>
+			<<set $_item to $store[$_slot].find(item => item.location is _args[0])>>
+			<<generalStoreon _args[0] $_slot "check">>
+			<<if _store_check and $_item isnot undefined and $_name isnot "naked" and $_name isnot undefined>>
+				<<if $store[$_slot].length gt 0 and $_name is $_item.name>>
+					<<set $wardrobe[$_slot].push(clone($_item))>>
+					<<set $store[$_slot].deleteAt($store[$_slot].indexOf($_item))>>
+				<</if>>
+			<</if>>
+		<</for>>
+	<</if>>
+<</widget>>
+
+/* Unequips items, then saves a copy of stored items to a temporary variable */
+/* args[0] specifies the location identifier */
+<<widget "storesave">>
+	<<if _args[0] isnot undefined>>
+		<<undress _args[0]>>
+		<<set $outfitTmp[_args[0]] to {}>>
+		<<for $_slot range setup.clothingLayer.all>>
+			<<if $store[$_slot].length gt 0>>
+				<<set $_copy to $store[$_slot].find(item => item.location is _args[0])>>
+				<<if $_copy isnot undefined and $_copy.name isnot "naked" and $_copy.name isnot undefined>>
+					<<set $outfitTmp[_args[0]][$_slot] to clone($_copy)>>
+				<</if>>
+			<</if>>
+		<</for>>
+	<</if>>
+<</widget>>
+
+/* Loads a list of stored items previously saved by 'storesave', and tries to equip it on the player */
+/* If the items have been removed from storage, it checks if the player is currently wearing them, and will not unequip them if so */
+/* args[0] specifies the location identifier */
+<<widget "storeload">>
+	<<if _args[0] isnot undefined and $outfitTmp[_args[0]] isnot undefined and Object.keys($outfitTmp[_args[0]]).length gt 0>>
+		<<for $_slot range setup.clothingLayer.all>>
+			<<set $_item to $outfitTmp[_args[0]][$_slot]>>
+			<<if $_item is undefined or $worn[$_slot].name isnot $_item.name>>
+				<<generalStrip $_slot>>
+				<<returnCarried>>
+			<</if>>
+			<<if $_item isnot undefined>>
+				<<set $_stored to $store[$_slot].find(item => item.name is $_item.name)>>
+				<<if $_stored>>
+					<<set $worn[$_slot] to clone($_item)>>
+					<<set $worn[$_slot].location to 0>>
+					<<set $store[$_slot].deleteAt($store[$_slot].indexOf($_stored))>>
+				<</if>>
+			<</if>>
+		<</for>>
+		<<run delete V.outfitTmp[_args[0]]>>
+	<</if>>
+<</widget>>
+
+/* The "storeon..." widgets retrieve the clothing stored with the "...undress" widgets, that weren't put in a wardrobe. */
+/* Requires the same argument that was used to store the clothing in order to correctly identify. Optionally accepts a second argument. */
+/* Inputting "delete" will destroy the stored item, rather than wear it. */
+/* Inputting "check" will set _store_check to 1, for when you want to check whether or not an item exists in a given location. */
+/* Inputting "return" will return the item to the wardrobe */
 
 <<widget "storeon">>
 	<<set _equipSkip to {"over_upper":false, "over_lower":false, "upper":false, "lower":false, "under_upper":false, "under_lower":false, "over_head":false, "head":false, "face":false, "neck":false, "hands":false, "legs":false, "feet":false}>>
 	<<set _store_temp to _args[0]>>
 	<<set _store_option to _args[1] or 0>>
-	<<for $_slot range ["over_upper","over_lower","upper","lower","under_upper","under_lower","over_head","head","face","neck","hands","legs","feet"]>>
+	<<for $_slot range setup.clothingLayer.all>>
 		<<generalStoreon _store_temp $_slot _store_option>>
 	<</for>>
 <</widget>>
@@ -1162,7 +1225,7 @@
 	<<if $_item isnot undefined>>
 		<<set $_index to $store[$_slot].indexOf($_item)>>
 		<<if $worn[$_slot].cursed is 1>>
-		<<elseif _equipSkip[$_slot] is true>>
+		<<elseif _equipSkip isnot undefined and _equipSkip[$_slot] is true>>
 			<<if $_item.temp is undefined>>
 				<<set $_selectedWardrobe to $wardrobe>>
 				<<if $multipleWardrobes>>
@@ -1185,6 +1248,10 @@
 				<<set $store[$_slot].deleteAt($_index)>>
 			<<elseif _args[2] is "delete">>
 				<<set $store[$_slot].deleteAt($_index)>>
+			<<elseif _args[2] is "return">>
+				<<set $wardrobe[$_slot].push(clone($_item))>>
+				<<set $store[$_slot].deleteAt($_index)>>
+				<<run delete V.outfitTmp[_args[0]]>>
 			<<elseif _args[2] is "check">>
 				<<set _store_check to 1>>
 			<<else>>
@@ -1202,6 +1269,10 @@
 				<<set $store[$_slot].deleteAt($_index)>>
 			<</if>>
 		<</if>>
+	/* Strips and returns clothing items that are not replaced */
+	<<elseif $worn[$_slot].name isnot "naked" and !_args[2]>>
+		<<generalStrip $_slot>>
+		<<returnCarried>>
 	<</if>>
 <</if>>
 <</widget>>
@@ -1321,7 +1392,7 @@
 <<widget "generalWearFromWardrobe">>
 <<set _slot to _args[0]>>
 <<set _wearId to _args[1]>>
-<<set _slimePrevent to ["upper", "lower", "under_upper", "under_lower"]>>
+<<set _slimePrevent to setup.clothingLayer.torso_inner>>
 <<set $_selectedWardrobe to selectWardrobe()>>
 
 <<unset _cursedPrevent>><<unset _outfitPieceIds>><<unset _item>>
diff --git a/game/base-combat/struggle.twee b/game/base-combat/struggle.twee
index a51e5c0072..e091438a74 100644
--- a/game/base-combat/struggle.twee
+++ b/game/base-combat/struggle.twee
@@ -1799,7 +1799,7 @@ and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $com
 					<span class="green">dodging it.</span>
 				<<else>>
 					<span class="teal">narrowly dodging it.</span>
-					<<for $_slot range ["over_upper", "over_lower", "upper", "lower", "under_upper", "under_lower"]>>
+					<<for $_slot range setup.clothingLayer.torso>>
 						<<if $worn[$_slot].name isnot "naked">>
 							<<set $worn[$_slot].integrity -= random(10, 15)>>
 							<<set _clothesdamaged to true>>
diff --git a/game/base-debug/clothesTesting.twee b/game/base-debug/clothesTesting.twee
index 6bd7dacdc1..a8f56c98d0 100644
--- a/game/base-debug/clothesTesting.twee
+++ b/game/base-debug/clothesTesting.twee
@@ -352,7 +352,7 @@
 		<img @class="'colour-hair layer-'+($debugBodyState.birdWingsRightType is 'rightwing'? 'backhair' : 'tailPenisCover')+' anim-idle-2f'" @src="'img/transformations/bird/'+$debugBodyState.birdWingsRightType+'/'+$debugBodyState.birdWings+'.png'">
 	<</if>>
 
-	<<set _equip to ["upper", "lower", "under_upper", "under_lower","head", "face", "neck", "hands", "legs", "feet"]>>
+	<<set _equip to setup.clothingLayer.body>>
 	<<for _i to 0; _i lt _equip.length; _i++>>
 		<<if $debugClothesEquipped[_equip[_i]] isnot 0>>
 			<<set _item to setup.clothes[_equip[_i]][$debugClothesEquipped[_equip[_i]]]>>
@@ -418,7 +418,7 @@
 
 <<widget "clothesTestingGenerateClothes">>
 <<set _clothes to {}>>
-<<set _equip to ["upper", "lower", "under_upper", "under_lower","head", "face", "neck", "hands", "legs", "feet"]>>
+<<set _equip to setup.clothingLayer.body>>
 <<for _i to 0; _i lt _equip.length; _i++>>
 	<<set _clothes[_equip[_i]] to {}>>
 	<<set _keys to Object.keys(setup.clothes[_equip[_i]])>>
diff --git a/game/base-system/feats.twee b/game/base-system/feats.twee
index 31623dff9e..c3442d3ede 100644
--- a/game/base-system/feats.twee
+++ b/game/base-system/feats.twee
@@ -269,7 +269,7 @@
 		legs:[],
 		feet:[]
 	}>>
-	<<set _equip to ["head","face","neck","upper","lower","under_upper","under_lower", "hands","legs","feet"]>>
+	<<set _equip to setup.clothingLayer.body>>
 	<<for _i to 0; _i lt _equip.length; _i++>>
 		<<set _slot to _equip[_i]>>
 		<<for _j to 0; _j lt setup.clothes[_slot].length; _j++>>
diff --git a/game/base-system/time.twee b/game/base-system/time.twee
index 581e775cba..363612e210 100644
--- a/game/base-system/time.twee
+++ b/game/base-system/time.twee
@@ -649,6 +649,8 @@
 		<<set $swimmingattended to 0>>
 	<</if>>
 
+	<<schoolclothesreset>>
+
 	<<switch $month>>
 	<<case "january" "may" "september">>
 		<<if $weekday is 1 or $weekday is 2>>
diff --git a/game/overworld-forest/loc-lake/widgets.twee b/game/overworld-forest/loc-lake/widgets.twee
index 4b7cd250b2..a94f3ba2c9 100644
--- a/game/overworld-forest/loc-lake/widgets.twee
+++ b/game/overworld-forest/loc-lake/widgets.twee
@@ -531,17 +531,36 @@ A pair of eyes stares at you from between the trees, then vanishes.
 <</widget>>
 
 <<widget "lakeclothes">>
-<<if !$possessed>>
-	<<wearoutfit>>
-	<br>
-	Swimming sets:
-	<br>
-	<<listswimoutfits "lakeshore">>
-	<br>
-
-	<<storeactions "lakeshore">>
-	<<temperature>>
-<</if>>
+	<<if !$possessed>>
+		<<wardrobeSelection true>>
+		<<wearoutfit>>
+		<<set _store_location to "lakeshore">>
+		<<storeon _store_location "check">>
+		<<if _store_check is 1>>
+			<<set _clothes to clothingInStorage(_store_location)>>
+			<<if _clothes.length gt 0>>
+				<br>
+				<<if _clothes.length gt 2>>
+					Your clothes are lying on the ground behind a rock.
+					<br>
+				<<elseif _clothes.length is 2>>
+					Your _clothes[0].name and _clothes[1].name are lying on the ground behind a rock.
+					<br>
+				<<else>>
+					Your _clothes[0].name is lying on the ground behind a rock.
+					<br>
+				<</if>>
+				<<link [[Put on clothes|$passage]]>><<set $eventskip to 1>><<storeload _store_location>><</link>>
+				<br>
+			<</if>>
+		<</if>>
+		<br>
+		//Swimming sets://
+		<br>
+		<<listswimoutfits $wardrobe_location _store_location>>
+		<<temperature>>
+		<br>
+	<</if>>
 <</widget>>
 
 <<widget "destinationlakeruin">>
@@ -558,27 +577,4 @@ A pair of eyes stares at you from between the trees, then vanishes.
 		<<link [[Next|Lake Ruin Deep]]>><<endevent>><<set $eventskip to 1>><</link>>
 <</switch>>
 <br>
-<</widget>>
-
-<<widget "schoolpoolclothes">>
-<<set $wardrobe_location to _args[0]>>
-<<wardrobeSelection true>>
-<<wearoutfit>>
-<br>
-<<storeon "school pool" "check">>
-<<if _store_check is 1>>
-	<<link [[Get dressed|$passage]]>><<storeon "school pool">><</link>>
-<</if>>
-<br>
-Swimming sets:
-<br>
-<<listswimoutfits $wardrobe_location>>
-<br>
-Normal sets:
-<br>
-<<listoutfitsPassage $wardrobe_location>>
-<br>
-
-<<temperature>>
-<</widget>>
-
+<</widget>>
\ No newline at end of file
diff --git a/game/overworld-plains/loc-bird/widgets.twee b/game/overworld-plains/loc-bird/widgets.twee
index 02ae8598c1..36d44a9666 100644
--- a/game/overworld-plains/loc-bird/widgets.twee
+++ b/game/overworld-plains/loc-bird/widgets.twee
@@ -90,7 +90,7 @@
 <</widget>>
 
 <<widget "select_random_clothes">>/*Selects random clothes from shops. Sets _random_clothes to the item name, and _random_index to its index. Ignores forest shop, and secondary parts of outfits. _random_clothes outputs "piece of fabric" when clothes are ignored this way.*/
-<<set _random_slot to either("upper", "lower", "under_upper", "under_lower", "head", "face", "neck", "hands", "legs", "feet")>>
+<<set _random_slot to either(setup.clothingLayer.body)>>
 <<set _random_index to random(0, (setup.clothes[_random_slot].length - 1))>>
 <<if !setup.clothes[_random_slot][_random_index].shop.includes("forest") and setup.clothes[_random_slot][_random_index].shop.length gt 0 and !setup.clothes[_random_slot][_random_index].outfitSecondary and setup.clothes[_random_slot][_random_index].cursed isnot 1 and !setup.clothes[_random_slot][_random_index].type.includes("eerie") and !setup.clothes[_random_slot][_random_index].type.includes("naked")>>
 	<<set _random_clothes to setup.clothes[_random_slot][_random_index].name>>
diff --git a/game/overworld-town/loc-dance-studio/main.twee b/game/overworld-town/loc-dance-studio/main.twee
index 58cc52d32a..c586131da0 100644
--- a/game/overworld-town/loc-dance-studio/main.twee
+++ b/game/overworld-town/loc-dance-studio/main.twee
@@ -89,54 +89,12 @@ You are in the dance studio. Here you can pay for lessons to improve your dancin
 		<br><br>
 	<</if>>
 <</if>>
-
 :: Dance Studio Changing Room
 <<effects>>
-
-You are in the dance studio's changing room. Benches line the walls, with hooks for clothes hanging above.
+You are in the dance studio's changing room. Benches line the walls, with hooks for clothing hanging above.
 <br><br>
-
-<<storeon "dance_studio" "check">>
-<<if _store_check is 1>>
-	You left your clothes here.
-	<br>
-	<<link [[Wear|Dance Studio Changing Room]]>><<storeon "dance_studio">><</link>>
-	<br>
-<<else>>
-	You could strip down to a leotard or similar dance clothes here.
-	<br><br>
-
-	<<set _wearingDance to $worn.under_upper.type.includes("dance") and $worn.under_lower.type.includes("dance")>>
-	<<set _notNaked to ["over_upper","over_lower","upper","lower"].some(slot => $worn[slot].name isnot "naked")>>
-	<<if _wearingDance and _notNaked>>
-		<<link [[Strip down to your dance clothes|Dance Studio Change]]>><</link>>
-		<br>
-	<</if>>
-<</if>>
+<<dancingclothes>>
 <<link [[Leave|Dance Studio]]>><</link>>
-<br>
-
-:: Dance Studio Change
-<<effects>>
-
-<<set _slots to ["over_upper","over_lower","upper","lower"].filter(slot => $worn[slot].name isnot "naked" and ($worn[slot].one_piece isnot 1 or $worn[slot].outfitSecondary is undefined))>>
-<<set _arrayClothes to _slots.map(slot => $worn[slot].name)>>
-<!-- _arrayClothes and _slots have same length due to how .map works
-     _arrayClothes now has all our clothes names -->
-
-<<for _slot range _slots>>
-	<<generalUndress "dance_studio" _slot>>
-<</for>>
-
-<<set _them to ((_arrayClothes.length gt 1 or $worn[_slots[0]].word is "n") ? "them" : "it")>>
-<<set _hooks to (_arrayClothes.length gt 1 ? "the hooks" : "a hook")>>
-<<set _clothes to formatList(_arrayClothes)>>
-
-You remove your _clothes, and hang _them on _hooks.
-<br><br>
-
-<<link [[Next|Dance Studio Changing Room]]>><</link>>
-<br>
 
 :: Dance Studio Outside Exhibitionism
 <<effects>>
diff --git a/game/overworld-town/loc-dance-studio/widgets.twee b/game/overworld-town/loc-dance-studio/widgets.twee
new file mode 100644
index 0000000000..835240abc8
--- /dev/null
+++ b/game/overworld-town/loc-dance-studio/widgets.twee
@@ -0,0 +1,54 @@
+:: Widgets Dance Studio [widget]
+<<widget "dancingclothes">>
+	<<wearoutfit>>
+	<<set _store_location to "dance_studio">>
+	<<storeon _store_location "check">>
+	<<set _clothes to clothingInStorage(_store_location)>>
+	<<if $wearoutfittext isnot undefined>>
+		<<if $wearoutfittext is 1>>
+			<<set _slots to _clothes.filter(item => setup.clothingLayer.torso.includes(item.slot))>>
+			<<set _arrayClothes to _slots.map(slot => slot.name)>>
+			<<set _them to ((_arrayClothes.length gt 1 or _slots[0].word is "n") ? "them" : "it")>>
+			<<set _hooks to (_arrayClothes.length gt 1 ? "the hooks" : "a hook")>>
+			<<set _clothes to formatList(_arrayClothes)>>
+
+			<span class="purple">
+				You remove your _clothes, and hang _them on _hooks.
+			</span>
+		<<else>>
+			<span class="purple">
+				You put your clothes on.
+			</span>
+		<</if>>
+		<<unset $wearoutfittext>>
+	<</if>>
+	<<if _store_check is 1>>
+		<<if _clothes.length gt 0>>
+			<<if _clothes.length gt 2>>
+				Your clothes are hanging on the hooks on the wall.
+				<br>
+			<<elseif _clothes.length is 2>>
+				Your _clothes[0].name and _clothes[1].name are hanging on the hooks on the wall.
+				<br>
+			<<else>>
+				Your _clothes[0].name is hanging on one of the hooks.
+				<br>
+			<</if>>
+			<<link [[Change to your clothes|$passage]]>><<set $eventskip to 1>><<set $wearoutfittext to 2>><<storeload _store_location>><</link>>
+		<</if>>
+	<<else>>
+		You could equip a leotard or similar dance clothes here.
+	<</if>>
+	<br>
+	<br>
+	<<if $wardrobe["under_upper"].filter(a => a.type.includes("dance")) lte 0>>
+		//You currently have no dancing clothes.//
+	<<else>>
+		//Dancing clothes://
+		<br>
+		<<listdancingclothes _store_location>>
+		<<temperature>>
+	<</if>>
+	<br>
+	<br>
+<</widget>>
\ No newline at end of file
diff --git a/game/overworld-town/loc-school/changing-rooms.twee b/game/overworld-town/loc-school/changing-rooms.twee
index 235ddd8e50..90a184905b 100755
--- a/game/overworld-town/loc-school/changing-rooms.twee
+++ b/game/overworld-town/loc-school/changing-rooms.twee
@@ -1,5 +1,7 @@
 :: School Boy Changing Room
-<<set $outside to 0>><<set $location to "pool">><<set $bus to "boys">><<schooleffects>><<effects>>
+<<set $outside to 0>><<set $location to "pool">><<set $bus to "boys">>
+<<set $wardrobe_location to "schoolBoys">>
+<<set _store_location to "school pool boys">>
 
 You are in the boys' changing room.
 <<if $arousal gte $arousalmax>>
@@ -37,7 +39,7 @@ You are in the boys' changing room.
 			<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<</if>>
 		<br>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $exposed gte 2 and $malechance isnot 0>>
@@ -118,7 +120,7 @@ You are in the boys' changing room.
 			<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<</if>>
 		<br>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $exposed gte 2 and $malechance isnot 0>>
@@ -197,7 +199,7 @@ You are in the boys' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<boy_lockers>>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $player.gender is "f">>
@@ -222,7 +224,7 @@ You are in the boys' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<boy_lockers>>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $poolroomstate is "other">><!-- $changingroomstate is "empty" -->
@@ -247,7 +249,7 @@ You are in the boys' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<boy_lockers>>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $player.gender is "f">>
@@ -272,7 +274,7 @@ You are in the boys' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<boy_lockers>>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<</if>>
 <<else>><!-- $poolroomstate is "empty" and $changingroomstate is "empty" -->
@@ -283,7 +285,7 @@ You are in the boys' changing room.
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 		<br>
 	<<else>>
@@ -293,7 +295,7 @@ You are in the boys' changing room.
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
-		<<schoolpoolclothes "schoolBoys">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Boy Wardrobe]]>><</link>>
 		<br>
 	<</if>>
@@ -301,7 +303,9 @@ You are in the boys' changing room.
 
 :: School Girl Changing Room
 
-<<set $outside to 0>><<set $location to "pool">><<set $bus to "girls">><<schooleffects>><<effects>>
+<<set $outside to 0>><<set $location to "pool">><<set $bus to "girls">>
+<<set $wardrobe_location to "schoolGirls">>
+<<set _store_location to "school pool girls">>
 
 <<if $hour is 15 and $time lte ($hour * 60 + 4) and $schoolday is 1>>
 	<<set $schoolstate to "fifth">><<set $schoollesson to 1>>
@@ -388,7 +392,7 @@ You are in the girls' changing room.
 			<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<</if>>
 		<br>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $changingroomstate is "other">>
@@ -471,7 +475,7 @@ You are in the girls' changing room.
 			<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<</if>>
 		<br>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $poolroomstate is "own">><!-- $changingroomstate is "empty" -->
@@ -499,7 +503,7 @@ You are in the girls' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<girl_lockers>>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<br><br>
@@ -529,7 +533,7 @@ You are in the girls' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<girl_lockers>>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $poolroomstate is "other">><!-- $changingroomstate is "empty" -->
@@ -557,7 +561,7 @@ You are in the girls' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<girl_lockers>>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<br><br>
@@ -579,7 +583,7 @@ You are in the girls' changing room.
 		<br>
 		<<school_pool_swap>>
 		<<girl_lockers>>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<else>><!-- $poolroomstate is "empty" and $changingroomstate is "empty" -->
@@ -590,7 +594,7 @@ You are in the girls' changing room.
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 		<br>
 	<<else>>
@@ -600,7 +604,7 @@ You are in the girls' changing room.
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
-		<<schoolpoolclothes "schoolGirls">>
+		<<schoolpoolclothes _store_location>>
 		<<link [[Locker|School Girl Wardrobe]]>><</link>>
 		<br>
 	<</if>>
diff --git a/game/overworld-town/loc-school/classes/swimming.twee b/game/overworld-town/loc-school/classes/swimming.twee
index d70468ea7c..94f5900b78 100644
--- a/game/overworld-town/loc-school/classes/swimming.twee
+++ b/game/overworld-town/loc-school/classes/swimming.twee
@@ -98,7 +98,7 @@
 			<br><br>
 			<<He>> glares at you. "So, thanks to a certain someone, I'm not allowed to let you in the pool unless you're all nude."
 			<br><br>
-			<<link [[Swim naked|Swimming Lesson]]>><<undress "school pool">><<endevent>><</link>>
+			<<link [[Swim naked|Swimming Lesson]]>><<schoolpoolundress>><<endevent>><</link>>
 		<</if>>
 	<<elseif ($worn.under_lower.type.includes("swim") or $worn.lower.type.includes("swim"))
 	and ($worn.under_upper.type.includes("swim") or $worn.upper.type.includes("swim") or ($worn.under_upper.type.includes("naked") and $worn.upper.type.includes("naked") and ($player.gender_appearance is "m" or $swimCrossdressPermission is true)))
@@ -240,7 +240,7 @@
 <</if>>
 
 :: School Pool Ask Naked
-<<set $outside to 0>><<set $location to "pool">><<schooleffects>><<effects>><<undress "school pool">><<exposure>>
+<<set $outside to 0>><<set $location to "pool">><<schoolpoolundress>><<schooleffects>><<effects>><<exposure>>
 
 <<if $swimnudecounter lte 1>>
 	<<npc Mason>>
@@ -489,7 +489,7 @@ You speak in a low voice, so only the teacher will hear you.
 	No one will be able to see anything once you're in."
 	<br><br>
 
-	<<link [[Accept|School Pool Nude]]>><<undress "school pool">><<endevent>><<exposure>><</link>>
+	<<link [[Accept|School Pool Nude]]>><<schoolpoolundress>><<endevent>><<exposure>><</link>>
 	<br>
 	<<link [[Refuse (0:05)|School Pool Refuse]]>><<pass 5>><<detention 6>><<endevent>><</link>><<gdelinquency>>
 <<elseif $rng gte 41>>
@@ -501,7 +501,7 @@ You speak in a low voice, so only the teacher will hear you.
 		You unfurl the fabric to reveal a rather tattered swimsuit.
 		<br><br>
 
-		<<link [[Get changed|School Pool Crossdress]]>><<undress "school pool">><<spareschoolswimsuit>><<endevent>><<exposure>><<set $phase to 1>><</link>>
+		<<link [[Get changed|School Pool Crossdress]]>><<schoolpoolundress>><<spareschoolswimsuit>><<endevent>><<exposure>><<set $phase to 1>><</link>>
 	<<else>>
 		<<He>> produces a bundle of fabric and passes it to you.
 		<br><br>
@@ -511,7 +511,7 @@ You speak in a low voice, so only the teacher will hear you.
 		You unfurl the fabric to reveal a rather tattered pair of swim shorts.
 		<br><br>
 
-		<<link [[Get changed|School Pool Crossdress]]>><<undress "school pool">><<spareschoolswimshorts>><<endevent>><<exposure>><<set $phase to 0>><</link>>
+		<<link [[Get changed|School Pool Crossdress]]>><<schoolpoolundress>><<spareschoolswimshorts>><<endevent>><<exposure>><<set $phase to 0>><</link>>
 		<!-- A crossdressing girl may now have her assets on display, "School Pool Crossdress" will handle that -->
 	<</if>>
 <<elseif $rng gte 1>>
@@ -525,7 +525,7 @@ You speak in a low voice, so only the teacher will hear you.
 		It's the shorts or nothing.
 		<br><br>
 
-		<<link [[Wear the shorts|School Pool Crossdress]]>><<undress "school pool">><<spareschoolswimshorts>><<endevent>><<exposure>><<set $phase to 0>><</link>>
+		<<link [[Wear the shorts|School Pool Crossdress]]>><<schoolpoolundress>><<spareschoolswimshorts>><<endevent>><<exposure>><<set $phase to 0>><</link>>
 		<br>
 		<<link [[Skip the lesson (0:05)|School Pool Refuse]]>><<pass 5>><<detention 6>><<endevent>><</link>><<gdelinquency>>
 	<<else>>
@@ -538,7 +538,7 @@ You speak in a low voice, so only the teacher will hear you.
 		It's the swimsuit or nothing.
 		<br><br>
 
-		<<link [[Wear the swimsuit|School Pool Crossdress]]>><<undress "school pool">><<spareschoolswimsuit>><<endevent>><<exposure>><<set $phase to 1>><</link>>
+		<<link [[Wear the swimsuit|School Pool Crossdress]]>><<schoolpoolundress>><<spareschoolswimsuit>><<endevent>><<exposure>><<set $phase to 1>><</link>>
 		<br>
 		<<link [[Skip the lesson (0:05)|School Pool Refuse]]>><<pass 5>><<detention 6>><<endevent>><</link>><<gdelinquency>>
 	<</if>>
diff --git a/game/overworld-town/loc-school/main.twee b/game/overworld-town/loc-school/main.twee
index 5011f77bf5..f04e47b78f 100644
--- a/game/overworld-town/loc-school/main.twee
+++ b/game/overworld-town/loc-school/main.twee
@@ -71,16 +71,16 @@
 		<<playgroundicon>><<link [[Rear playground (0:02)|School Rear Playground]]>><<pass 2>><</link>>
 		<br><br>
 		<<if $schoolstate is "afternoon" and $detention gte 1 and $detentionattended isnot 1 and $headnodetention isnot 1 and $pillory_tenant.special.name isnot "Leighton">>
-			<<link [[Leave the school|School Leave Stop]]>><</link>>
+			<<link [[Leave the school|School Leave Stop]]>><<schoolclothesreset>><</link>>
 			<br>
 		<<elseif $schoolstate is "afternoon" and $bullytimer gte 1 and $bullytimeroutside gte 1 and $bullygate is 0 and $NPCName[$NPCNameList.indexOf("Whitney")].init is 1 and $NPCName[$NPCNameList.indexOf("Whitney")].state isnot "dungeon" and $pillory_tenant.special.name isnot "Whitney">>
-			<<link [[Leave the school|School Leave Whitney]]>><</link>>
+			<<link [[Leave the school|School Leave Whitney]]>><<schoolclothesreset>><</link>>
 			<br>
 		<<elseif $schoolday is 1 and $hour gte 7 and $hour lte 16>>
-			<<ind>><<link [[Leave the school (0:01)|Oxford Street]]>><<pass 1>><</link>>
+			<<ind>><<link [[Leave the school (0:01)|Oxford Street]]>><<schoolclothesreset>><<pass 1>><</link>>
 			<br>
 		<<else>>
-			<<ind>><<link [[Leave the school|School Gate Exit]]>><</link>>
+			<<ind>><<link [[Leave the school|School Gate Exit]]>><<schoolclothesreset>><</link>>
 			<br>
 		<</if>>
 	<</if>>
diff --git a/game/overworld-town/loc-school/widgets.twee b/game/overworld-town/loc-school/widgets.twee
index 303cb55c49..91abe51d88 100644
--- a/game/overworld-town/loc-school/widgets.twee
+++ b/game/overworld-town/loc-school/widgets.twee
@@ -36,6 +36,12 @@
 		<</if>>
 	<</if>>
 
+	<<if $schoolpoolundress isnot undefined>>
+		<span class="yellow">Your clothes were moved to the <<print $schoolpoolundress is "wardrobe" ? "wardrobe" : $schoolpoolundress + " changing room">>.</span>
+		<br>
+		<<unset $schoolpoolundress>>
+	<</if>>
+
 	<!-- pool room itself is in use during $schoolstate only -->
 	<<if $schoolstate is "fifth">>
 		<<set $poolroomstate to "own">>
@@ -2586,6 +2592,82 @@
 <</if>>
 <</widget>>
 
+<<widget "schoolpoolclothes">>
+	<<storereturn _args[0]>>
+	<<wardrobeSelection true>>
+	<<silently>><<wearoutfit>><</silently>>
+	<<schooleffects>><<effects>>
+	<<if $wearoutfittext isnot undefined>>
+		<span class="purple">
+		<<switch $wearoutfittext>>
+			<<case 1>>
+				You gather your clothes from the bench and carefully put them on.
+			<<case 2>>
+				You put away the clothes into your locker.
+			<<default>>
+				You change into your <<print $wearoutfittext.toLowerCase()>>.
+		<</switch>>
+		</span>
+		<<unset $wearoutfittext>>
+	<</if>>
+
+	<<storeon _args[0] "check">>
+	<<if _store_check is 1>>
+		<<set _clothes to clothingInStorage(_args[0])>>
+		<<if _clothes.length gt 0>>
+			<br>
+			<<if _clothes.length gt 2>>
+				Your clothes are gathered in a neat pile next to the lockers.
+				<br>
+			<<elseif _clothes.length is 2>>
+				Your _clothes[0] and _clothes[1] are lying on the bench next to the lockers.
+				<br>
+			<<else>>
+				Your _clothes[0] is lying on the bench next to the lockers.
+				<br>
+			<</if>>
+			<<link [[Put on|$passage]]>><<storeload _args[0]>><<set $eventskip to 1>><<set $wearoutfittext to 1>><</link>>
+			<br>
+			<<link [[Put away|$passage]]>><<storeon _args[0] "return">><<set $eventskip to 1>><<set $wearoutfittext to 2>><</link>>
+			<br>
+		<</if>>
+	<</if>>
+	<br>
+	//Swimming sets://
+	<br>
+	<<listswimoutfits $wardrobe_location _args[0]>>
+	<br>
+	//Normal sets://
+	<br>
+	<<listoutfitsPassage $wardrobe_location _args[0]>>
+	<br>
+	<<temperature>>
+<</widget>>
+
+<<widget "schoolpoolundress">>
+	<<set _store_location to "school pool">>
+	<<if $player.gender_appearance is "m">>
+		<<set _store_location += " boys">>
+		<<set $schoolpoolundress to "boys">>
+	<<else>>
+		<<set _store_location += " girls">>
+		<<set $schoolpoolundress to "girls">>
+	<</if>>
+	<<if clothingInStorage(_store_location).length is 0>>
+		<<storesave _store_location>>
+	<<else>>
+		<<strip>>
+		<<returnCarried>>
+		<<set $schoolpoolundress to "wardrobe">>
+	<</if>>
+<</widget>>
+
+<<widget "schoolclothesreset">>
+	<<storeon "schoolBoys" "return">>
+	<<storeon "schoolGirls" "return">>
+	<<set $outfitTmp to {}>>
+<</widget>>
+
 <<widget "school_infirmary_options">>
 	<<if $passage isnot "School Infirmary Ask Painkiller">>
 		<<link [[Ask for a painkiller|School Infirmary Ask Painkiller]]>><</link>>
diff --git a/game/overworld-town/loc-shop/clothing-v2.twee b/game/overworld-town/loc-shop/clothing-v2.twee
index 8db1ffc2b9..9cddd269f5 100644
--- a/game/overworld-town/loc-shop/clothing-v2.twee
+++ b/game/overworld-town/loc-shop/clothing-v2.twee
@@ -486,7 +486,7 @@
 		<<warmth _truewarmth>>
 		<br><br>
 		<<shoptraits>>
-		<<set _slimeSlots to ["over_upper","over_lower","upper","lower","under_upper","under_lower"]>>
+		<<set _slimeSlots to setup.clothingLayer.torso>>
 		<<if !_slimeSlots.includes($clothingShopSlot) or currentSkillValue('willpower') gte 800 or _temp_choice.reveal gte 500 or _temp_choice.type.includesAny("school", "event") or $corruption_slime lt 80>>
 			<div class="clothing-colours-div">
 				<<set _hiddenMannequin = $images is 1 ? "" : "hidden">>
diff --git a/game/overworld-town/loc-shop/tailor.twee b/game/overworld-town/loc-shop/tailor.twee
index 48d7ee62eb..34b62308ba 100644
--- a/game/overworld-town/loc-shop/tailor.twee
+++ b/game/overworld-town/loc-shop/tailor.twee
@@ -123,7 +123,7 @@ You are in the tailor shop. It has cloth of various colours hanging on racks.
 
 Your clothes have been fixed.
 <br><br>
-<<set _equip to ["over_upper","over_lower","upper", "lower", "under_upper", "under_lower","over_head","head", "face", "neck", "hands", "legs", "feet"]>>
+<<set _equip to setup.clothingLayer.all>>
 <<for _i to 0; _i lt _equip.length; _i++>>
 	<<set $worn[_equip[_i]].integrity = clothingData(_equip[_i],$worn[_equip[_i]],'integrity_max')>>
 <</for>>
diff --git a/game/overworld-town/loc-shop/tryOn.twee b/game/overworld-town/loc-shop/tryOn.twee
index cd3c29567e..49dc9d506f 100644
--- a/game/overworld-town/loc-shop/tryOn.twee
+++ b/game/overworld-town/loc-shop/tryOn.twee
@@ -66,12 +66,12 @@
 	<<link "Re-equip Upper Clothes">><<ShowUnderEquip "normal">><<updatesidebarimg>><<updatetryonstats>><<numberify "#passages > .passage">><</link>>
 	<br><br>
 <</if>>
-<<set _slots to ["over_upper","over_lower","upper", "lower", "under_upper", "under_lower","over_head","head", "face", "neck", "hands", "legs", "feet"]>>
+<<set _slots to setup.clothingLayer.all>>
 <<if _slots.map(x => $tryOn.tryingOn[x]).some(x => x != null)>>
 	Clothes you are trying on total to <<printmoney $tryOn.value>>. This includes:
 	<br>
 	<<if $passage is "Clothing Shop" or $passage is "School Library Shop" or $passage is "Forest Shop">>
-		<<set _slots to ["over_upper","over_lower","upper", "lower", "under_upper", "under_lower","over_head","head", "face", "neck", "hands", "legs", "feet"]>>
+		<<set _slots to setup.clothingLayer.all>>
 		<ul>
 		<<for _tryon range _slots.map(x => [x, $tryOn.tryingOn[x]]).filter(x => x[1] != null && x[1].outfitSecondary is undefined)>>
 			<li>
@@ -107,8 +107,8 @@
 <<if _args[0]>>
 	<<ShowUnderEquip "normal">>
 	<<ShowUnderEquip "over">>
-	<<set _equip to ["over_upper","over_lower","upper", "lower", "under_upper", "under_lower","over_head","head", "face", "neck", "hands", "legs", "feet"]>>
-	<<set _itemTypes to ["face","feet","head", "hands","legs","upper","lower","neck","under_upper","under_lower"]>>
+	<<set _equip to setup.clothingLayer.all>>
+	<<set _itemTypes to setup.clothingLayer.body>>
 	<<set _towels to ["towel top","large towel","towel skirt"]>>
 	<<set $money -= $tryOn.value>>
 	<<switch _args[0]>>
@@ -166,7 +166,7 @@
 		<<clothingResetOwnedReset _resetSlot>>
 	<</if>>
 <<else>>
-	<<set _equip to ["over_upper","over_lower","upper", "lower", "under_upper", "under_lower","over_head","head", "face", "neck", "hands", "legs", "feet"]>>
+	<<set _equip to setup.clothingLayer.all>>
 	<<for _i to 0; _i lt _equip.length; _i++>>
 		<<if $tryOn.ownedStored[_equip[_i]] isnot null>>
 			<<set $worn[_equip[_i]] to clone($tryOn.ownedStored[_equip[_i]])>>
@@ -389,7 +389,7 @@
 
 <<widget "ShowUnderEquip">>
 <<if _args[0] is "over">>
-	<<set _slots to ["over_head", "over_upper", "over_lower"]>>
+	<<set _slots to setup.clothingLayer.over>>
 	<<set _type to "showEquip">>
 <<else>>
 	<<set _slots to ["upper", "lower"]>>
diff --git a/game/overworld-town/loc-shop/widgets.twee b/game/overworld-town/loc-shop/widgets.twee
index 951c097faa..a0222a0ca5 100644
--- a/game/overworld-town/loc-shop/widgets.twee
+++ b/game/overworld-town/loc-shop/widgets.twee
@@ -117,7 +117,7 @@ Forth argument - item index*/
 	<<warmth _temp_choice.warmth>>
 	<br><br>
 	<<shoptraits>>
-	<<set _slimeSlots to ["over_upper","over_lower","upper","lower","under_upper","under_lower"]>>
+	<<set _slimeSlots to setup.clothingLayer.torso>>
 	<<if !_slimeSlots.includes($clothingShopSlot) or currentSkillValue('willpower') gte 800 or _temp_choice.reveal gte 500 or _temp_choice.type.includesAny("school", "event") or $corruption_slime lt 80>>
 		<<if _temp_choice.colour_options.length gt 1>>
 			<<run _temp_choice.colour_options.pushUnique("random")>>
diff --git a/modules/02-array-extensions.js b/modules/02-array-extensions.js
index 58cab0ba9e..c297cbcd2c 100644
--- a/modules/02-array-extensions.js
+++ b/modules/02-array-extensions.js
@@ -39,7 +39,32 @@ Object.defineProperty(Array.prototype, "select", {
 	},
 });
 
-Object.defineProperty(Array.prototype, "formatList", {
+/* Returns copy of array minus the values in arguments. */
+Object.defineProperty(Array.prototype, 'except', {
+	configurable : true,
+	writable     : true,
+
+	value() {
+		if (this == null) {
+			throw new TypeError('Array.prototype.except called on null or undefined');
+		}
+		if (arguments.length === 0) {
+			return this;
+		}
+
+		const needles = Array.prototype.concat.apply([], arguments);
+
+		return this.filter(obj => {
+			for(n of needles) {
+				if(obj === n)
+					return false;
+			}
+			return true;
+		});
+	}
+});
+
+Object.defineProperty(Array.prototype, 'formatList', {
 	configurable: true,
 	writable: true,
 	value(options) {
-- 
GitLab


From 3a66e779b465b3833c58a0a7d2021dbdd1825ff8 Mon Sep 17 00:00:00 2001
From: xao <33469-xao321@users.noreply.gitgud.io>
Date: Sun, 21 Aug 2022 21:07:18 +0000
Subject: [PATCH 04/50] Sprite fixes for darker skin

---
 game/base-combat/close-images.twee             |   6 +++---
 game/base-combat/doggy-images.twee             |   2 +-
 game/base-combat/missionary-images.twee        |   8 ++++----
 img/sex/close/chest/0.png                      | Bin 346 -> 1970 bytes
 img/sex/close/chest/1.png                      | Bin 357 -> 1980 bytes
 img/sex/close/chest/10.png                     | Bin 382 -> 2007 bytes
 img/sex/close/chest/11.png                     | Bin 377 -> 1992 bytes
 img/sex/close/chest/12.png                     | Bin 376 -> 1994 bytes
 img/sex/close/chest/2.png                      | Bin 365 -> 1988 bytes
 img/sex/close/chest/3.png                      | Bin 374 -> 1994 bytes
 img/sex/close/chest/4.png                      | Bin 374 -> 2012 bytes
 img/sex/close/chest/5.png                      | Bin 391 -> 2014 bytes
 img/sex/close/chest/6.png                      | Bin 383 -> 2015 bytes
 img/sex/close/chest/7.png                      | Bin 380 -> 2004 bytes
 img/sex/close/chest/8.png                      | Bin 383 -> 2001 bytes
 img/sex/close/chest/9.png                      | Bin 379 -> 1997 bytes
 img/sex/close/missionary/anuspenetrated.png    | Bin 683 -> 931 bytes
 img/sex/closeRed/chest/0.png                   | Bin 346 -> 429 bytes
 img/sex/closeRed/chest/0_job.png               | Bin 514 -> 657 bytes
 img/sex/closeRed/chest/0_job_nip.png           | Bin 153 -> 197 bytes
 img/sex/closeRed/chest/0_nip.png               | Bin 109 -> 139 bytes
 img/sex/closeRed/chest/1.png                   | Bin 357 -> 439 bytes
 img/sex/closeRed/chest/10.png                  | Bin 382 -> 469 bytes
 img/sex/closeRed/chest/10_job.png              | Bin 509 -> 674 bytes
 img/sex/closeRed/chest/10_job_nip.png          | Bin 195 -> 250 bytes
 img/sex/closeRed/chest/10_nip.png              | Bin 154 -> 187 bytes
 img/sex/closeRed/chest/11.png                  | Bin 377 -> 451 bytes
 img/sex/closeRed/chest/11_job.png              | Bin 555 -> 696 bytes
 img/sex/closeRed/chest/11_job_nip.png          | Bin 217 -> 271 bytes
 img/sex/closeRed/chest/11_nip.png              | Bin 156 -> 190 bytes
 img/sex/closeRed/chest/12.png                  | Bin 376 -> 453 bytes
 img/sex/closeRed/chest/12_job.png              | Bin 545 -> 702 bytes
 img/sex/closeRed/chest/12_job_nip.png          | Bin 218 -> 280 bytes
 img/sex/closeRed/chest/12_nip.png              | Bin 156 -> 190 bytes
 img/sex/closeRed/chest/1_job.png               | Bin 543 -> 687 bytes
 img/sex/closeRed/chest/1_job_nip.png           | Bin 154 -> 207 bytes
 img/sex/closeRed/chest/1_nip.png               | Bin 118 -> 151 bytes
 img/sex/closeRed/chest/2.png                   | Bin 365 -> 447 bytes
 img/sex/closeRed/chest/2_job.png               | Bin 341 -> 427 bytes
 img/sex/closeRed/chest/2_job_nip.png           | Bin 157 -> 208 bytes
 img/sex/closeRed/chest/2_nip.png               | Bin 119 -> 150 bytes
 img/sex/closeRed/chest/3.png                   | Bin 374 -> 453 bytes
 img/sex/closeRed/chest/3_job.png               | Bin 341 -> 436 bytes
 img/sex/closeRed/chest/3_job_nip.png           | Bin 158 -> 208 bytes
 img/sex/closeRed/chest/3_nip.png               | Bin 118 -> 152 bytes
 img/sex/closeRed/chest/4.png                   | Bin 374 -> 471 bytes
 img/sex/closeRed/chest/4_job.png               | Bin 357 -> 456 bytes
 img/sex/closeRed/chest/4_job_nip.png           | Bin 164 -> 215 bytes
 img/sex/closeRed/chest/4_nip.png               | Bin 120 -> 155 bytes
 img/sex/closeRed/chest/5.png                   | Bin 391 -> 473 bytes
 img/sex/closeRed/chest/5_job.png               | Bin 377 -> 487 bytes
 img/sex/closeRed/chest/5_job_nip.png           | Bin 166 -> 224 bytes
 img/sex/closeRed/chest/5_nip.png               | Bin 117 -> 155 bytes
 img/sex/closeRed/chest/6.png                   | Bin 383 -> 475 bytes
 img/sex/closeRed/chest/6_job.png               | Bin 416 -> 548 bytes
 img/sex/closeRed/chest/6_job_nip.png           | Bin 195 -> 252 bytes
 img/sex/closeRed/chest/6_nip.png               | Bin 119 -> 155 bytes
 img/sex/closeRed/chest/7.png                   | Bin 380 -> 463 bytes
 img/sex/closeRed/chest/7_job.png               | Bin 442 -> 575 bytes
 img/sex/closeRed/chest/7_job_nip.png           | Bin 191 -> 252 bytes
 img/sex/closeRed/chest/7_nip.png               | Bin 120 -> 154 bytes
 img/sex/closeRed/chest/8.png                   | Bin 383 -> 460 bytes
 img/sex/closeRed/chest/8_job.png               | Bin 483 -> 633 bytes
 img/sex/closeRed/chest/8_job_nip.png           | Bin 198 -> 261 bytes
 img/sex/closeRed/chest/8_nip.png               | Bin 119 -> 155 bytes
 img/sex/closeRed/chest/9.png                   | Bin 379 -> 458 bytes
 img/sex/closeRed/chest/9_job.png               | Bin 599 -> 768 bytes
 img/sex/closeRed/chest/9_job_nip.png           | Bin 205 -> 271 bytes
 img/sex/closeRed/chest/9_nip.png               | Bin 119 -> 154 bytes
 img/sex/closeRed/chest/base.png                | Bin 514 -> 657 bytes
 img/sex/closeRed/chest/chest_job_big.png       | Bin 690 -> 904 bytes
 img/sex/closeRed/chest/chest_job_big_nip.png   | Bin 161 -> 216 bytes
 img/sex/closeRed/doggy/anus.png                | Bin 601 -> 861 bytes
 img/sex/closeRed/doggy/anuspenetrate.png       | Bin 648 -> 945 bytes
 img/sex/closeRed/missionary/anus.png           | Bin 601 -> 861 bytes
 img/sex/closeRed/missionary/anuspenetrate.png  | Bin 648 -> 945 bytes
 .../doggyRed/active/body/doggyactivemouth.png  | Bin 0 -> 473 bytes
 .../missionaryRed/active/body/activemouth.png  | Bin 0 -> 520 bytes
 78 files changed, 8 insertions(+), 8 deletions(-)
 create mode 100644 img/sex/doggyRed/active/body/doggyactivemouth.png
 create mode 100644 img/sex/missionaryRed/active/body/activemouth.png

diff --git a/game/base-combat/close-images.twee b/game/base-combat/close-images.twee
index bc83c21a20..d285e9af8e 100644
--- a/game/base-combat/close-images.twee
+++ b/game/base-combat/close-images.twee
@@ -308,12 +308,12 @@
     <<if $chestuse is "penis" or $chestuse is "tentacle">>
         <<if $player.breastsize gte 8>>
             <img @src="_img.chest+'chest_job_big.png'" @class="'anim-close-10f-'+_animspeed" @style="'filter: ' + _filters.body">
-            <img id="closechestnip" @src="_img.chest+'chest_job_big_nip.png'" @class="'anim-close-10f-'+_animspeed">
+            <img id="closechestnip" @src="_img.chest+'chest_job_big_nip.png'" @class="'anim-close-10f-'+_animspeed" @style="'filter: ' + _filters.body">
             <img id="closechestpenis" @src="_img.chest+'chest_job_big_penis.png'" @class="'anim-close-10f-'+_animspeed">
         <<else>>
             <img @src="_img.chest+'base.png'" @class="'anim-close-6f-'+_animspeed" @style="'filter: ' + _filters.body">
             <img id="closechestbreasts" @src="_img.chest+$player.breastsize+'_job.png'" @class="'anim-close-6f-'+_animspeed" @style="'filter: ' + _filters.body">
-            <img id="closechestnip" @src="_img.chest+$player.breastsize+'_job_nip.png'" @class="'anim-close-6f-'+_animspeed">
+            <img id="closechestnip" @src="_img.chest+$player.breastsize+'_job_nip.png'" @class="'anim-close-6f-'+_animspeed" @style="'filter: ' + _filters.body">
             <<if $chestuse is "penis" and $enemytype is "beast">>
                 <img id="closechestpenis" @src="_img.chest+'beast.png'" @class="'anim-close-6f-'+_animspeed">
             <<elseif $chestuse is "penis">>
@@ -324,7 +324,7 @@
         <</if>>
     <<elseif ($worn.upper.exposed gte 2 or $upperwetstage gte 3) and ($worn.under_upper.exposed gte 1 or $underupperwetstage gte 3)>>
         <img @src="_img.chest+$player.breastsize+'.png'" @style="'filter: ' + _filters.body">
-        <img id="closechestpenis" @src="_img.chest+$player.breastsize+'_nip.png'">
+        <img id="closechestpenis" @src="_img.chest+$player.breastsize+'_nip.png'" @style="'filter: ' + _filters.body">
     <</if>>
     </div>
 
diff --git a/game/base-combat/doggy-images.twee b/game/base-combat/doggy-images.twee
index 74730cb8a0..c501d587e3 100644
--- a/game/base-combat/doggy-images.twee
+++ b/game/base-combat/doggy-images.twee
@@ -682,7 +682,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 <img @class="'layer-sexblush colour-hair anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/hair/doggyactiveoverlay.png">
 
 <img @class="'layer-sexbase anim-doggy-4f-'+_animspeed" @src="_img.doggyactivebase" @style="'filter: '+_filters.body">
-<img @class="'layer-sexmouth anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactivemouth.png">
+<img @class="'layer-sexmouth anim-doggy-4f-'+_animspeed" @src="_img.doggyactivemouth" @style="'filter: '+_filters.body">
 
 <<if $feetuse is "penis">>
 	<<if $enemytype isnot "beast">>
diff --git a/game/base-combat/missionary-images.twee b/game/base-combat/missionary-images.twee
index 4161b0b129..f6a1b2cc08 100644
--- a/game/base-combat/missionary-images.twee
+++ b/game/base-combat/missionary-images.twee
@@ -207,7 +207,7 @@ Previous "Always Open" mouth. activemouth can be used in all active frames still
 <img class="layer-sexmouth" @src="_img.activeclosedmouth" @style="'filter: '+_filters.body">
 
 <<if $rightarm isnot "bound" and $rightarm isnot "grappled" and $rightarm isnot "behind">>
-	<img class="layer-sexaboveclothes anim-idle-2f" @src="_img.activebaserightarm" @style="'filter: '+_filters.body">
+	<img class="layer-frontforeground anim-idle-2f" @src="_img.activebaserightarm" @style="'filter: '+_filters.body">
 <<else>>
 	<img class="layer-sexarmsbound anim-idle-2f" @src="_img.activearmsbound" @style="'filter: '+_filters.body">
 <</if>>
@@ -524,7 +524,7 @@ Same as above, but with eyelashes.
 <img @class="'layer-sexblush colour-hair anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/hair/activeoverlay.png">
 
 <img @class="'layer-sexbase anim-doggy-4f-'+_animspeed" @src="_img.activebase" @style="'filter: '+_filters.body">
-<img @class="'layer-sexmouth anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activemouth.png">
+<img @class="'layer-sexmouth anim-doggy-4f-'+_animspeed" @src="_img.activemouth" @style="'filter: '+_filters.body">
 
 <img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activebaselegl" @style="'filter: '+_filters.body">
 <<if $feetuse is "penis">>
@@ -574,7 +574,7 @@ Same as above, but with eyelashes.
 <<elseif $enemytype is "beast" and $monster isnot 1 and _stanceCheck is "top" and $NPCList[0].type isnot "hawk">>
 	<img @class="'layer-sexaboveclothes anim-doggy-4f-'+_animspeed" @src="_img.activebaserightarmstroke" @style="'filter: '+_filters.body">
 <<else>>
-	<img @class="'layer-sexaboveclothes anim-doggy-4f-'+_animspeed" @src="_img.activebaserightarm" @style="'filter: '+_filters.body">
+	<img @class="'layer-frontforeground anim-doggy-4f-'+_animspeed" @src="_img.activebaserightarm" @style="'filter: '+_filters.body">
 <</if>>
 
 <<if $anusstate is "cheeks">>
@@ -779,7 +779,7 @@ Same as above, but with eyelashes.
 
 <<if $penisstate is "penetrated" and $enemytype isnot "beast" or $penisstate is "otheranus" and $enemytype isnot "beast">>
 	<<if $silhouettedisable is "f" and $NPCList[_na].type isnot "horse" and $NPCList[_na].type isnot "centaur">>
-		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activepenile.png">
+		<img @class="'layer-foreground anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activepenile.png">
 	<</if>>
 	<<if $orgasmdown gte 1 and $orgasmcount lte 24 and $femaleclimax isnot 1 and $condomPlayerPenisImg isnot true and !playerHasStrapon()>>
 		<img @class="'layer-frontforeground anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activepenilecum.png">
diff --git a/img/sex/close/chest/0.png b/img/sex/close/chest/0.png
index 064cda7dcb5f075956139f75bae98923114fdf19..77800a9cffb8ffb1522c9f87c01c46e027d47662 100644
GIT binary patch
literal 1970
zcmbVNYitx%7@h3{S+HQikQT&@(`X<t@7bM4x|Fh8>4t7u%LYm?(%G3iyOZwD3^UX2
zwrVH@tt18^S`&nZMq`bUC~ATN5tK*LANa!rBq9$VKOn?JG)intz&pF!wKe4tCz+j@
zd(S=J`Of|Bw>#tQt7~R0oP{7rO|&)A0iP?qduAp49sX?FFYvJ_-j-;&{r(3->+#=@
zzVX-j<A0ob`^KBkj$b+Z_qB^~e6R*}A<XY~w68<%lrFwv-#Ks4YTf7{$n5#v?L*$$
zUxy&ozv+oiw=>ozDQ1?CRWk{QeAa?!1Zix_Te8v(Tr>$%x)H*DJ$3>^bv1--2*jwE
z6$WX&wciHo`r8vqf43s4Sknr$F)u-aEO2EspUoJKln-GAUJ1T?!z6|lAZ~XEYxV-7
zov}C?Hf?|gh#;=eoPhEoK?gaC4K7C+iWW&qAZZq-Xo(6+0Uj+~7>s7Cn$!__x)ck3
zg|M{iS`ta-aycT$5~iIZX;Fk649PG!MBq-J;mUd3a2h5UBEV5>-Ewu)Ks`n|Y4*4w
z3@R<AkhRLRhEuW$8b;=2i=+w4OQ`@<l`_uiu``9>szQPc$O6N4AeJs;t+eTyPTIT+
zb$NP90BCJ2R*o^PmTa~h!f{)AVHzbvrbRo6J`0c?z%hGl1+?@+nGIexmK3&u?3#AM
zG&2($6`zodGB9g&$p+m}&78Az(gF~XT@b<;3VKcPIKw9>Q3`Mp%`BrBiK2?on5pVo
z-&80|Cumv<uo4%X0)-``%C3B0u&PL!X=i1au%4AufV7MhhL&xV!e+*_VPH?)<nd@Y
z9JftP&%g<%WA!RD+7b@ZVlap^1YM9Di%C(#ab-gR(MSk`<`BBBO01{}v>f1ZO5in|
zp*RW`M3KTZN)|blQUq3EC)P(yrN=7)Z+-DJsHOrr{*@<ELJ}}Mh06h2#kByZLbfD>
zs{#mUEE{BHv1lGtv)0z(fs`|oSv^%MWK1#?9}FlWF0z3nuJW9K3q0frGAtwW9H$AK
z=9PV+lB8DMfqUFnI!NolmeN~BM+?Ox$%=O<LYU%J15mNjus)3+4-~nyK9>fN^d41G
zjP974o0DzOoPyrnw+hL-iFf4QdrN<?tt@JqDt(%&{Xf!6wkT=YNCDVkNz6-z^m<Wo
zQ^^1BS7B~a-<p8KX6U_^yD<DH_i<oAY8!UxQEBEVg7}t2Bh87<mo8uUX5n`9;TiGT
z-B<4Hbe1QbN}}%Kg{|OB`<xox5jX8}j<t>-+^c_i!2i{Y^WLeNvBN*$_r1K?pC3GY
zWR74Ts{d~6IA70>40df9s~zKzCp(wdHWFugKB<?H)19-Io(yjSJNzSa&tE<DQN!tq
zk;}+qPyF!3;zw4!YVF}h4>!NI|I_N5hpQt^e=bA#1(y<6bq+b?Tf7^8<*Bm+&xsF>
z?0nug{&U63wx7O62qTCPL)ER(N@35uwvj-5@OstO;dvV`z32NJeN@<WVebm0VeEB%
zA(E`JPA*6fYbX4-y2clc9N1hrrkp{plh@uIs8H#?swMkEYr5JFR(JKi@OWKq_qJ!|
z+ut9Vk<Na6<JM8^*1)$rQa^6x*ZYQUVr#bXx6iGtKD~CX;r%m4TiPQZuIk$U54-V+
AlmGw#

delta 311
zcmV-70m%Nc5848d7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc008YtL_t(Y$Gz3<4TK;J24Gg`3a-!<-W6D(E3g7%A6f*emr%~T>ks_sle`TY
z4MY?|pzW;v%G4AvqZo<}&^joEtqF=`jSGkfhLp`17qFzX0W>lNBBk9(S@-raIC()l
zno4SEY!wbL+<zU;;wk*VB*+ff2M~d7xG&@dWrHKc2%VLnQ_ew2z-34oGh9I40r?oT
zhemzKPXT-Y3exbX^q833;JA}+8A;##Dc}ku=L^U=_yFGkuK}|+HiP~N<VS#=0QbHE
z;30q?;3=Rl06YZOjP^ZU0kG}z7V{G58C-t@`af9$7#P~i-~|~yAVI$pgX91J002ov
JPDHLkV1lXoe4YRR

diff --git a/img/sex/close/chest/1.png b/img/sex/close/chest/1.png
index 026be873bb07d3923e8e6ed2be4a948fbeaba6c7..0baad05d10216fdb615173e18d4b146a3a2401f0 100644
GIT binary patch
literal 1980
zcmbVNZEO=|9Dmp{GgpTrBnBAbd4zz%^<LZSom9HDgH_kDjE0SbnBL2?_OkZwc6X!Q
zz_1Z?G4MeX1hdVUVE7;~C2>mB#SsXM59$X60Tta6lLa#)2p>=q@VTz5n;9?hlIuM$
zzvuV={a>Dc-)L&wR9UgC0sv4Mt&cRLZ^(ViOVRJUCwr&Rr@E;jUU&C{V{dOI{`~yF
z?TcUDI&=89gWLc5`KvpVKcMx#O3Xp9$DQWJE#O|^;Y$WCxQk}}HX8uXV)tDD`UjT)
zP<BI$w>qt{22n9GUP(1%=*?wJga%;!hMXxW?a;wwnAG$j{>K-iIHsvVyu}xzVrCeo
zwEAufZs~4}E8XpipyC@|#Mb9TM38}wgyk}6-4=5}JkKklvAay-SRUfE2k{!$Al4dd
z!or3HF`w5@C^Q$qc)?5iIg0hK!x)MdNGd?mEJ4vC<rjTCR(Nn^%~IRM=E%l^Ei?<_
zDaSEIlFVka-Yn}itRzVb0^(puh9MAwu)B0e$`QJ~a)u!SZN<_|M>BNHWt3#2(+T28
z>9h+Ovq-Dkg)pIjkvYjEX)oovln1Ix5odN<>AZ1OAz>P3pzhcROBb<b%5V%jW!#6l
zxIM=J3T-S_v@x%iOr~hUcItK@Hwpon7j4J8Oh`6E+vv0uShoYoT<LmaieU>%j$y?O
zBR!L-rWwf?gS^Jpv}n3&WbNl>9e@$ZfkB+1P^>AQVE8yCh(1oFnY9!nQq(jwW~f?Q
z*IXz|$7x#hu_DXQfufR8B}aNFSXIO}!^%j=VJ#yiA!+JK94m%V3>#^~LWW&+v)7~H
zaFb=UX=$`!H*c!NqIF?EE%^Ne<E8U*V=*zR+m56wFd7NsC^%kCQ$?AgRN2q_2$^D3
zf}=T>2=F{hsF30Wj^}7u@Xef$7)qyG0`B?g+n^c>;`mpdO1JqrT44wtswyF&>L&t}
z>?Z^U3bM~fDYDGXux++9bRnhmY*ts5iWvO?DZsL90G;L~!pCzG5%3ETO<9$Lke4Yb
z;Ff*9lEiw=Mmg>(T%;|qqcBQqSiX2fNpUYl5Leu4fGS>C*5--FBUvt-&!!+EeL$5=
zTepoiCo5U7CW&JA&?+SFC*GEJJXrdprE*%+T<P;v?f;Qp2#b=E^dv+bmc(6WNVgYF
zCx!fPzVdss`qm5_HA8n;?80bL?Bh^J)E4T}!-s}C09fFQMrz`%ubsVgwd6EbUN%11
zzw_Q|z5eB@3;TLIJ~_DS_o=ZfYcF(PteB|k+|3^!3ynN~<oeLysuNfPIDR0J+k9%p
zvhSYET{=xM=R2NQ$|hb<*hg2rIR=IkA4kkPy1sf~(PN=+hTg(QQt^%NfWMnwedg}+
zXP5VMfXlVm#uu<7gA=&cu&?H1?TNDMpO!^7+*;97?a`0^qH%!gS$Mu2-@BA*p9Fg^
zd(QWH`p-sxsu({qTw)#_>22nE7E|X|q{1%=ANBY3(7$TC%1<dZy*Ia)2F@)6a+$ej
zxEj2FX0R_oKGhN$_;v&gefHk>KTbXkMxFH)T|-O2&1)lL*Uu$A`@aV3MyGmx6P{DI
zZtqUi-7Yy+WnH;ey8mEnrt50e&X8x(wi~0>uY^_}UehvO8ka+rWm|VHcmE@!b&Zh^
IYZH6^0aH4e9smFU

delta 322
zcmV-I0logb59I=o7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc008(&L_t(Y$F0@d4Z|P|1yEM-3R%G`+!a{CD`W-6t_g%-S_wnSM;`b{mjEJx
zh(ZW-+%3PEHU-R3L$Lu`2ikBnL6NL+0TDr$av0+RmS`D3BU2!v<wo?H%h$lk3*uEQ
zq_z@Ug#&cG-G5WOg&&v%$$)(T5qJzg7xDs~;0Q6IjFnJEIR~16VUW^ixPbfuvJKjz
zG2tZ;CqMybw^ZeRE`Y1&OlinCQ(4U!;0n?g&>kP)FTghlE@0=zWY8AiJupl&SF-`?
z2i6#Nf?><wjPp763djP$TR?vRcnQXgcAl;P*s|_oULyie2G`#}`JXHSbme960oynr
Ug%CMmYXATM07*qoM6N<$g2BvwfB*mh

diff --git a/img/sex/close/chest/10.png b/img/sex/close/chest/10.png
index d1609d30d19cc77f46540ed86b47e49eb79d4b4f..860b47ae6386ddbb2c565542e162b095d9805b9d 100644
GIT binary patch
literal 2007
zcmbVN4Qvx-7`|=%<03_Z#5uj(f=KXsKmEOfvW<3Zm31^-=Vk=i_3pd&q`f=tuC%Ly
zn?Ko%MneQb*c5^x!GVjY5e1cnA4P+~D2BgiK#hRGFcyDUnBsR`S2r_$;w9I+`@ZLU
z-sgS3_j~(7u&%mz$~{vM1S$5{_(JemVcwI9;O}dD+AhIINw79t_4k`QH#~y(?_GcO
z+fRNwxb2sX%LcwbdhPsaINn~28W1+w2-Vdi*K?Pvu=BV%sMb8HBgoXd%)0>D+%*e9
z#$S=bO-56omgSX%l@pW*u%;6#L?g(8^0dnFD}jMVKva@F*yVluF;o&fSfe9A22?MI
zNi`V_)Mx6#d}bxj2w3?-bU~Vh1PNepXgU#>bvEt6vb-#OH-`xf%|eWo9<0&~h&Ba+
zs8`Vd>aaR-p0c}97h|QIcGBj22&GAiAxJkt*>I9#Nhj-Yp}7l#(KJD1L%zkiSn$h(
z#SBAb2_ltBSyMKvqD2XcVIT)h&@>JaxZWZgTpE}4vS9`v(0NT#4M~wvlaY%kNyCFd
zr9&ws)I6=M=WK$85ot~(C@X2Elm!ZW9;YU?cs97e6Ce%}KsI!UrSe!crWlGIQ*J<=
zpB@zeS{n%DV~nXKk;sS8jjGi!jhrE4qV;f#3WyNUm88als?|_tnVF5sdNsfqiWXLs
z`0z#rhb5yl%o=^LQIZ8ErOzF)0QfiqcrcoTUXw1Ic7;iXb=X;oo=4IwNe)2+iXe$C
zqoFn`Oi?D3WJW<@$q1am-4ZPDtf*)S4kj!mxF{f0If|iq8(FUsS2P&dR5x<m@AU>X
zMU>)jLJw6hLj6@<C&f6OIBlh}asvU@FY5*;^T6-(V9*?^BnhnOblGXQ+lB+0w&9Fm
zx8V^^6mgr~A&NZUNLmz!*ZUMcX_kPwe&{p^3J*E{l}FjR2!Mr(1BN7V8)X;phyWdQ
zQ$Tb^Y)(q#z%biVO@arKi;rYARSA$$0JKQipdc6JaN=&a-HkJViQp7q7=Z_(LnQ5H
z*=H+>t&w!N$1S;oR1a3=-r^FPEgqKR%|qeAc(WRSfaQjzG5ol#$hq~Y7=WZVsgj}S
zx*{4WP6L%u=-n-=khqa}om+i#>9@C)Lz+fQAERpjkMx`^e2kN$0CrdcGm|0AUNp2R
z#DDiIJ2#?l4Z~qGG+*;w7=GmYIFKQ=2D@~3--5LWQV{g}D#K0BA3pJG&p~w3gyy-#
zg}+u@S^IX++U66bRJ*X`jlSB=$4{*fJv`S^>YcXz{BGo{`J1ZGT6W)ov>sXY(m2bz
z=k^seG&ETDulw=pfpJLhy}Kh8OXr!Q9WQq*-*PzJ-r;=?>BhgF(5-fW-X*_(wrM#w
zW0PxZrm(_}9=NojrO`JZ5iL(&^lW{iB2}`dfS>y60~_0}_0M#7c8njKcx2wf&I|Gn
zbl+10Gs``-OL{+Cw`TVH1#`|F3m;nC+i~h>`^hPYZChr?v#niQ5N1USGHv2d%a(pu
z<fxo6{=FAFiyB{FQ?#nJcw^`bPcXW(dwNyj_QArFchcAAG!Lxnoz+^}|8vDR2kvhh
znEuva&*X;Y(httiJ;!!+#Y&t1n7->0dp1)t_+<TK6OgjgWyv*%E?4j6|D@4~uk^m;
tmnY|ae*Tr&$c4LI%BPQi94gt_J2n21_ab)mos9YS>94Bu^(<<B<{ucCty=&9

delta 367
zcmV-#0g(RJ5B>s>7=Hu<00013M{Ml?000|MOjJbx005O%E%LgQ>Xuyi)xPw@qWRv;
z`{&yJsjHmQdgK5A00DGTPE!Ct=GbNc009w6L_t(Y$EDSQk;EVf06<%yg|t8mv_K2A
zU<)bxQDa2UKk%Q-WDM*DGx1_dDZ$kP(l)*W(7+eK9{>?wuYUl9590$7VbkSWjSpxd
zT4rWTd>}8;b1CaJF`NK-$P+}faKXr$5gHK$QwJ%4!hmtq#t9ApvP`1Q6~-)&z}v$1
zaKTc4fE)nYl}itf0@(xk<z+d5?aJA;a6u8WiZh@>R&fZ(iuT4MAb)~fbA&OFbKZa^
zAOvIsYA)9v5on;p``$cenLPx-y$AY3{3p<S5SYiD#NAtb1GLoV9uxrc3aN($-~${9
z;`S9DYrm{H7ZA2I(X$csLI0w=fK{{@s$7-5t^RR*(C;_(;jy83;0JChKix-Oq)Gq)
N002ovPDHLkV1mRLq7?uD

diff --git a/img/sex/close/chest/11.png b/img/sex/close/chest/11.png
index bd929bf974f6587c8ef6e64afc30e470793f04c7..1e747c4d160b8889ec01a9ad2ef4b98f5238d418 100644
GIT binary patch
literal 1992
zcmbVNYitxn9G|-a!D5kzA}J<p7D+(a+u6PMhNF+Wqj%Cf&h~^7P3+w6+;#2U?z+3}
zT`TeuL=qB0cmxqqN!1t|O;n0X5CVh`LINL9DlxzZpNJ6%8Wm%my}O>RDUZ0x?#|Bq
z=J)^oAM@W$iFi{@b!{~Ope7m#wUBqcbx*7!&sPtuy+U5I63xl*-|xJ;V;OV()9t^1
z@!5@I`!4T%>W>SjZhn8B%x|orOai;dY>Bsmq4MRmzjD@^)FLYk047bhZX4LWXC?sS
zugS?avn|#vh-%J(BsGN{g`7sv04%I4Xh`hDCY8b&Sqad;96U@@vJ{|~yJIk>1#yQQ
z>D6&-Z#*gXc8Y$9u3JPcEC_@khfPEka#_U?3IV#vE0D1@&C*m6Vs-}T2FoDT7E4e;
zRmYUu;bBD1<)gfQ2j_7?r)L4hL(b1aAImuz$O+IRxV=>QqKP$KN((Ka#bsOMD?oRc
zrY5j#KA(5woeovcu$<pdICz%l8G>Mp9>qijMlt3LGlZ}q>au3aszO<eD5Z9p0h%Z+
zxscN;w2Dy<6A2hwKpM+Apyg5#D2WxE)}?2Q#wC%(S)9X)X%H+|!D=0<sTv*XEvPHY
zqYRMH#$pv4V`|CeDkcmw+)dml2V_jNk?heh+ky?XOBZpto5-AFd7}wI9V1iKld75>
zPE=x8GQ|_Gsd>v~MN;#|{1F>)2$?uQ^N_?EdKuoEgnq&85;*=*$O{mbpfOdF(><f1
zPA<uD78H(#l9G{-iS7uNL?Nx}IYb<mb0~vZP07$yC5%E)&8j*vY^fVL9}NZ*x|)`=
zWWi`@YNVp!pojB&JPhyPigIHyA*vWAQbZgL1!xi+hb&8i%jbbO?UWcU<#IA<mkTn8
zLn6atG41p@)5wJ?`$MYOWtD)nzjPWTRU{n$%5!@-r{sqcL%fw3>~l$s50MCZU|Nz=
zkoO`VkzLHcuvC}HfkfGntd=T?FiKvR+bLqmq*5qtNkfc3h27-vh+YXo5APSfR@s-B
zBC<hp+*3YCt@zpUC@WLN;t`N&9f|-gTGfChx;!n95s$mFT;8AWz=ZTRRZ_BUsA)5g
zbli|3vAbgxvbPd%pzhmCzq?eHG>w)%M%Dfw>E*D99Z1Pw(qUQJa)z~fQ7I|xfAdvb
z8_~Ch;iMT_!%7z>AC*3i6+*3(F1>rp-sb_ZHAF)V$+iuL&e<lvK;1h&G4+uPL&rZ{
zHl^=@oikSR!EqP*TQ{E6Pkgd}lX0?e|C)pLGxp&6+N(`Rx9&U=SbuuLfHR_P=<nRf
z0XVI3Tkv&y#c?n=FyoEx-B;dkzxWVnrMp&6eKAq>bz;?Quw<8Aw++%qp6jH>0j2hw
zu1o+^?5lrR3fKkTx#Cslr>&>Y9=Um=HWD7R|5bB577s6s@2j0zxAOC+z1ylI_kG~t
zY9iw<woaLDqx<$Y?*iQQV^_c2@zTnMS>W2KiHR)-Cstkh>e}S(b8P)!{?E~7kULE;
zn($clfr0wXH@7~%M&GkI*nV-S>guG!Kw5X=Nqg?k`X`P)4C?fuGdl)t-@LZzt^DlH
zXX-CI-ZsSRsU<a+=$}@-Iq$*WK05SrX6V<p<y9Y_o!b|$T{ZxJoC}Bc%WG%vZ*Tne
TQtuhX`d>!F@z8sX?d$#lyQ-b;

delta 362
zcmV-w0hRv95BUO+7=Hu<00013M{Ml?000|MOjJbx005O%E%LgQ>Xuyi)xPw@qWRv;
z`{&yJsjHmQdgK5A00DGTPE!Ct=GbNc009h1L_t(Y$DP&DwZk9?08m$8g|5H~tiTGa
z;0hW0iQ0(9J}`Ww3EXoqi47^G1fOp}+Q$C?O5hFP1t4O+1%Dtsj1NSFO_$GVd_WT^
zWiCD81jtRwQOo6;7*2q6(t~IgE*M#JhDHRz)Ik(b7%-07IKTlwmPxd=!dT@IxLepB
zE?DXv$N`{TS$l94$R5a#m*oJqJ7?Fz1uA3}XP^jKMF3=bo0F(d+Xp%4C+Im9K9D_V
zNeqGMWqlW^AY<1aZ$VRK>jgo+t{teWjDhP1$kz)niINWjbDImmb3oI-dH1MSKui6x
z>0Ds1TYY5ehs*`oCP<qBIwR|knF%gnETjiDKzgpz5mEsB0kSYn&pLoJg8%>k07*qo
IM6N<$f-a(&+yDRo

diff --git a/img/sex/close/chest/12.png b/img/sex/close/chest/12.png
index 1433de3bd749618dd3a3065519e9ca9a0bea6c20..8e6ddaaf6d808fbbceb7b1f018586b0738fc0b7d 100644
GIT binary patch
literal 1994
zcmbVNe{9rL9Pe$x@M}(46eEk45(q<k{c+dcwQ_LV-HjdY#@J4nVMcnduXmNZwzl2w
zwg7I+2pEk<#X(SmkdR6E74;7l4aOOb5dufzuYe))Bbh-BU@*a;%-7rP+|2k9o3wp>
z@AE$2&-cgs_W9<fWfjvOoQ`2wMYJK@g5E*ro?4EcZ++1FD|*doZj486?A`bJD)RTk
zTd#e4<m%_UFAlW-dFI&l;ZtaSa|LcA*fhJPsTCV3UcRz7zHugvh9@lyn^EQ5E^Nn}
z4`A4oD{8#WZi_XFK+m`(Sx-QBE@L1xhAm#2GbFGM+IRvcRV_eV`uI}<SLFb)nv2mf
zBLq`wL$?WAyPM*mdmRvDV(AimaZW@88E8v*E|b<QF&7{TydoMq(-eUhAojWdQR^7Q
z+hWalNH-zQxp@*WUO(;=+zjufJ^Z6MOEUsR`zgjl(u_#+BIm=47lEvqvLd#G>x;I~
zSAa;_wjokfHk);4J#O7hQj8!V4whnB5+O*dOS7dMsaf;J7{bs3rfS%#uHg=&l+Ziu
z0D+W_x{xtSw3<~66ABoWlMIS+(~e68pbSblqr*%WjLU$6X_$eUZ6PdE!Wt>v)~%F&
z6YA3P1Oq6vu~^B*q*^kWk_pR>bRsv30httS#k&khwLnYnFaeBoBAN3XZwxVHLdn+6
zxUQ$i64g8=8E28#_`=nyChJ+NX50oCmTVXxSQ^Ee_K~bFP75OE6&dysniXk!6dKcI
zRq2`t^)PXU5jl^@aTB1ZWMs*fZVQ%ysOV-!LJq4LDG4b<OA>e~jABSn>n1Yns2e{Y
z4TYLbT~X6$!D?AnhesnJo)LJSWZg_bZY(B7HOrPX0Hfgmfr8^!Ras;h=w$(9NSYQT
zk_KLdOmK=!0@lMR3S@x53uF7kI_Pjpz}Y`~8e|<Hj(_EOc|QOQ&5^R;p-ISjS<=r*
z0-0cWKa^yj!ub4SY%5F^9Y`rXp4Cw$BSxQ(;enU)l3qmyB<uD1NxwuZq#|<(f#>|3
zpY=FpU#KLpLA6khyNU;?6+T-WrB%F8JfZ}gLlGc=Qw>liiqq;O@wg+)#r@e7M5MQ<
zl2PlHuGm@0gtbW&yW3VFbu;mn)Ol;^cb3XgO%tV0Qnmj_dNC{@C22{BIxIyv&QMM-
z8choI-+UF;#`Uc+IBJH@u+)XoN2!lP4N;q@OS=wzcMQW^p=h`^-nQwB?@!*}htIt0
zr>P5$j8qM`zcx2?C4KR^lUJs$XTI)R(f;Z{KX&;*Uv_B6iIvqoYQ-$FPmrpy#>!ov
z)vSDF(K)QK^@TiF`O?VR(*dlW=-9obZoBKizKxZ^`R%<MUAai`#WTU>*eUwAMg5Oq
zJzKBtz2y2UQFAmmCqIy{8JbyLdC27+nw@_b&(O2qT@&`uOE$RA4ZXj%?B~t<pE`GT
z@Z?N-*M0nlTNG?Ye(8llY*F3dl(X1{#jC={_YC64g2&%G`_7ib!}Z&HyPr89N%xl<
zTW@TeR(|=R;GX>vf0=ON@h`Cj>wCM7l;!8Rk6t5!e+OJ-GWf*Md2Cj;+^+tmYVgF+
zJ^7t@Z0FN|bXLASGCcQX@jB@F!Pw#YF*R^-{wE)8gI}fBke;5?8|s!{zB_w<*Pi+P
c7Z;|dY?P|%H`SVh_d0*fXrw88ux@SNKl?JF`~Uy|

delta 361
zcmV-v0ha#C5BLI*7=Hu<00013M{Ml?000|MOjJbx008*azVySQl~yh4mR$0>l=<Gw
z`sUgCvZ&vdx77du00DGTPE!Ct=GbNc009e0L_t(Y$EDTn5rZ%Y24GiU1y*1MR&WJY
zU<Jo6`KSqLJQB-~Tn&%+TBGIwKqNj(5fjnjD+VHhbd&QOO@9o)5o@Dm(hiWD*qGXO
z3`jdbDyaqFMF`q#_lrBR2wZ|B0LuWm_1ZuifKi+%*Glawx4<3IXM|wrS0EbzX6=-L
zt3c*JXucK!u%``M#v71?jA9P}cK`YnkRH^G80aKJwTTd@>Tia2A_St(8Ck?&SZ{Ps
z5dQ}>XRHCeu3}k)rWIQQ*Bsc1{3o#aMeuZ^u5ZL^knZ&+upQ2cpS73(7y`h(ez*YK
zt5UY3@77R0rXk?6i{;|dz9;f`ECk3#a&his9_)bX79D{Pchod-_-u=!00000NkvXX
Hu0mjfCDx!F

diff --git a/img/sex/close/chest/2.png b/img/sex/close/chest/2.png
index ebc4d26498401d817c5ca25a052a257aacd25c02..878addc76e2c8467f9c94241394790dd9de88720 100644
GIT binary patch
literal 1988
zcmbVN4Qvxt9KUULjEyOXj0rJ0kLX75dLO-Bdnc8Rwqs4`tfP?;74~}fZoRC%JMV6^
z8^(do4-%s!f*J)f5fhXzC5Rt02-zSp5;GIbA{t^`!o(N>g8}?N-?d%c%=n0xyxzO_
ze((4H{XgEn8)GfYsw?MJVi;B(X%4lbcY`x3%Fyq&4>$abUh`wi<Ke6C?B4P)`RgZ}
zFMoab;^2;-UU~G&=@Wm9okHu+RpT~-O}ATHR$zY@9$)DjC!Iy3d6k7>RkNK@g1x@A
z7Q<W@)OefS7F{k%dfE+SJptX>w1LnVws=X_08%Hk@dWHpwE%H$;4=bO<p8nL8>OR0
z5GK{;9uuzUX^Bfcosu9EOCG=%XGKJihBm;n>6B)P*#ME_717*TrU*O-u{#4qqhk<n
zi^lMvZbIDa=1Ga+{J2kWGdxFo`1^2{W(11%Q;dhC8Ik5iuMaOg1hQtzir5-zD%e6_
z0U~MJhDcGFOvat@xOKCGVgvzkuoTOZ2tiuinhmm~W-S<J2ti9SRl`<w4R;tpLhrHz
z1X7xJA#D_CHLDON6fi0a42p5nj!QY9EERD^mzl~Lmn90OU>a(+g|JK!Yb14Bx03ob
zsEgZ^44}|PqeUB2YDuSyCM-L=7P(Of$dqU+-fcjt6<T_iDZ%hsBy)k|jUfh22yESq
z>w0QDQL%B!IE%c->sP9ptY@r+6Ar)-uwj5;X%uVPN3y;+Er?!DWIT&#R;1}XG^)$0
z(mfgKVd4xUdOad5OoF14k%0|v2$m&L(akhK4y$R<0VzZ4An;-s#h{+jO=Q?nH*q}@
z48}}dQB!EcYF)MzkA#CfBk(-Qx|y8ZXjF`7mJKusMnVAs1;?$bvgqR&#_v;nB#@ww
z<op~>f&}d)6@^t44?u&@yNk|;bg9cJ0q1=FHpse!IR2H#v0fRnv_P^R9+EJ@K~mt9
z1fmoq+D8M4gK%8UgQkiuBuGtUbyUfSk@f>6;bl1zdVLJ(S2&(bC=wtU)(7|m$4jgr
zIAx!!B(YhwP>#C`7ik52yf90tc&>OvAUT&JKuAtCK$$2kt5d||rYslEXOa++UZ+a(
z)-7GJGr)w69Vm7;tU~Hq;w`ZD`qFPMm3d8*rB6|{|3`WuEK(9^9T0U`ig28voL-bq
z3iaQ7<@P4@t#LSNhR(Fuh0#Z`k3$Vno2X0g-`Bev!%6~?P-DF9nPVfXYM#btxMH*F
zf9XBu-C1$>jP0X?XR64L)0>WJ_a3hqeC@ID?|bIIRI=__>&)EKo$X5-uv^D=t&0wC
zJ8+`wNL~5dx2nFm<Sr{~s;C>Nt?Zr=tE}tn`*xvl+aVlVe@S>hByWDZvb6Nzz@c*&
zM&=Ba_OHP{sC}<yntv=1*je-P7xj-EZ!g(?sPABJPxbK7j!0Ma0_^+JQ|sN0b4tpZ
z&feZnoOWIOVTbH}et+qo^$%hCmgyC5x=w~F5@f^r@9yavePPwClU1(a1N9q5KPoe*
zJB|$1?%KHME^Md!(yN{|a|hU4`bX`}m&^O7z5D6l-Y3Wx`I)iVzisIox^Q)7?UKXu
zMk95r>DA@Q%jb`5ZL1nC|EssXX^%?@|2Xocw?V)E^Zg@t9xdBT?5Vhtk>+fgzB{q-
ayzA^&4UJ>;lLO9wWhC4Z+PAd*seb^l!kjk%

delta 330
zcmV-Q0k!_b5A6bw7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc0096=L_t(Y$F0>{5yT)21yC%+LM_C?wSa|Kzyh*2JPT}R2;1eO4{~Ob0tH7z
z&N;eTOK(%#0%oWo-vONiZMeE1PqQ%r5y6n<nv4m|M8g0&*#Z#_ccRx6&V`c|_#7;x
zwvx6A0~mUTCx73B9ZVS{0k#2n;5K|;$O?3TJ!BH4Rzj(A4>SXoB4x~B0`dgpXV52&
z2`_;d0SXAiRMm%2=fVJTPl$2N5uyoj1@RkbmkFp?0C(UlAoV;>cN%LekjEu=1bSKA
zmVLg%4w`7Uit6vb1Is5i#%UjW1>^wWEucRDyaa2GzAK-e0L)=VIULO3&cXE<DCfx$
czz{wLAF<{lKYUaGrvLx|07*qoM6N<$g08rHx&QzG

diff --git a/img/sex/close/chest/3.png b/img/sex/close/chest/3.png
index 9c1c0e2d885fcc391d2a918b46afedc76cfb49ce..349232bcf8ab84698637c03d0e4bff75d9f919e9 100644
GIT binary patch
literal 1994
zcmbVNZEVzJ9Pj3C9-BxOA`&H9N>EUGeY@+e4JT}Ox9!4i9NQry7};~}(_P(NTiR}S
zTSSMT#^?v4@*+w?fDelAL<0_m5hT$-c!?+kj5+1Qh`}IcIE*4by}O;8885L(pFVw_
zUw{AK|K<7jrC3Yj<f{9sFbta<X$rNX=R)Up-+{)hd)8b;kNacI@$ld8yu0CX^0$H4
zuYS9K_|W#BH$L&l4@dtTI*Zm{oQ&HDHpy;nX~V7;FMs))r<_HjX}N`A)l;3j4BPV7
zbPRJ{R^#n<d$d`U^t1=adIEZ~X#=4#Z2p3*0i-Ty;|bWQY60TXz5@iV$^l}TFG@#^
zAWW)FeI{({Yl%yJU6LRZ3m(JgXGKJihBm;n>6B)P*#ME}717*TrU*O_vAY69onsJh
zkH+wzZbIDW;Yo?{*5ZD_!|-03<LBWl%?K1-OEDZtGa}84K0jW(2xQHa6|ptcP_%{K
z0z}fb4UwWUnT#jHd33XrVgvzkuoTOZ2tiuCnhmm~X3ZL92ti9SRl`<w4R;tpLhrT%
z1X5aXA#IdsHLDmV6fi0a42tp4j!Su<ER}FZx0%Wtmn90OU>a(+g|JKsYb14Bx03n|
zs7u@944}|Pqa_;?YDuR{CM-MLgWM<vWJ0tR?=>LR3N5|clwi0A$(-eQV~9Z$0$VrZ
zx}F+MRBTi-&LXezIm=W{)-%@JF(1GXuwj5;X%uVPPqO|vEr>p^$Z(I+tVq)ZXjGR~
zrFT4(W8w@W`Z$ph#z9fZ$iN1-1j~}B=w=!qht)Lbgp{Fm5_l<$Vo*=%CNk`(8@nC}
z24kkKs428zwKmq{k#LY_1fC~Z50jT0jfxS?vVkVSNGL#{;CNJ37Hbt+@$x_*IbQOU
zg4c@%+Up~skLP@}1pI(QhVmH`L%P)Mlz{Vn;WWs)ggE|{=jUVvNIpQ;Dm)q(hb@ut
zl8WSKAxyvo&m~6L7Mm(MkRUad)lnrQMotDkmgaq=k5d3C(_V!Hir^<DR`N28EPMR|
z?Ua2%SCeX?9QPIvQX5=VoTXGeUpyj^oI?>HB&QmnOca;Z3F2{EmW$tKk`R&Jq)H0b
zEnTrQz=U<3D0a83Lh451Ezomw>9?24f~N7(C#c&0BfS_FDG9Vrh&n7qIL=T`FDfL3
z`ftASdt>_6C>%9IXIkpQ=%v)hp@yhU)TKXbCr)BmSuhf+i?=_2`1HwXYjJmFu6gSh
z*QZiMc&$A&d~WaVSM?pIQmY#0HP-Ig_0?(ZJd+!7AKY5Aqq4H1BIjN+uyT^vwn><B
zb;iNN7wW&evT;pWVBKqnYN~qgid8+_weFm-T<Zy9{nKZE+;H~oMQOLYBlGF;%g2{~
zS&`e1J;me#ce`gc^fgVJ1y7MfA7N8g)L%UCj4Ro3a@!+&YA~aW-?k_g9_)XzuR2z9
zsl3lzvU}jA56l0Wvjn3ytRD1iKk9O?-?wvkMa|rMeqt7WQ;!XN@(WYG_ra<TV&xgW
z`b5P@5PSN}o$nFH?CBkg-*_Om`jz(F*{{W2_l~gZ`};p19G1E^jT||0W#);M$6UwW
zpMUL0<$2iu!VLZQ^@E!?SDz@q_H0M!sH-7-Aw4uBr@cJ;Tvy$%{Y%&B+pm4U+2#Im
cX|rqpLp$qSyS8j`JAcebxFz&KeaCbE0Axv}6951J

delta 339
zcmV-Z0j&PY5B36(7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc009X}L_t(Y$F0@j5rZHM1z=Xl3a*e9-U_Uc6<oow8w?;=?|jzs!z%giUe1Cf
z5lJb@(nfij#w}2V8_6BWbKnC@7m{T*6fiRkDa&LiFcU8W=;RiddASq6mh#@XupsZn
zAaz7+6$BV&hkv`=1P`VJD?mAb3>-#}i?G07aE47HdKE;M_rMcyYSP9G3fL8}pF#iA
zRPYiQ3GfAmj6{MmvtDGZDh$v7wr<;3m+M9W7v*6)Ko>qo0RKG!8$jZKT`riCm02)u
z+yJri_ZLNhx^dg?txLac-aBw=umx&a2I&p3@+Bkz-ZTRF1Hemg&gkFMCjfI<5r+c}
ljts5GK%6I!0EY5o@BwV+C>P&ESsVZW002ovPDHLkV1hc0g|z?x

diff --git a/img/sex/close/chest/4.png b/img/sex/close/chest/4.png
index a50866ffa687e10bb2829100c6b9f9cf5edbd15e..b9730f2cd9c071878729fcc8a46d23235c7834fb 100644
GIT binary patch
literal 2012
zcmbVNeQeZZ9BwxlV}PO}K?tEMiC@s`$MwD%PPW|*cEBC;cFGY%_qKiSu5#Cww&QLK
ze=v-Kk;KISDyS#~69r+Y2?_xgCeauS5fD&d2?53M5&YO6gAwrU?RIWve8eVg-@fnj
zKELPp@&5XHePs5Siis5%hK&i;1*7O)W#8qc==uKc)+^{WseWFp_SPrc);&-CwP$V5
zPy4$&H(y%+!u77hy%&E$^Q*=X7J`kmqLBvdcH#1rY&>pH>U9fE3>)=`edE}M_a<Q2
z@IRGU+=_?i36hp^09g~EBbU(;8pCGH%;`W{0xd#>Nk#RO*Y+MD2}Smk3tV9)tOsC9
zscSJ{LrWwkwJec*GCA`ZVn$9t1Q}=nB9}?4rjYZKd0qjH?P;1M@(^o@pRBeG67g_7
z5zq`sxEyXuVtFs&@i|yG&p6%F365cXG~=aNC&jP=;}%>VqHvMOnjt5IXmD1+7W(p&
zDa+CYn$Bjkj;zz68A+P;`49(3a~y>bl-aCWAV;a@)P9B_G$ljPEk#oan-PdwljSFo
z(moe5dXZK&3t>V5qjNx~SqEdgln2UE5vMm9>AZ1SqG1|lplX>2%NDVEO0zUGrQLzL
zxID-J3T-%Cv@xWXOr~hUv}%_jHwpn65^ctsbx22{sWllAtX+m=PPM(!g@6Hpr5Q0z
zOZO+LzF#uIA+L!i7bvQ%WzDAsY=A*vK|jecDAtUJ;yf|NC%AZlbxvbAfnoZfVNF&N
z&4Zy%Hpa4o%PFwzASfys8Cc++U|A9pnvns>VI>2Skk-{CNfg5<1hlkfAj7u0f%Bn2
zpx)3DN*XPg(b+Xbs5anceQr0!IoQ11a99YbrUg_9hJt<)1;?Q%vcU0>lYMTE;&=~F
zB^aKkL|O78pCQM1M6Z|SJpKEFn$%>MfW5!(G{~BSIR2F<bG*m_QKSItc2NnyyC{(p
z-IR-kKF-Yp)|n9d+2$JxI*=eekkwWtBSt7Dc$Wxe3Q7ql<pjKs5<MP3i40&RAhJ%z
z3+=McSCUYtm?+21g@e=pmlj58g~%6=03`cR_({pG1}Kw-X=R9b+?VCT{%i^&(z{ei
zpLJ79SXp4e>LiNYJ*$wulXw#>ySw!JOJ$#?!P1AQ+W#ZH5Edx~)Feb5mL_dyXuB8n
zC58TPzVd4W`c^+2HA8z??84}y*vFxYs14MmM;|STU>N>fC|Dhfzk2B8>Gdm_(ZlQK
zE;@JnK>XN*x4Ol}#;48Vhd-YOb7b|S<DbRK7d04}_}i^L+t(i4W~i+rar~?3=3iaa
z$@Jl-j(y`+DX*kYx3%Ke#;TF66EAR8)R{Bn^65Xcd@&ivj1#lo==uEF$vA#vZtumO
zlaGlw^FY<?(ci2tjeh^`tvdfK>C~37?U=Tx=EjtLWhv?F)8&}AYD#J<UrBUqKU?~6
z$*ARB(<{$}Z~Ce#^^Vk}WAXDRx>heeQZnvTcK({0E4@#za7;e30e=m{_gwG}`=fJz
zS?ba8ZM7vmKX#3%z=vNty6R?U`Ac|rU{ibG<Fdn5t=PQZrww!URzC6OI{w>t{=R-T
z_fY$&V+*g2`0et+O;;NmV<kHOvS+6kYmA%<Q#&_$SCn<%ZoR(X@|?!;HSXOXEG%8~
x;;!y<(P0mE*Bsw+=+@p{744;8?%3K<`rYF*7f-D0Y_tENq1s4rM@{3(e*k(}uWbMT

delta 339
zcmV-Z0j&Pq5B36(7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc009X}L_t(Y$F0=c4Z|P|1yEM-3R!^_?h35n6|w?j*Sw5Dkz(5N5w-Y8ml`*L
zh(ZW-ja9xa>lMTZF_aY0Igo`*1tnUI3otWG%C#65Sc#MYD0v0UQdT0*QmzLlFG#i6
zNM9|s3kNW}=6_Qf!Vi`NE+F~<5-?4i5Ap(OZ~`x)ot642-+?4xJ0#l-2iWT!@Bw%%
zmkj&}*a>W-8L>{FW`qN9cVRQ`BfxjgJ7~fK>P{}8{{sfd*$c{60e$cd$ZjweHV_;@
zep*`V3fjOpz!dYs>!rmMJYb*L)+qB5`VvIwE9f2I2{cFuyny}y@FUnWwB;uNYq>P(
l2+WKzHSMO308IH9d;oTl8+ik90T}=Q002ovPDHLkV1lsuf@%N&

diff --git a/img/sex/close/chest/5.png b/img/sex/close/chest/5.png
index e82f18284a3f472a550c6ebb787d90232f020054..3d1684e2ba883e9cdb8271ed30396d34394d17e9 100644
GIT binary patch
literal 2014
zcmbVNdu$VR9KUW5$I}f=U?_MTBIvl@t9NZrI<`JwC3GyKxJs1l*SlZW+uFPH?nb*s
zc^NPu3CV&m0TU(i2WSxEcu4{TP>4d*fG$x%L<3PV23-)t%incf-OPBzORo2Oe14zr
z=ll45yQZ#o&ZyxNhGQ5uDqIt+N8c*@Eh$F7Z|+-h1$`c^n->k;-tq41&ys(9wBh<!
zhkA}}`(@+vf1f{f<MKCX{nb&pg<!+1`q~B9o&4i2+H%%j)N7tIF>J(G`*mQOw~oiK
zp;wh?%!)<kiISFf0$GbgXEv=PG=|NbmDPdN0xdian-tYY{C@B-fh)3)Xy7AsL=V8E
zQqyk01?{y_sl7$=%EYWnd}dZe1ZijiJey9brkM2+IbIQs?PZF<a}cY=M^xJe@mQn|
z4`>F&d8a^1jLU<&y-r4O(VQ>?XKBVu(H@H7NSYC8LFC<d{vnVxLr#eG!P$9RXyzl5
zmZggnmC0nB8P2I0O%&txA`X^fSrQ>gvrV-?mQ>9teGEZpN`|6ail*W=BZzCQmXAP6
zdtFHD1zOe2hY1CY$^xBYoV4vy4k$|noZf1ra>iwef+?7Ws%0W9Q^4v;&C<-Ib{Fcx
z_5cGYw2?@`#-Li#>4FK<3N1ly<O4D&+Kjg8kgA8K)@n#Fv;@hVVtb>D0RsX{GoqT7
z>Pu8zpJbdxUgOgn6jjzT=2QI+z#y=ok6>vOYuZh+?kMdQd6&p=6*Mc-bT2fb$x5Pa
zAe3XG3?uTKNDqXfl97Q0?hBSBF`*f0fE-rRpb1jC+C<=mFp2>!r5VVut*-xiI1s2a
zw1kpE8)p3+KOPPR1jZ`}B<o~yaw8EjteO^3B^VC+2oxNrqR67ecqNWw6Qqmh1mvtM
zL3;QEPr7*?N}dGc@i5-L^Fd8&wM)Q0-+LQmO+p<1$^(4d9d~;L5=sn9@-CM^qA5p0
zH|M6^g5Y8#p^t68p`Z&1QvF$NRWf4a0Lw!Luq0rCi%fW3kc`ukKzfBZmxu!p=NQ>8
z`&=c7HHwLH+?Kyc3*d|SQA)vc#UldAz7#$}va12gM1ENrBpwfBIe$KrgoyMWRnlwS
z)Dl((7_hnt#qPdUNZn1m36|Vj`h%siSJOc0gH-MRk)98Wlmu!ML>-nQY-cFD7xgBE
z`ft8+d;R)W9~?D9dsyhgXj16oP({=R>e7dIr@ArB(GU(+M`No#{`$*~SMZTT>&jxc
z?ojHnb2UY8Ul|FuOgqtWX7Sn!WpgKP_j?Xr{CxGEk;gOJA6Z&)c~WPo6MK5<g!5yp
zIiGy@(9I40&dQT*qs!eF#;&{+-5J>EXs$NbU)a3mSGnS-<KzKhZgA7Ooh9RrOltoA
zSog4aF+IAf0gLw(*MIuP?I&K_!Thwa<Pf%zoP2G*=2#SKo-h#`vU^3Pf85cboqJlA
z2d)<_(=L@ZkGV7P$m&05yc25dTBnpQ`i)GC(_h#;e%1b6(~fV#%8r)f7ne4Sc&X%v
zA!i+bonD^$(Emk4ThYv|j+ghxu-UtcJKwwJ`7sbJYCp5)gRaLbt9-kACOcnksY+e>
z3{$(;bbaeM+5Om6`T&M^O!tA##ZLwgj-a23_H4V<efsj$mh!jKw{9G{nLIb_l)r0z
zdC9WIp0x`%siB*Wir|gLpHCzo#`nFycW)83qP(iC<9g{;`(HF1stxY)H?I5#ZZNC+

delta 356
zcmV-q0h|8b4~GMg7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc00A0FL_t(Y$F0@djl>`f1<<tM7Se)SxGm6vTSyBjdki*Dt%OmQk0^uB=vqLM
zi-@l4qPvd#YZ_a?3^kM*pmU%DcN3IoHX$G)7*g)ZguqO+44{!M5YciYdd=n1I7LA!
zMI$~e)<pmevwy=~sv-`i1j&G7014=Z`-P%F7dSyCVZD-fxd)nnrAZkx0${B>kOS~%
zIcMM_5ZkOR7#CW=<pkDo1RfV-##1uB0LzF1dEU2zIU@qf#G3*4Bj^7Lf;^uAuRtgF
zAg^yN=rJ|mM~Jl^0p%(4CtgNi=Y9+H9%-&Cu$Pc+Rz(0*QCriFvw$DDEm$8LUvGGQ
z59l8NK7uu)y-!a7<}$-R4q?zU>X!LVod68wWAFo`h9CV)Z4w^<0000<MNUMnLSTZG
CTZ^^;

diff --git a/img/sex/close/chest/6.png b/img/sex/close/chest/6.png
index 518ddc989743ece86efad86aabd451e01409321a..96c5127d16ba30167c73c1c8e5c9f53e56b949a0 100644
GIT binary patch
literal 2015
zcmbVNd2AF_9G-2F6mShk(n38L1_&i~c8;CB28JHHl`eKmZC5D@hS@i7b|>u43^P-9
zTO*dHK#c??R79Zx0WXNe;|~)dSOsH<8YJOT6GAkKg2qB5fHc-O+wIz#a>Pky=FNNG
z`+nc=c)xkRp?;xreCc=$!<^yTP$PO*+ILYQdiH#@_BZspzo9N#^Y=UZUw(qT@^Sa|
zQ-}XNvisuJWjD@!b@Re^Xnunew-9Wc)mYzz4dgCg!S<8(q+Yw!#IOld?Aw98wqq)W
z-E&!qHe1b+Iv!{#mndm5=*pyYgvPM>6&YOwE1`wQU|dlJ;*W!$5V#@<#1c=0j_5&{
zP-@!@*wj`Z1#K%qKq4v@;PW#)B1l0?#51X+YVsL@$nx@NY)?}Jo`qN|1)|C}h&M+X
z@StWu+~e|+fZ_bOFW_Rl9PRd&<1EbtDB4dkZjxqr+RJ-<c<v&QHA9m5#?T`<Tj)z5
z5|*X&6qQb=U1_&VGvX8z2p|rYVp$R)NV8S7#0;sLGlv*L&;*8}TZ*RQHlrBRS}cJ;
zN(Ws?>3Le!%!LUBjLL{Q#kgqOr7Tbad7R#2B(ugPK*1zTLDe!5mdRuFgl1`GLc0ZZ
zetCoe6xv86Z(~#~sZ`#CY1OPoZsY<oD%y;;>X2%Lrq*HrShE_*oN0Tb^FafOmS#jX
zEjg5^h9Su~i@e6mmME&ErOmm+Ho%Z*L4jat6l>Z?vc4!C;5{7AxF4ojo~8$(5lvF$
z){#&*6J;3Q?c+J$2q-EUNwmZ}f+fJqnvoKb!%9kwLrPcU1fCBgAJmeXfehQ~hR=tC
z!3IN<l_Xj)8y8mN;hLbA33$CE>teEUBN0BVnwF>n7!C;p3XV%rB;E_$vKvT%gkCmA
z(twjlKa6oC&H4h2kMl_q>lxY~(m;z{0`~sF(;#U8ar`UK3u)Rf(;iX=T#RHq98Jbz
zv>)-(4D0vP9#IYqu`M<fbRfm#a8_HDgcvza7MVZ{A{jDG0xt(hzr-*ka7%Jb@&;lw
z?X$~1TS<JaVxk<k<_=O5T$LLo6+Bx!ya?<=ArQc>1}G7^X=Rjn+?D0r{&WH&(%V$Y
zpmkG|t+Z&ssyK?>9jlPKm3UKJeS7J5m&!p+Bc+d0wf{$YE-WA+s&R-qEJfJPP<AgG
zObYeid}Y^$^{pW|YKHbO--XdfzK=r{Q5&dBcec%9FwD^$4pl{)k9>aS`^lYn5%x{p
z!Tx~~Ep)VIU(ci$=EP4mb-zAuFS%Z5EZx8B@b<)5!!`RsCgSO<9fM7MqgQ{lm+HDU
z_Gf{9mEXMTkl4{aZ_J!mga`Ic+ZNxkZ06ZFkM+OjJaKQ`l*Qd$o60|%=xDDvIpCz;
z>eA2ij>L?Y%yNu62K>%%7tJkghZDM<yHwo14n73j?c=Uj_H=9sVSU{4!tPLc-+;8J
zS~z;fQSQG`eX*!=+MbSdu(ROH*oNh^XLKFM%3PPRiI<9t`?_FYt69`rc>3{zr>jns
z+$`>W|931^d@deZxBjUQ(mNL%b$CAAvg`Qd_|gej|17DX=$9YXtf`yP9x3!utsgF1
z@%FXyvac~`C%N^-$F6KX_T%)c`*xR(Igf4pYu&GtE^aHq=4<ah>o{As^S+ER?yBR!
wrsn=9f7-us?4eo4=`WtSk=|3XtD<Mg+UZwdB@^wH?LRgauBi_ls9w?W4<q=dxBvhE

delta 348
zcmV-i0i*uk5B~y?7!(8p00013M{Ml?000|MOjJbx005CJ7=KI{1g-!800DGTPE!Ct
z=GbNc009z7L_t(Y$EDTn4a6V_24GiUg|6TV?+UKK3SFUNABf+%M2!3}Rh|Z}dTk&I
zA<$DpXLD>p1WBX@=p0DkX@U|h#siocLzQPX9xxM01L$N6SkjHisOj7|c|poaBPDXx
zCiY-h9j;OnZhtUUU<J_&fNo+R$PFkZ@Fc8Ps$Fh@RKU_CPc`;n%@@E2;BQ)M;1Y1z
ztTO;Tev5E|x2}yfOk4p@e!%bdRnWz&58DCq!e^i#m~z`KkkvilG;|eF2b)UX2bzGD
zsUjb`Js4_Og{Zr3Q{5~Fs70c6r`K7Ozup$02uXu0U_JD=m<vo{E$iDjI00?}VM&+A
ub^<V`BkYH|L9Y?ZXTZKEM*u_m9Q*(>*CNLgAVRhP0000<MNUMnLSTaYoQiY+

diff --git a/img/sex/close/chest/7.png b/img/sex/close/chest/7.png
index d778b6c4eac26f8afc6b4e7946241131718856dd..f2bff3db34971d3951fe5f0e77424f7ca5aba2bb 100644
GIT binary patch
literal 2004
zcmbVNdu-Hn9Pc(a9x{=j5jP06Tc!fNzOKD%vjexg$sKa@GA`Z>iuBrFZ)JCFX?t7`
z{9`}}41<XehygUjS0EUCfG<FWKrp@nDxi=^)DT^81R;nJ9`o1R?cB_G#3pTj{rx__
z&-e3v{J!muwa%;_T{9X%km^V{)CS)Vx%bEl_<Z@prM>V~8=D<(xwd8N+Q;y7J72tb
z<kR!}UOlz$iAyKGzWn=fIKQ$QwIOVj-PSq>=__8o@(qXGNhAEYg&?<&ckeP}{l*Ch
zQh8R5x7+Q}*@C2JJff^8fyc=h5RD*>GaN&dI)RNQK}yvE*qL3QVW=txuml?=qec*P
zsNuyXn6tPwE-mhqco~~99c^?3NRR=xh&q|HW(iIJEAR?%>`oIHT7cM{0j$Y2h_**#
zXizr+%6d3lqP%|8$9pKwOETOvlqM;jApHcz;3OrGoWT0f;)OwLrmP5Up@)mM;8y_a
zux&#ih+Hn`$uS<?Oc4~%Lk^mtX&fSOE3et2gKJjZ07D2^lBpWDs%xmrC?@r+9l)T{
zeit%EiB_|UVS)i89MK>s59zv80LoGcXJpNE!MH3DAPq7=vn`0FN?4;qw{@#SzYcY2
zd58fR+Gw<7V^}SjOv!|0w=9Bg6az9W+KT55K(ql%&zcfwSp;R)x!xE;&;+8bn{i!F
z4<sr!AQ`2h*XRQYRg?9c_28flASBu#fYBt3HR;1?U!3Fx)+<oVRFW1*vL71NWmU-!
zg)&r}q6C%}SZW9qmW(Xg;!VM_Bq+L>5uw9sMoa<1&{7y$3ZoFz)4B-_yXpqdM}ona
zsViz4E?8|do6$&1kfV5x!)XsykQ<E(5zVqiO#+cn0E5BtsH!X|qzG7r7jaSHIb2D4
zc|0j9EUwTDBa<>E`$=|Se@K_IZV9;i`%i<cOOWGVc@#}@ia(jeB?Txr$3Ql}1UQ`X
zE3(Lu6s0iS0NbOc3J;{19?a^hk|87Kqgd8QQ8<$XP#W(gaX*`saIeTvGAB_i&B$)q
z7b-~zs}{_0zIc%4fQ7|TT15-RBZ!iFC<2(|Rs)c+;<P$UJZ{NyaeuA@K++pjNxyYV
zSL~c<f~FLV-A${IxSn`RTy$gUx0cF&O+%#*Q?>s`dNC|ghp43h?63spIzza<s6Q#h
zfAdvX8`QT3;IJ9G!%`Q9AEiDHG)Qg2F1=;fr7Z|j7LA0O;_WLw`Qh8=m!o4UV`S)R
zAF=Je*s|_*_cot-Ve3gd_+&$Eatu#tQ~o;E`DR&H`?AeT%aS!=9@%lF_0XgPiHaq6
z_+G0$_Cex6r4#&Uf;oGC<&U{Fe`fJ*lY<A3B6oG4k6^1`s_K2?LLju<sCuP#)6}ZA
zbCo@hH1GKGt*sNTmhCQ|-*+n4HE-JcYraR=`4u}Ww|A>QC-P$tH$1)c?61f7pPqY>
z*)yW`ZwxPYI#1Urn^&lt#$DJ>{4#Rl=YDk63S|5R?z`j7{&M^BZu;nL<5r#6lYh42
z%EG?#-nx~ECCI_IXLaty%zXQZ9cESUzHchRUtrEV3%VM5Qj@#Zh0AB1>^U;4{;6vl
zCm{`+o|!nMe%=UAP1je?an*+t^;vbpk&4DUe^To2-?RERr)TWmdz_kg7dU?$E%SOB
n*P0(+$w_w~TJ`#S6E7m!xlN<)TR&ZP|DBPR*3h=*`OE$RKNqO=

delta 365
zcmV-z0h0dI5Bvg<7=Hu<00013M{Ml?000|MOjJbx005O%E%LgQ^uwa+mR$JNzWLtF
z`{&yJsjJuC7_R^T00DGTPE!Ct=GbNc009q4L_t(Y$EDQkt;Qe-24GiUg|6_fzzVFu
z3SFUNe`*!cG!f6?N7I(a;4LIdDbdxVd@ZpBpd4&~&Vh*FGJio#s|f&Ag{yKcCIDuV
z(*PU^05y`IC0)jVPJlMjLSzzK;QqQd9wG{+3R-|f0l*_S9ux=6&`G>=C7b0IzymAc
zYHY!pZ$J;gXS&qDKY{kcIszz1wTdH9g)Sln?oaTFGmwRw<y}ua2K0WOj~cgd7(AaK
zkBb0VfxAKZcV-k!dkqKD9!$OC-6*(w7Xdtkv>Ve!-RdpSA?gC(mI%uSKozC$0n$Mh
zIhaxepm)wz$N={q6#y>G!CLViU``9#Lc@UIvt_ky%?AK3{Ri*^^Ex@fmj^Gk00000
LNkvXXu0mjfGf$hS

diff --git a/img/sex/close/chest/8.png b/img/sex/close/chest/8.png
index 9287cff63962d7350007bac18dbf4695767f5e63..8e9f417bc0cb8e35937ad099eca4c34fc46812a9 100644
GIT binary patch
literal 2001
zcmbVNd2AF_9G=}mxmtoY8iE=p(*#kNoq4k}v%6zgj@?REm|DxmwnC(DXWn)Pc4vl}
zDZ8y9igG6e<ctULfJBK&|1gFo8U?&U0twJmA&LZ*Bas3@<%$)2v%6heQ;s;v?99CP
zz3=z^zV~~-UE5GUyK?NLu>?U>#_FPt_&LM9N0;H>9o@_O@Z+I|x$)YYyFc3cJpKEp
zTdsfi#h+ij|J$|&H%=b<>)a1`e03%1VAvR^v3?$Lt9S*xZ}qx^W?hR-5aX)c+e5th
z_C$ghd0C4$JI(T3Nii}$s2U06%VkWACWxBpITI?2kwYd>o2G}UOP}qfNKFk>O@hqI
zW(1|Qx=stt>#UC}or{%_N=<)?tjS53AcGu8<}zvBmU3Y#&nw|~cbK8bJj7WXre?YU
z$!58Mj2IRo1)oSOfDe*^kPnDF>ldey91B7W8)Sf=W`V?tk`N$^7lor)YEo*9K3$B3
zzrs|?aZHI}ve~RJ>-QN}8v{Zi%)v1nM`HwScjykx(Yjqdzz{{YVrizM89M1Q!i3T8
zgek1FkV3{R(du^5CTtj!gC+xftea9Es469#*>0ut!BvGpX_P^_V`D5RVa=4`7<S6I
z4RvXHNC0fDESF*ot0j{ug|MC4r8teEA;Y5Wc!!CYMr0f9mV#=RVwu%$Hl`G@5OfSH
zZW!r-jcOQ>OmaADa!Qk?t47v-e9!_Eg$@c+9E-hX12h+ivmr^~CE%aRauUlHpt7NA
z$&R5=KZpY$37o`(Ay8a0Ds<po!Kxx94J!k2!deElA;#3(D6(Xu6fx3<g#)|l29L)g
zkp|01YH2)SH_o0##%d!X2#F%i`9NN-EK4!ncA&1HSTsywb9|bnN&-+6$c03j7gUxG
zsJuW2l_W>2NZ=9YPX-_m2i8XorQIz7cYWbBsD^?${*}iDLQvr`5lD!D4kA84Lk<bF
z5KQt3o)bC170knGp0zZ5AYpnitE)=IjEa&-3Os<cB7h*xLY}9gABJe2Rf8PwPl|pK
zx@DiQB&klb@g8>+57Ioer1+NB$b9igP;n1Mm{QzoKq^%n)`s!po+205XHy81-l0kg
z(QPB?WTAy-wqft?T7}H*#M^M`ou%K~Ru(i3l|D?>{vYW@Ta*;k+Ys)s4CN-nxV@;b
zDa?QOD?c}=Zw<h4Gjv}|T^N6q`Z&@twS~L%k(MiG2*UGBEIKpZyz-l4M>oAjR*Y=e
z7`<_eIk}1-_w}idBdJT9cb@KLKjc?znz&(pqT-Jh;+H4aWLwuYm-kF1_ytwYs>?s^
zYw@-QtcPD_#}jCU3AR*B7<H=V(&$I$Ea_a`b-^=*?s-fAYtX()i{6RwW13n|5RZV3
zn*ziusjV%u!9`+%r*Hl-f}W;K>h@fFuw0&2cKA$~l&^cQmZ=ZSsakaZ_T@KzJlB67
zzCh#_U1&NKA9s+Tk3Uzn&MfOXsDF8L`KsgPX4Ut6&w;b=oh+{r_AB=-^GG`uzTw%m
zepb*MI$SpQbiX{~+n2o3&Xv914aTlmYt6gfof{Um92&oG&Bn^sWuNzXa=#|FAB**^
zy;!}s;=tM6%(kDejNP%B?3vtuZR?(j2}h0H=Pz9S<canXr@0U4$z4=`clC&cGnm(V
iYrFT1IuiIBo*ET;ar*ufGVT6V6S3O*XxFUPSN{R4{iP!S

delta 368
zcmV-$0gwLC5B~y?7=Hu<00013M{Ml?000|MOjJbx005O%E%LgQ>Xuyi)xPw@qWRv;
z`{&yJsjHmQdgK5A00DGTPE!Ct=GbNc009z7L_t(Y$EDTn5yKz|24GiUg{;5|tiTGa
zkQFj^C4Ql?QCffGsyuhEjYdNV0glojOxrtv*sucl0TA&~1%Dts%o>OYo0MZTYd{@|
zWoEWy4WyFz)N<?-g9k_^xe@hZ3EHUng+^?GE<qH~HehVE_5cS!mQJL(LYt)v)Cilg
z1VcRoaR8c?HG_A7%z=Datare=R1e_+#5SXdEpVC)8HEePj5f<t(u%u4pK<C7-vn}A
z*JPG41b4wT1!+-Se*zuf1nqCq0Kyv31K4j7c7PRnCf@tT1JDRcyEcn_0xW@4agW~}
zVr__N%PoN*-v>CeNd0n3bq{EtOPM%b4#Q#o2FhEZd<~@g#0A)te*qtpIy32feLD#N
O0000<MNUMnLSTZ3cbqu@

diff --git a/img/sex/close/chest/9.png b/img/sex/close/chest/9.png
index a2ce2426a79c4b4ec9fa808d366a6c745cf9bf0e..cf7cc1f1884d9a42766f3af42c1ca5b3b002fb2f 100644
GIT binary patch
literal 1997
zcmbVNTWr%-7(Q*-)E3GJ)qugI8S?@R$Co5d?2+}76dH|`D2<@okl@5VN!%v3vE3%+
zrncLFF<#KPX|RjBE1I-DYy);}1=<sPgAQp_z{Iv9geahGz(BC$G|k$n3^Yr&kI(te
z_kaK8{C+jsyu7+<ZWREaI@}bB;dh;VS2*zV%_BXR@oQdmMZEFup^x{hqOO0n`{v+x
zzaQ_rw0F&|vp?J({t3@-t0pWAtF&UxE#O}9@|7PrWl!o&&zk^Dt+DSi@W#P806cO{
ziMLv<krkq(WnEC#63CU$>KF~c(%QTZrFLWy36xUQ06Fq?KS?NZfL!g3FcCe7(n`|?
z1GQ{uj!PTbB|#=@pCy*&MNE)I79{f7jB1Mc09oJ_@z|cGNumI;+5=?0ZIEb<M2Vng
zAj0e7DT(#?37_C%c@N{}mk=Do3N+)VSvSS7BEySbA5pwWY|W69Vl1?*XbXP@$h2kY
zB2DLVIaki@(u@?%3IgWfXpW;Wf-<{Q3+5@+TrkEELZ)OWx}|6;VKc&n)?o!mtaQ|c
ztX`s3&0?5v!00^GY1YNqE){^XRKn>UMy6m~mS~hgS)^Jf#<C@>p4KeQOl$X{E-g<m
zfI}OJlx$3@C7UgoFs;T;>_#yllcLRdmyYNdGPMpvLXDkR<^tOrT?`rsTAC5pw9Htd
zqGOT?4tq^3T&<|GmNOTP+kisQLIILvaI6_0#rfilAbLF_>wcQyM1~oKMl@MTc1?u3
z**MD<p!@_VE*TkG@PS}i5|f&dh1g*w3sZ>J)f7pT!YBr{jAmfNwz~22;b1UoXh|i5
z7tGl51|r-T<XM5|DbB?f<VGT5ST!xEN+=u(kT^IlMUh1xgLszXJd_vu1xj{%7)oIM
zEX8_cIqBzQ$osux`$L-4VV8itfAloSnuIz2k;l6s^zuHLVv}-$@<UI8O8ERT<(E00
z5m1unkZ+7_rJ>*h2{YqaZB;U6WReoY@g6V5a)~6xBaci8evYLWNr2D;u|NdvvM*GU
z*rb>^$6dvP)PmL*M;V1E6psic`%nZ($*u+@lf`Lel6X9n<>LNa8e!7^sFG3Zrk1pF
z&_MMm9J>crA$>pbChYug=?|C6QB4!2Pg1r2M|v?VQW~l$ggY!v+Ro5+FB(k>{qKAg
z*2eX%F*t69_OR52@kgnTBNbB{xJy6P_uF~^%9e#g_3_r@-=FT8*-K0VQRfGD?#&+F
zKjqlgq3o$Ei);Q&EPn6I-eX^WJ9YT*tthxMePrXh9Z|>6Rp9d3nMb!>9URzI-c8Hr
z*3NN&V8g;EVinuV^d|!iX9QuWC)*Bo&h1+EQSbay;Pjqz!-41amm6hA8|x~51l>2*
z%suk!P}RUju;n7vJ$sfpXJ6Uo$_8iKx`TJ87|z3>w&&<CYeMFX!GSwhPxQJ2v*Uo0
zH=T%Awslt=dY_zC{`$*K{jEF7?(J={10b~{_s*49vYi8;Dbu30oBBWe!ddssg~u<v
z)Vigjw#B)%Zs*8A&1={C!5>Ga+&sCkX3^%8j_WhbztXW6!Ml|Q)^2+Hc5Id7=8d!T
z`Q0z<xVUSix9`!0y1t?4zR&qfn+N;a08!sGU8wH&K33P(J#Wd{6<e+<>W%7d=QYQ9
Z$2Xrg%-^<BY_)%y;l}3BCk^X*{{{<sqE7$-

delta 364
zcmV-y0h9jC5Bma;7=Hu<00013M{Ml?000|MOjJbx005O%E%LgQ>Xuyi)xPw@qWRv;
z`{&yJsjHmQdgK5A00DGTPE!Ct=GbNc009n3L_t(Y$EDSQ6@(xN08m$Og;rn%R$v8I
za0SOcDN{7>z>9mYXYva>dKp3p@wg*~W&8%Q1T+x;0El!n5q}{*j18EXRFz{kHo$?D
zG!bcH18$@oC0)*u;tt?SY9Nln1btSGKnW)pDzE@_1A?CGhqwWNco5fGV_)SKXeD$F
z6HNIEcmv=nEj7pscn$bVvkXA`%~_Q&fe4<(9w>rm;Q>iKrWRMn9U!Ij0M`_P5AYHs
zDJ?DcfHKT^T4m&UQIZ-ykRPD3{1%jXCs2<$h@68BaLy0y0tXoTD?c?Of3*pqpO@@e
zqmlE4F#!T${rcVmL{gt)8x(QHkfXLUnV{cS)sbE4-VSU)FTn=}MKG7h()8p20000<
KMNUMnLSTZgKb0Z?

diff --git a/img/sex/close/missionary/anuspenetrated.png b/img/sex/close/missionary/anuspenetrated.png
index 281d650d9e59e1c6dafec606da25b8fd46236add..21a2f656da5b649a79fcd1f0b42f03df91e30b77 100644
GIT binary patch
delta 884
zcmV-)1B?8t1)~R$7&!<70000ahER<F001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK0Cg__
z0P0@=06Lcd02gq46}kZc001YEB`AOY|NroULJI%@01b3fPE!B?00030|NsC0|NsA~
zE_giv00Qz!L_t(|ob8%nTZ1qRgr^8N`2YV`x-O%ImL_RkK<_^IL7!YN_X>{9+wF4d
zUuxmgCeyzX0GO)p0l-uMV5+`v1)vSYe<uJiRo?@EsQ{q4WCgSX(C!a;-MoLf0Kiz1
z1-A9;mv40&0|51@0Pv8cfPMV{P%Qv3m85`F{o3W*KqRM{d1C>9v1|aex{Z-n&AhPy
zz*Ld~()DYWZv!#(($5<U0F3qf0ER_nCtdnK@MazWyhX#1s)74vn4iwoUs`@#6rV2j
zNN4BgKY;+CfpR5sL?vwJB_)4q0r+Wm{{B>+#~z_HzrMMR2>|HwHvljU<M_Qui{XAx
zt-)R3zDN(?{t%t6@u2kacO@D0%{>JG#sGZ%PA<wcNv*;XQa6M0bS(fXQ3oJIxKGak
zpl$9c05AqX2*#(Jk>rw!OQ1=90r~p*0Q~uS0P$^9mO<a#O8{UFAe4Wz$-g|yuMn=m
zUtpeV0L%~3=`{dy>A5e3bIq|H<N)Aw0Opw<amo<l68st#0CXOu^ilw8bN;6Qa8&?n
z99{|G5^))&>3RTOH30JI<p8KTx|x;cZvb#A0Mnvz4C6>jkS}l+0Qp;4DMPL~x|x;c
zZvbEj;Pcacb%U$PG{t`xWNx-w^zjj|;Mb5WaP($0cllNTQt9*aUH7$!GNhVgoDTrT
z0KBF^?olGXD32z)E-oQe#qrs70Q`fGKV9chN`Ex(wqM)ZHwOS$0Wb_?;TMW8N=XTF
z07oCmbHY>RJjlBA$MX(Bt~ve=0ALM(7NIb)k)#AUfc!sY@xy=n)3qMQ>3Q?1<^bSY
z0JdRPEAHev_ig|_ca29rJ^z<r+Z+H~5kSgHKKFhAM?Q7wB^l!80N|<swpQ{v$pT09
zzY{<%y|h4TPCLJ`0RSTap_P2@ssK{yH3h~m3FPyE4FDJdAS>yNY=Kq)+CY@&FT3dG
zp8^150Ch(L001ytAAr<ATEN)=)C1i5=;i|>?ZE&500000eg6Zl6scJn%FBiT0000<
KMNUMnLSTYin23V_

delta 634
zcmV-=0)_pf2df2;7!3pi0002tcD;-M001PBQ7C`N5#?wA000GaQchC<00000!fOVx
z0006pNkl<ZXx{DF;dz4~5C&jZ$O>J-6|w>=+zPjXE3g79uv|qjin%+84QYGAuRaBi
z?=?hBG7PPn39US)+4`3Um=5?0`AvDyZwJ*1Fdgu*q(1;uz0Et|)B>gkP<Ny4fI@vk
z|F?ewJ_Mixm?}W!jkW_?0cwxB4k+X|^nZ)-s@~?!AGa?EfR_NxANKww03I2rhp`)g
zkpP&cvm;>lcg;bk5dZ*EH*WpZ0*EpI5kvsW7bq7h1>iJE28)k1s0FMQ0oK|uogZP7
zaNr*HroshQ0GQ^6=(tfa!nO}y284(LAPRp4fD}##0K<?lh<>S3gwRO_Fh#&TUj(F0
z%2W`;DFMXh0FfG%BH(&r9lE^?@ZN{%GGJexx)JZg5eJ<ffJcguBG~oBIs*_!9LsY6
zpN>R@0Neme9U?+p!kz@oO$KD;SwOts8ifFt@;i)m=m_ir?*L@mi~_9T!amam_yT|D
z;t=Pb0poZ>pBe)|88DX?0Z-+#{_%d#!x?>m`2&Mn8en=Y^WG6+ge}Ekb^#El3xH$!
zynj4|QwdlE0BapjN8kVh$bcbKMt%ew%OCp3ES%8^SU%QoFC`s;1q=nias|XqmX{~`
zw{U6!YZ)W~aTnofz>t6URVYthf;D2CX23Rz?K=%9egU7o(WP*@0qZEXk6ysM0kAJG
z?Qx?W5J$0nEdjd&Q3!VdK=yM66XFD*f>`x4>?Ht&*&WaxV5G?n0YzX3bikVc-<e0I
Upz6Pi0{{R307*qoM6N<$g17Dg+W-In

diff --git a/img/sex/closeRed/chest/0.png b/img/sex/closeRed/chest/0.png
index 991fd1fffdfab19fee0c27d7399e1eeb8ea6a346..0e0693b126df08f37ce53dedbe335989fe561cd6 100644
GIT binary patch
delta 389
zcmV;00eb%00<8m(7#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00ApWL_t(oh27WD8iF7U22c@@-v5bnEMjv5E*RR^
ze`Uo^4h?B@Ia`i%yGZ%0nQ6eE3Bi35qXY(o34jR!hF=MIhqk#6IC8KV*~q>(88e`V
zU~$M1$TR>YSS%5LJTAp`vKe6j#8?X{!b4kSgbAPz)!)OfBg6ur-2faR;JqCXLX2>c
zG^VyekDRjw@U{g+KlLjBHx}Gf-)S@eumK&AEr=$}fL=KVpox0{`QrjWOybP|E^ame
zE|mpHNdq{M5=@{qP>1LQf1MIp+@}G!AQU)`*O@*5Bgm6vX&L}x1aQI@Xq{%i3HD(5
z8=#+G1IS~=0O&90rGNrtF?j?in>|ZlOsoZ9d3+ui5o>`_6LQ<R254=u>h`)K_JG!e
jXW@T0RsogpB1?fc{?tGP#7_@y00000NkvXXu0mjfh?|=}

delta 306
zcmV-20nPrc1KI+R7zqRe00013M{MnpE**dP`1rjH{>ojnp8x;=0d!JMQvg8b*k%9#
z0PRUcK~zY`z18gvgdhwCU{>e~uFw_U6<DDwumWQrS_G<>P|myS5B%tpybT%+L=-}x
z?X3OE)D$qI7>W(hIw*y$35sNm3y27Yl+73yu%xsBG%^JurQJwb_x3S3c|kmyN@{;;
zY!wbL+#Sy1Dg3}B$PU;C5P@#EFXRPfgCoQUot2<d&Ou4QWk?w_TtMCd`53f^Mt#Un
z0ek=o((tJCn3&w)xRY)fN#Fb_;0h$?3&=V60N((w0kbzYgZ>HRM}VCG_r3z)A%Gv?
zDWER^JOtN__B~wzu<h~|^AhM8Tz?(|`af9$7~0F=1sOdcLBA4%<NyEw07*qoM6N<$
Eg1n}IQUCw|

diff --git a/img/sex/closeRed/chest/0_job.png b/img/sex/closeRed/chest/0_job.png
index fea23a48910a83141546db05933280b77c8785b6..f777c0a6cb120bb574038c6740ac7aed52108ee8 100644
GIT binary patch
literal 657
zcmeAS@N?(olHy`uVBq!ia0y~yU~B-g9XObQq)J;rFOXs^4sv&5Sa(k5C6FT>;1l8s
zq>C9C)-y0XV_-PK$T*XM;Xe?iJYL0|9y~>+2q?{2666=m@E;1ynPy*MU|{0+ba4!+
znDh4b>%3+I5#|RMSZ@5b|Hz@KY`);>mQO0b|0L<o&(7?UP%S=els7lA!esN_a+^<P
z{Q3vp&Hb*(b6)be*#j-7d(R%S-uNptL9L~tN>(u5^WmraA3rd?`6p?xcCuLT?g?`J
zk0mN+w~HryulIgoq4IEppR`i`XP}CEzQKobJ*@71_-6Rg_UHM^3dXYc#|qmkJuK~J
z8^MgdV88W$)UO>j5Pq%jh1s@7tQGY!4*zUH?wH>2!#zkpE#B?tMT0A>Pjuzt8t(3{
zxGm#+t3meJ^eGk56XV^U<bp-FH2h*L4Y1M^pSb7jVeSpp<t3b!TpisjbQS8a1NpyC
zH+(z2RANKC3q<{WE)V|ePwXE8Jy$DeaDH!tQPRA}tV`k@{?&pkzTWV6N}bEk&o<9z
zYeO`IGhY6(`AnsQ&Eb>vCqM>%mFHQ<bgIM10USbmZ~M*iTUKX&KSBlUdyt#J&R~nz
zhq^$T@#r?C%Eh3d(r1}sE_C!TOXX$|FQ2U?L0e&c`~myV?`neYmNr0q01Pm&Q{1z*
zF?|vPF=Owjl=Pj?SAlss^b61O<L9D1);IhCyLxx`32|Z1x)}Bow{7+?>|QT6G5^_A
ircd8(_b_b#&#L#L?8np#>&k%Xg~8L+&t;ucLK6TBdN3{k

delta 475
zcmbQp+Qc$Jf|G@rfq~&++1{Rsdb0ID@15Dp^UvVqr3|1TV@Z%-FoVOh8)-oHR8JSj
zkc@k8XWiv(HsEQAJgB|FDeMDRq@wl)ret#m4$ielntR_VnezYr?RTxbC@^~E<P#>o
zM)T9FugRA2i5rM>X#G4QHQ}H|%z-!s`MKFni@rz##Xo3F2)dN!T|7PUc>!a8JyWep
za_Cw?um%sw>mK{=eyDqRLPAC_K~JE(!sXP>?PY2=EP+NWsN7m9a-PMyoqLDq3$rQP
z93}{YOm_Hss^zuYImRa-9SVk7uY`_oRjP_neFNf8Fu%g`s_RuB$biKTzeGK*Gi33J
z7w8A<H#u22aYONr1NGgkUlJME+qo@7Bi1>1>Nw6~+#{p+ARwWBsppj6u5Awr7}qmp
z#^yJc$~GNlJ;Qn^T%m*!?AVNHMYkvN9DK<1pDBZ}pXp^HgK0bWo^XW|0zm!o3u*$U
z%;)|hqxT_<u~x$2@I$6&OuqyYo)<LMGj3_v+hE6|0Q7z_qx(haeYF8VmozvtzAgMG
zD!YsE4#?#NZ#Aau-zf86{a0Q8#3GPv?uYeYsVDN2Sc)_MZC3jUj4%dIS3j3^P6<r_
DwD-i?

diff --git a/img/sex/closeRed/chest/0_job_nip.png b/img/sex/closeRed/chest/0_job_nip.png
index 63ae35d29c27f87d542043976a6c904515806162..3091a57de7f4eb9dc578adb3b32c72e451443602 100644
GIT binary patch
delta 181
zcmbQqc$9I1L_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EKyI|Bi(^Q|oVVvT3Nk42Fgq^zzi2*}hs+H3-5bv@HUuhwfqBO1
zZ{6Zw-)3L(UEIgxJ&3-2>m2_%alKzr_w5w+=F3mGx1HbPJtIuRgZp;V>KPvv2Hdm+
O33<BuxvX<aXaWEQ2R^6(

delta 137
zcmX@gIFoULL_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-m}
zou`XqNW|f{XBUbxDDt=*lsFUW-kGt=rkSzXlPCX}%IZ2628IdC<^8{{<KJ>){+n3&
mj-Bt!v$h?uWnehKT-Q;oe$(QhI6KfJ22WQ%mvv4|2~7Yx`Y*Wv

diff --git a/img/sex/closeRed/chest/0_nip.png b/img/sex/closeRed/chest/0_nip.png
index 1a1351aedcf918fa8d613eef7a69fc328f13cc43..886528dbdd3f8badd2d1985160efd7f865b5babd 100644
GIT binary patch
delta 121
zcmd1pW}F~V%)!jSz%X}v;~OBwSRCZ;#IWw1%u67LEx;$l6-cjQPVX!}<_Kgll?3?(
zGyIR9sI(QxQ}uLl42fucduAgq0|N_#<G1)(vLa6JUY&PmV33)R8)75Da9|PBX9Whu
TvWn0LKn)C@u6{1-oD!M<VK^kr

delta 91
zcmeBX%$*<+%E-*Xz%XI?<GDbJEx;$l6-fVExmxAVtgAp4V@Z%-FoVOh8)-m}sHcl#
qh{pNk1PN9ZW@&|I>IWng85pz*8Fk-n%)1X%z~JfX=d#Wzp$P!Hmm0SK

diff --git a/img/sex/closeRed/chest/1.png b/img/sex/closeRed/chest/1.png
index 6288716e25c9a733d180a01fbed25974be55fd7d..ccfc98382f79d000d70782a9bd7e683ec4e20506 100644
GIT binary patch
delta 399
zcmV;A0dW510=EN@7#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00A{gL_t(og~iw10>U5&1>l^Td;ceHNJ|jZi-B>q
zmVE8($Jr~?desWy5Oseytj9pSDy8tPoF%XzOaQEuV0cf!9vagRc-O)(GRScZ88cvp
zU~{S^kjDVDV6#MjaQkj<Cz}xlK+dg^BD`o+MwkHlP<<c%93dQlaRAstAVxbNrJUg+
zX-tbjw?eQ5@U{g+KlC1e8w+l#-)S@eFn|uo2qJ_TFl*-kgxCwnhYOm;N!$wHrL+QY
zs=R?xG=LK@#vW)xN;$8Zhk!BUX?zI4V?lxQTmv}94gg|q1#p728vvujoQGg97FR%<
z(!2nzxu4eC=N$mQbUX@qtr!6F>Ac7A#%BwR%>XRF?144m3&8aFe_%!U0;>>m+35p}
tmRN0h-4J^~3lUlIzZ+gaBcdo*-~&`*Kn(>}dmI1&002ovPDHLkV1m;OsdE4T

delta 317
zcmV-D0mA;b1LXpc7zqRe00013M{MnpE**dQ-psuW{xHeXXaE2J0d!JMQvg8b*k%9#
z0QgBnK~zY`t<~EN!ypU=P*(5?S-~sZ6<EP5WCg~q34~x;2}8<99{5O?03v~iLI`x+
zEx(yI1<X)Gu>o2K+Hf>Mk*sk65kZ%77~=w#Xc<5wQy`+{M)aD?*TBgO;#Dl9wi16^
zg#&cG-BY}UAD9HmfPDZFcnm)m@&cXU2r;6Jl~6`G2bzFkkkV(kfcyfo4cekH;Uy3!
zKmljBRONmyfUD<BX~;NJS<M;X3ep$Q9v|Q@z&8jkVCTkU&=%l5FibO7vjOS{));nz
zVawl)^Evhk$O6DyKz{&u3C4_eo~|hX*s|_oUII@B*WW<-pDY1%<z?^z+c+SF5IJFM
P00000NkvXXu0mjfWkiCg

diff --git a/img/sex/closeRed/chest/10.png b/img/sex/closeRed/chest/10.png
index ab9a9708a658e02edda968f3d543d103abaf024a..61804ec24234b567a2abab237c244a1f9a75a5ef 100644
GIT binary patch
delta 455
zcmV;&0XY8t0@VYM7=H)@0001;w}I>c0004VQb$4nuFf3k0000RP)t-s0001U006H5
z0OkMy!~p@B009300RLp;ssm?JlpJyZ000SeQchC<|NsC0|NsC0Hv*f~0003~Nkl<Z
zScS#ci>`wp3<hAaAin<-A4^4UEpw+O`;!?X@QoTTxNRxU?SDg@+ulb3xH|wN@QP3a
z{z?egy(jPp;j4ioB?P{ZegD8102m3O!68LJ41nVp5!%m#{T*yu17K>TjjzHGYJls?
z9|K?sQ$Q{N_XzOb8VCV^8^-N9w*mkNfuDL0;DyDU#$~`*f>4ASm=AA(T!bya-$2~p
zTts&g)xi7dQ-8j?nN&c2kbNYU0h!=iDq<l(gw*m7O98xfrAPfk7y&W90b(ru@C4fd
zG1g6Upe9lgCO|tm87Tc|n~E?3=-_!}4%EGIdlg{_oaZ+H{UN|F0qSoFj6pyqaClR~
zKLL4)G<;S>x|Gzw?2%D^((vm-QUkca;9jC-iJkZRK0x<FO$~TYM7yM}m-zjWZrQB{
xumOoW993HAljM1^7y$j`<YMU4Yipwg{s3&eL+O0Dgq8pR002ovPDHLkV1m6m!hrw)

delta 367
zcmV-#0g(RH1O5V#7=Hu<00013M{Ml?000|MOjJbx0046U0IvW5nE(Lh006`R0sjC1
z`{&xd4E}c)$rk_s00DGTPE!Ct=GbNc009w6L_t(Y$EDSQk;EVf06<%yg|t8mv_K2A
zU<)bxQDa2UKk%Q-WDM*DGx1_dDZ$kP(l)*W(7+eK9{>?wuYUl9590$7VbkSWjSpxd
zT4rWTd>}8;b1CaJF`NK-$P+}faKXr$5gHK$QwJ%4!hmtq#t9ApvP`1Q6~-)&z}v$1
zaKTc4fE)nYl}itf0@(xk<z+d5?aJA;a6u8WiZh@>R&fZ(iuT4MAb)~fbA&OFbKZa^
zAOvIsYA)9v5on;p``$cenLPx-y$AY3{3p<S5SYiD#NAtb1GLoV9uxrc3aN($-~${9
z;`S9DYrm{H7ZA2I(X$csLI0w=fK{{@s$7-5t^RR*(C;_(;jy83;0JChKix-Oq)Gq)
N002ovPDHLkV1kt9m&pJC

diff --git a/img/sex/closeRed/chest/10_job.png b/img/sex/closeRed/chest/10_job.png
index 2799ef5e8a6bcf206bdc31577c026dc48e5303dc..6188d130347d9b56c6dff2e73d31b076a81a68e7 100644
GIT binary patch
delta 639
zcmV-_0)YMf1EK|x7#0Wv0000ahER<F0004VQb$4nuFf3kks%s?|77E;17|zjA}Rm?
z00?waPE!E?|NsC0|Nqs>R5Abn0whU9K~#90?VHhZgdhw>g%$Sy|G1^rg+Nf+sDa_$
zN8w~4hq^PmT^0mE5ClOG1VIo4K@bE%kf~w}cuih?0h9CQC*ZYs^##n%FV?n}c)h@1
z&#NzBa^Bi?HKwh91XlpOj8|X4?EL2sC=HK?k+OuGj~h7NgfY%>>mQqkfF1>Kg|@5C
z<t@B}uWjI-1E9-8K(7L5nRqp{FfDTz&n^F{1Mnmd0sRUvW?i>A^lQesb&X~2<ICmm
zTX^CCJjFvm&jLaVL-MO>3-9E055O}#1oSN+Om>dD-X@@bg)arATR0auHV*-P3kW6n
z2JR)~JU5=sI}<oI4*|UkI4co(?~i%!(-|et=l%nr%R@jv0%Q&Jo{sZ;oN>LtF?k5+
zMZgseJm%?)s|AkALqIPA{@TF(<pTW@^8Wpu8c%0jD{xdE0{RiKO=)kSwI%<4pYd@9
z$4dl`$wPpDz5u>GwE|@WrF=SjJ{|(}1*DHl^8x|iQ(M5%<Jgjqxk}*JJOpS9IC`KO
z;N_G2#oAs##>)kc%|k#B0_u-Um!;M~`ckfirxjBEsRNK!xat7Oc?i%Ju(dEWktT0n
zC=ti#kCP<){{+(4`fYq#;Xl0e^LZWu^aX?>TNBe><ckjltbP54j>vd!3pIuN_?f~U
z_&QB_aRVVhEI>Qk7U&I(SIFH0$LH0f-2iRAgXFic+ARJS*vf~06_xPP&#&|9fdB-V
ZEnlsmVc~*gh&TWM002ovPDHLkV1g+VCn*2`

delta 473
zcmV;~0Ve*U1^ok%7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0h38YK~!ko?U?PYh9C?^S)nVi0xNWduD}Yee|;4c@B^jc8k#=83<vc&1QXR5jYgx<
zXfzs)=F`C7{PO~A4lp$TyZ~Fkp3QLM@XrgdIl{>dHw^#00AB!N5)R-Vb3D+Qllgxy
zE=gdYG#`?C%^Meh$z=(^*6-KQz2>|HXyd{J0OyhL)DXJYoVfrkT$%tNVmw?MzT?aV
zXyD=m2x&idPdMgxI0$y;;shWq_?uDXl;NXbXD&~moUw3UaPM=@SpX&%B2X#ly)U_c
zCD@V65U3X{IOM!`eorn#;Hn_(50QVLrj&<)hk`x15P_?LcH>jYr<~slcH{yCs8X=T
zp9yy30t7IdK#1!b>vn<sb#~)Ro(Oj4;|t{PtAxvETKsCWbzT+h%q0k9FQ_Ih7{2L_
zJWN2>x&ZiifvS9bfw>`4NbF~pk@(-@p5F-4<pQh|$hDrIZ~+3wS`0DU^{qv7@!wsI
z?{}c0U}?zb84g^405>*nvD9$ig59|a7+dbJc_`U}XWUeH?fi_ZfTlTrJ7qu~laF0;
P00000NkvXXu0mjfiq72Z

diff --git a/img/sex/closeRed/chest/10_job_nip.png b/img/sex/closeRed/chest/10_job_nip.png
index 9bbaf91e68e8d13907ea3e4f313434337c1e9eb5..8302d294d2ad169ec207f84416d7db67f37c986e 100644
GIT binary patch
literal 250
zcmeAS@N?(olHy`uVBq!ia0y~yU~B-g9XObQq)J;rFOXs^4sv&5Sa(k5C6L1z;1l8s
zr2nTpUd5dL_%zc^Acwgm$S;`T|9_W&Yl=Yb1Wy;okcv5PFFNuy8}P6=O!{xXOXSGb
zX%Q;gCC|FV-S6dsOoxMp!xC4&XEk*&Io)JDzJf2tcM0pddEpNE|2mn~{5`&}2eQi<
zUox)m+_~F);=6d;^$qWs&Q1Ky{%6+aQ~&276g=Hr^PBmf?fm}=S85yH?P1!*4Ys0U
YA%AE#OQv@5hY}Fq)78&qol`;+09+|qb^rhX

delta 179
zcmeyxc$jg5L_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-mJ
zhNp{TNW|f{XBYAvP~d5KIBS-zEZgSg&Y!19%y^MCYc03;zw-y4PMXI7RLhW%zU$tn
z>5SDI&V{eO?_T`xz}p9*KWa^$^WSJ*R9koM+1HD6>~#|OPi-v9&yzp<llj|&+dqFZ
fX8&hoIN;3u=wtN5SC$K-K?Zrc`njxgN@xNATr^KQ

diff --git a/img/sex/closeRed/chest/10_nip.png b/img/sex/closeRed/chest/10_nip.png
index ec20d4ee6a2e1d8d5eec5c12ddf8a5e993c005f8..e0fb71f3d74fd5a2a069ed9f73e1c3410c75e7f3 100644
GIT binary patch
delta 171
zcmbQmxSMf;L_G&H0|Ud{?Tv4M6k~CayA#8@b22Z19L@lr5LY1mKjrZ%=Jdy>nQj6(
z%q2m7!3_WZy98WQ1abpCT^vIqTHl@z<YEvIa1Av69dGh<^2HaLmu%-(t((Hcz|fFB
z^J&;aKb{%7w`R_jiTIbdOZr;T0{N=RCs{ZxAM6uWdBJ~=m#5ltgZG{~1%{fXOunHE
VTUWf2+YL0G!PC{xWt~$(6964NKN$c3

delta 138
zcmdnZIE!(DL_HHT0|Uc#_L;swiZj3`#1%;YetzrU%GK*OBpLxZj3q&S!3+-1ZlnP@
z_MR?|Ar_~T6C_v{Cp=)(o+H}jtYE^RC(sbvAgXsj>Ofa$Lu0Avp;HWNm|{Gb)^Kxh
mHr$k8I?<5LsMx5;%TVplTkVnX=^@Z422WQ%mvzie2~7aOR4cgv

diff --git a/img/sex/closeRed/chest/11.png b/img/sex/closeRed/chest/11.png
index 4730de37d422c4672b7e48d5add7ad66ae8af56a..06dd6bf65fd98b3f54553a9abbad83f933d543a8 100644
GIT binary patch
delta 437
zcmV;m0ZRV)0>cB47=H)@0001;w}I>c0004VQb$4nuFf3k0000RP)t-s0001U006H5
z0OkMy!~p@B009300RLp;ssm?JlpJyZ000SeQchC<|NsC0|NsC0Hv*f~0003&Nkl<Z
zScSdU0S<#83<XdTD&GIZvsMtK6_yr%GD8I3tW$@}a>lu}iGOp;cocxU0?-0Ogc|Ti
z!jYE1J%rB&wlhd@g{*6bF#s?ULX$(FB3Z-$*tQm-cAD(3VBZ`7QzCVI5r$9$+)#cW
z085wxask*Pz<X;T1ORRt*K%$K01yIy=uZGIEao&$1KJXVBGkb9^cqM-*aG|w#7#~`
zJWiq-7(aZ<Uw=1~3P=yKE-?*A1m9B-69FQmo=lhkG4jLk)|H5SK^p+^%m`4Ay9fi|
z+3^mPBLS=cDeXy20Bz4AJ_bq(x3)lx`;k$Aa-2p(VBh}(@C&~HWP-+90&V(0Rl+0y
zKXU)jmDmB~pNXb-A8Tqr>Mo~qWAb844d5c{ex)cE_Aa!&nP>m?SXTqM)Fq@&8dkP2
f=_N4#wP}GLwO~T!;Cj$*00000NkvXXu0mjfJHfBS

delta 362
zcmV-w0hRv41Nj1w7=Hu<00013M{Ml?000|MOjJbx0046U0IvW5nE(Lh006`R0sjC1
z`{&xd4E}c)$rk_s00DGTPE!Ct=GbNc009h1L_t(Y$DP&DwZk9?08m$8g|5H~tiTGa
z;0hW0iQ0(9J}`Ww3EXoqi47^G1fOp}+Q$C?O5hFP1t4O+1%Dtsj1NSFO_$GVd_WT^
zWiCD81jtRwQOo6;7*2q6(t~IgE*M#JhDHRz)Ik(b7%-07IKTlwmPxd=!dT@IxLepB
zE?DXv$N`{TS$l94$R5a#m*oJqJ7?Fz1uA3}XP^jKMF3=bo0F(d+Xp%4C+Im9K9D_V
zNeqGMWqlW^AY<1aZ$VRK>jgo+t{teWjDhP1$kz)niINWjbDImmb3oI-dH1MSKui6x
z>0Ds1TYY5ehs*`oCP<qBIwR|knF%gnETjiDKzgpz5mEsB0kSYn&pLoJg8%>k07*qo
IM6N<$f-bI)jQ{`u

diff --git a/img/sex/closeRed/chest/11_job.png b/img/sex/closeRed/chest/11_job.png
index 257031346ca5d2fa680ac94e98a17ba8f072a207..2a84672dfd3b3c98c7b5f59651ef59db49118f9e 100644
GIT binary patch
delta 661
zcmV;G0&4xM1h@r|7#0Wv0000ahER<F0004VQb$4nuFf3kks%s?|77E;17|zjA}Rm?
z00?waPE!E?|NsC0|Nqs>R5Abn0y;@VK~#90?VIg#gCGz^g{XP|H*P88@U^I9sh14*
z{*0W3?m;@Hc3BvPVHk#C7=~dOhG7_nVWx^P<dHml0h9CQFXT}?d;zobi?znwEAo1g
z@6W>*Fgb7Sx*BtTuY^>9ypD%2V0Jz$a8|;YZ7WNV*YWTL%+41D>P6fYS0XK9?Y8B-
zRKb7l`M839{#IW5^Y`T`0571WfiCNsHn60RabZ+E$F{{4^z*mzDUIhT0571{zFGt0
zBGL_5)+m=4SE$q1^Pll@1MY7i9Urg$jHdvs0Br;18!#PzDUYyrbb*iX6aW{XZD9Ch
z-=%TxS8f;)#`s0V^UHiZf6Vt0h~_B(FQAV5#0@M<1b*M+_Q-rZ#y^sL&X)q^Tx}pM
zPXQwdXgfmk2BueKzC1)e=cV~u)}L=63{L^$2xvV5$_C1*9bvusr;orsJOzv+K!1ez
z>+j#x`FKQsZ~oaMun$iGBMFexc7(j&R}Bm!{)5-9|7o5AMiZbtLeK(`N8l$s1&k)3
zy#ZH`;`LiFe~@YAN8A9dJO$tdqz!B-;2U`Mb*#jP-1{=EO&|pnp@0hkx&~gi(D6PJ
zj~9sLDF7`%+d$vKdId)xf0#}y953mi1!8#$7(sw^u7PJ2Vmhr5UQfgd#Pbw@7NBk5
zQNh*7lfRx9#^f|oAeN^9yZ~(jeFa}5%~E7tt<C>M<No|%1^oo#c?!S_&^AyXq(D5c
vZh$`13;6cj73fAv8|W$izcw&D-zne+`{-p!W#?g500000NkvXXu0mjfr=~Hf

delta 519
zcmV+i0{H#71*-&*7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0l`T`K~!ko?U~_m!ypVsy@FO?1y;}stl$;AejUIVFj&-bL(!pM2~Uvk*}6;WF3YT0
zvu4ejHEY(aSzQYT=iLLaIl$1odjPh8f<lWPhj$Oa<_LujJq+(2;4Oi)1B@PpcMpH?
znn2P5dxvjP1}+U?xo+EE<J9LjasdM6fB@(NLR4s%+z#U!$o&<L_ZO&{3lNC&#Q|N*
zc?UyBIMFrK1pP-OoVq{+#{wT-fC?DhLBAL+sJ8{5@ZklhfcC|Dt{IznUHuVm|C;Z2
zyg`u51qfvMeZbJ6T%0xIZp9Eh2;P5OASRb0P#KXUAY1~58M)=>{_^?A=RyQ(BM<^Y
zen7Z~P5kKyHgF*V<cRF=w=E557h3tl5p3X61n3dj@_<_^Kym8)r(BKzH6mOA-U!yY
z9D!<p{Hr{<h5BnFSmOc&%w2=df6iV78U?37Re%V1Noa7dC?Hpm$;TI<0`7AOO^QE%
zN&5!#f*_Mi5Fi4k4aPrPLidI*$mZh<Pys&;XpTA_?%5S=*-r{Gxc~tw;NGC{sPKdv
zl|KK4aoukZXcA;|0RmJ&vUq}QE<oU~t0cHY7w8H9%?19?0zYrqT@n(f>>mIC002ov
JPDHLkV1l@o<UIfY

diff --git a/img/sex/closeRed/chest/11_job_nip.png b/img/sex/closeRed/chest/11_job_nip.png
index 69c222a0a35f9413ae6cfb73249a2d487954b9fb..23417ebbc01d8541ec540210255f595e88e2c15a 100644
GIT binary patch
delta 255
zcmcb~*v~XUqMn19fq_A#Eua@jF%}28J29*~C-V}>;SBHzaRt)<Qy#BkPJeuw=_ZiF
zToU9L%<%ueOTaZnAa|*!i(^Q|oVQmExsDj{usGcQU;l+QC^q@<TE`zYm)&MNNl&>3
zR0aq8zU-Sf<Lr{3uQeBhynp@mOxmT2KVL-zPWyX&YqOcZ<n?E+6=&zyF|G1X*kjK+
z<^SPJ!XND9`|qnys`<-#r=Vq#xCyJuPu*h?x&?L<pRHfs5K!f`ihG4kqxC1Q6?zZ8
t2nYOSJn}oZfl28qcgTU4tYCZpEaacx$&y(!`@RW?@9FC2vd$@?2>{?TXLA4m

delta 201
zcmeBYy2&^}qMnJFfq@~<%tHrAaR&H=xB}_l&u{%(xq97(L?a-Fu_VYZn8D%MjWi&q
z&eO#)B;xSfNrqev1_CUXmwYTW%dClgwdc|?k$Y}^3)mUcS4B^hjr8FJDrR7KF!N5o
z(Ye>$r|Rr;;`|jRf0_4sLeBm2qCE*^O!-bPxy5fdaR%jGZ(iKD$$H@zSMHXz;@hmw
ztp6F4p#G8NT+5`#teb@^<P~Z;4%KHfG~6#{`rjR&I&}*78j#_hu6{1-oD!M<mT^z3

diff --git a/img/sex/closeRed/chest/11_nip.png b/img/sex/closeRed/chest/11_nip.png
index 0b79d554738a410dd4e6156e194a154b55d79a65..fa716779bdba48fc42771c553a3329448e1ff87a 100644
GIT binary patch
delta 174
zcmbQkxQ}syL_G&H0|Ud{?Tv4M6k~CayA#8@b22Z19L@lr5LY1mKjrZ%=Jdy>nQj6(
z%q2m7!3_WZy98WQ1ad<>T^vIqTHl_H<~m@&!Fn;~`~DYp3IQG(%dStFZ@K@~4Jn|a
zWlQ!l-rY32o+Xa$W_X#xdUm_?HwTPE<tIE!F+Hp9a3tzM)edumH@6!@pH(_CXp}I>
X9A((L_R^AApk4+~S3j3^P6<r_NUcIr

delta 140
zcmdnTIEQh9L_HHT0|Uc#_L;swiZj3`#1%;YetzrU%GK*OBpLxZj3q&S!3+-1ZlnP@
zj-D=#Ar_~T6C_v{H(XO_n81*&F-Nj1wt>-8fnhhpq(a6uEGz|9U8SPCB404YcrdNu
p=HP6&DZ!-iOjkk0po5WNuNQB1R_6C@K*Jb3UHw>H);T3K0RSAbEGqy2

diff --git a/img/sex/closeRed/chest/12.png b/img/sex/closeRed/chest/12.png
index 2635d88d905ae80eb4a296cdba13456c69005fa0..058d6c52a65c795bb68ddfc3408c73f6d4069503 100644
GIT binary patch
delta 439
zcmV;o0Z9J%0>uN67=H)@0001;w}I>c0004VQb$4nuFf3k0000RP)t-s0001U006H5
z0OkMy!~p@B009300RLp;ssm?JlpJyZ000SeQchC<|NsC0|NsC0Hv*f~0003)Nkl<Z
zScS#c(H4Rr3<lr`Ccgg@=UkH^L-B0tf6?&>d@;&`Ph66ggnt0=t%7&Ln$J-jfN2d9
zErK~=8~{uYp}{Fpkt*T<OjC={H4l#eVB0+aMj~~hh(eeFt*d?yKqXv(egSwzK#bl%
zN&wn0?J9&j0DzSAsqX>&Vkygb8_<@}DZ&gK53d0(!WYmVAZ;)gv0FqlFg|@Q;=;3F
z0_caVUE<-V(SHmup%pf`h-Lr_&_Cp-04hSK1>peXJXS=`rKcdwK+dw^sEE4fMwo$m
zYU4$0gadGt{+9^@@E$;=tVK8iInPVR0498adA<VB8!pTEB0&8;0WD`hRl?%{5_bc1
z9P1OO&%zMUpCC=2U-fnmp#SF~k2?EffY@-F0o-Vot}rFMxtC?gY+EfefZKgSO7ISM
h<DsP`gz6}41%6=@MukCgrx5@E002ovPDHLkV1ldywcP*!

delta 361
zcmV-v0ha#71NZ`v7=Hu<00013M{Ml?000|MOjJbx008Cy0K@?Sa{vID006H50RI30
z`QFUE4F1Sa9kKub00DGTPE!Ct=GbNc009e0L_t(Y$EDTn5rZ%Y24GiU1y*1MR&WJY
zU<Jo6`KSqLJQB-~Tn&%+TBGIwKqNj(5fjnjD+VHhbd&QOO@9o)5o@Dm(hiWD*qGXO
z3`jdbDyaqFMF`q#_lrBR2wZ|B0LuWm_1ZuifKi+%*Glawx4<3IXM|wrS0EbzX6=-L
zt3c*JXucK!u%``M#v71?jA9P}cK`YnkRH^G80aKJwTTd@>Tia2A_St(8Ck?&SZ{Ps
z5dQ}>XRHCeu3}k)rWIQQ*Bsc1{3o#aMeuZ^u5ZL^knZ&+upQ2cpS73(7y`h(ez*YK
zt5UY3@77R0rXk?6i{;|dz9;f`ECk3#a&his9_)bX79D{Pchod-_-u=!00000NkvXX
Hu0mjfT|1Tf

diff --git a/img/sex/closeRed/chest/12_job.png b/img/sex/closeRed/chest/12_job.png
index 1a8585d706f0dad05739e56b47f0250f3983ea73..f406d2b5265489b77a668a9e4016bbba4ac4e4b9 100644
GIT binary patch
delta 667
zcmV;M0%ZN61il537#0Wv0000ahER<F0004VQb$4nuFf3kks%s?|77E;17|zjA}Rm?
z00?waPE!E?|NsC0|Nqs>R5Abn0zgSbK~#90?VH(lgdh+^6}SKY;|w7VEdqi~QcSFR
zL~nzAJDGE483u-77=~dOhG7_nVHk#Cm`7zC$s>9A0Upke-yx6U;Rkp+KNwS5Vw%Xe
z=ivu<IB(26kMGof7a*_W;Rkp+|0=L7<0&!RuAfWP@;2!Q$UVe3E=z3x&*mur%b)Q*
z^Bm$fwuCH_=EH;R{P7qmKK=mZ`=|J@0cf5A@B(80KwRe8OOSUR8(7cF3OW9K{JQ;P
z{8=EDrvSWw6z*<!O$;}Y4ZOqq3VFUnV2<}qNDol`{-u0>$pBM8-vaE-wuyHe81m~Y
z`;`)2E70xUet_EX6o3_wdkK+6QVo>6zmn(o``jUZS75lmT)i_u&3Oud3-C*+2FgbW
z8|e9UmDf_dY@y?I0$UCcf~SCf1l(<)ysw0pt1Se|-DB*LPY)1=r+|J093L)K;FwUr
z^#SrcQXqzZr+~f$q*5bbUAI?qyuSl0um_$3`V*jS;I>`y{tkpd*`n41P|s5UUO;%E
zrh&%j`S4I^fq%<W!2c5vOX^Rsg}~3|DF81Z-kMwiAA0~T|7?L2fEG~yhN@h(1#~=q
z0I)m-^dR86MD9a1J&zm!JWl~=0oN_G_@3kH{;{-rhQ|*8mZt!`fP4`PzrRK|>@9R(
zw(wt0((u>;!1EM<7vPH6GUxofP>2?~^#iWtu>*kTDF83P7I96Kv1>yRW2Wi+Lpv>x
z9RNJ9ZXgAy1)x(Z(Eiw2GXQ8lHNfzEN(0*p_yW0Na;@MRW!3-y002ovPDHLkV1mV;
BH0%HX

delta 509
zcmV<Z0RsNM1)&6x7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0k=s+K~!ko?V0VB!XOYu)55fn7HEMMXn_{e{*n+PUvY?UJsd{fFT(}%?sz=z>axtt
z%*@Qp%*@QpbPWy8yBB~t(a^km0a#$I?NH<J?ge13iOMZ%7~Z`AE?_9+wMe8mu2g?=
zgY*_;R94_?e0YJ2@6lI3w?mbjB7Qzc%wxgY`PzU`E<nJ<1@)oem(GH>+;2$vOR#>v
zG9Zu(5TGQ+RSZXb!Fzse$apE3aw-ONd%niY0gDqLWAwX%fm^#@sK<itc=Ldo`0xVh
zd&F;v3wmxV-1?_@C>YLj18V2P3s8Sv(BB~xJh=5&rJ>`DVB3H`=RySD74&N*KVQSP
z^UQz%E=1tAAgSU#Sm&4^z{Ln~1>J#dOZl+?3gTRl09SC!`Ihphf;JlvH$b@p;i6t}
zW%+*ze#n1Fp#Bo_f?wtW1a#3bEy(fCg5wL^{=MoSt{jI40CEWe#g6oUHkN5)1AzJX
z0!2fk_nZ$E%i#flT!28f#rUt-_lD*W;5aw{m<teaTeP{dp5I{aOKlt+0L%plEbimt
z%o_SFtGa&1<2X0~m<td<Qxja60iZk{@W=vxB1X>Srm`si00000NkvXXu0mjfk#zKd

diff --git a/img/sex/closeRed/chest/12_job_nip.png b/img/sex/closeRed/chest/12_job_nip.png
index e766a13b1894c9cc9e284d998ac27851dc0bb772..96e4b31b6f839284aa596daa1f27f3498ec71220 100644
GIT binary patch
delta 265
zcmcb`ID=_|L_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EK<+wE7srr_Id889^0_z&xCUPR9d9Bn;o@6;#B%>Gr&nH8kw8T-
zuw#MQ%lscEjI+LpRiteV-ODncU*kZ%%U;&7xzX?58|QOal*To@sHtz<d;T;#&w1_%
z^Wr~+#~3A4{rmBd*G~R{{HkNi${+pOEnj`~o_oWxcTC4EX5F_pw0^++?_w=eOR4yb
zdGFbL&L0=oa42SsecAA`lJOGbJ-xjSj4WU$RLl`QAI;J_u|h5y#P@Xdb6Mxal+XkK
D^gm@J

delta 202
zcmbQibc=C<L_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-mJ
zy{C&~NW|f{{f2xE3IZ&d88x!Kz3Uf0n`-9qXl|9zVb@7ByLeCXv;dU?0pFU-tg8&R
z&eePWUtHkOjXj26S>Jzq(I9ke^KqW2>Iw%gQ8(ucxA+)yb-r$RD(+Zp&9bDxvg~C4
y!Hm6EbQM~!O>@lt&A#tnz|S`Js+smc1Dj;y*pv11m~O5I8Sm-p=d#Wzp$Pyt(@j_a

diff --git a/img/sex/closeRed/chest/12_nip.png b/img/sex/closeRed/chest/12_nip.png
index 4a40f3b6a5e19da41d310a9d3f0053cdd8ceaec7..216ba1c29a6da21897117519fd56397dbcbbf9a7 100644
GIT binary patch
delta 174
zcmbQkxQ}syL_G&H0|Ud{?Tv4M6k~CayA#8@b22Z19L@lr5LY1mKjrZ%=Jdy>nQj6(
z%q2m7!3_WZy98WQ1ad<>T^vIqTHjs><YEvIa1Av69dGh!<;548S8VT}7hMWeVRJ%f
zH}|xp13Eg-rxhi9-1a7j?~iAl*N2(+I5;gI>=Ra(5WmOkQ*F7y+on$8g79|c1BRkA
XbQ$(q&E<U!)Xw1P>gTe~DWM4f-mgEu

delta 140
zcmdnTIEQh9L_HHT0|Uc#_L;swiZj3`#1%;YdUo^IrWLjPY^FdCV@Z%-FoVOh8)-m}
zqo<2wh{fsT1PRu~4N3>P5?B+&Id~hmTav^RTDc7#2q@eR)L>e(T0n_0f_29PmI!eH
oA%@L{EE5>7GdVFiOEEC4)!}*iHafQmXc&X1s~@Y&I;Vst062Omo&W#<

diff --git a/img/sex/closeRed/chest/1_job.png b/img/sex/closeRed/chest/1_job.png
index ea43a06eb34f080a44ac9cb8396bed9223f8372d..919b180947909a7c22d5b6dc4104ed153c35a843 100644
GIT binary patch
delta 649
zcmbQwvYvH<gct`i0|SFfTR<<6Vk{1FcVbv~PUhuAMcMlQDUVk%rw31wDFRAymIV0)
zGyI1FbEer>7#NszJzX3_D(1YsbGz@50T0WCDNCmO|Nls}uzT(j@s5dSPCZ^8RMj>y
zfaUEp-r$)5X|wX~=A4)1-E(fX_=k7SHGW=~tv=sjpW}Yu^`1(`_xo5bESbWeulz}F
z=a~olU!Se#uK2#bp;|J^=daVQyM0LyO7HDyDA%8Mp^)QY$THr>>y@9G?$w@XDUf%%
zEqyOe&7S?gZhqW>-Suo|jGZNe{6&<NAzI>@zVY9^@2-Db@Pidd!F|pf(tS%BB>K4z
z)IT~4v_)}g<+=Dt-;ydMPp-|J#0XKvUte--j`J^uwol5c^TR$I=YTkyd9Io~>lVi?
zy5fQmfq2IBJ$xs+SLid?KLZ(-&+<ily3sR!#fn~Y{RemXSucdI{K)j7g1PQk`;?Re
zo8GWq5&S8^*8q0@U#SD_I;S67=DPf~kUuQG_<<?NkMf^V6(v8^SH!SiF#K@;!!y=B
zzrV7xg)^46Jow-R@&SL%g}*7c(x3Kvevkt3_jBC%)+g4m{}V{*1?6LBGP>ozvpzTu
z3f6xH3;w+d(N`^u7Tj|Q6!3?Cz7@%pm|JmLUIG&E{|-0&`E2aVSh0uE{@H1HkrGz0
zGcwBK^HyJAIq;bG$Mw3s8$H4q>h6H_>x&1*w13|M4JP|Ymyf1j&WH7JALy?JM#$fH
zN?lh|l(yeysF(}#zj?Pt*=Ik-AB8}7ZvM}F<$OcL($)O?fhmf?)78&qol`;+0Lg_w
A;{X5v

delta 504
zcmZ3_I-g~N1SbnK0|Uduvb{YM^<?XR-aE6G=bypJOBp~x#*!evU<QY0H`0LYO`a}}
zAsP3s&bpo3;=tpYc~CcpJMW;b5BFsz-GDN-XS~uM6W6b6=buurZcXu1)tlGdTyAf>
zxLode{^N&p53^ojouQhlv4vsn(T7ZItd|t$Pg~#+e9XF?dxl7d;i(Nv&(HXH?jcjX
z8tXHULrOu)_bg)^Vik_HM61m8ueocng{7VQ1$PVgGY`v8w~7t{wMmFbtmCt9o%8{y
ztBiFS?@{9eTNv88S8#g>yp(*Wev0wEjNSsh3I80~JA;+(YpYz3eFSvH7uHK{Z4S|a
zcPEzfi5qAN>}O4qe=zef>l^MZ>b^cs|LQGc9<;MQI?W&t(yd^*;k$$98_NekojP1G
z;olzbc$;A#_Mm{Vlu@tov7kq|7?54dSjV!14J_JNsJUJCBA1L_LTp1k+m6QtjFXvU
zuW#3_kOEoa!#%}5Al27LyI@Ddt^;p%yQLm~F5V()5%VA%WTiRK$`pMCedamEKzW9}
zEPH^oBV(oHgV~_qduN?BU;Y1QiQ?m+08BadGStMMxdx=v;lAMX^&6kO7q*p8_OpyR
ku%LnG$8CoDK;s_QcW@q-EWYFU1Q?qPp00i_>zopr0Iu`b6951J

diff --git a/img/sex/closeRed/chest/1_job_nip.png b/img/sex/closeRed/chest/1_job_nip.png
index a228054fb1c3f8f527be84c74c87f55015777c8c..5d217274db3aa8dd11babbf5be2713ef2df6570b 100644
GIT binary patch
delta 191
zcmbQmc%E^BL_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EKyIq1i(^Q|oVVv3`5Fv37#wf?w~u;!_u7d@4dd_#Cl;UzC^*31
zJMs3#=f6I&@A`hdVqTg0JM%9)_x)*nXHk1*r~QUoP^o_YJyz@Pe|ySb@}3c<^}%hv
X6S~ZdvAfn*fP_3<{an^LB{Ts5aN9|*

delta 138
zcmX@lIE!(DL_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-m}
zy{C&~NW|f{XBEW`C<r(oG~KJR-1++y4VJ63x$gCNU0Kh>!0^jv{>8ta8>Nc-&zxt!
oSK0UOf4aiw&x{NVdK(zto4B3)zWagz&?p8^S3j3^%uWeS07C#ZFaQ7m

diff --git a/img/sex/closeRed/chest/1_nip.png b/img/sex/closeRed/chest/1_nip.png
index bce6f35a5afaa6bf9fbd13f9861294cc9b7cff22..634094c50adacff613dc2fb5e126947f98e77a13 100644
GIT binary patch
delta 133
zcmXS$&NxA$o`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXXxqT7!uL?_RL0J1_d6Ljeq`mA7)`uWbBQdzmAJx!PJ%c?|3KGZOEC&
hd+wbzGsBN8h86q_mW)c%dx4r6JYD@<);T3K0RXOoD((OP

delta 100
zcmbQvST;c-j**#xfnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{IZqeI
z5RLQ62@<R<4ZH%ziw*uU82)GEVPiH*Zed{1FJ{xW`smLCRLS7!>gTe~DWM4fvRoV<

diff --git a/img/sex/closeRed/chest/2.png b/img/sex/closeRed/chest/2.png
index d7f978fc7fcfd21f826281b02b83ffe142e2ce8e..e31218746b8804812b1f51a14149611df1a75f7a 100644
GIT binary patch
delta 407
zcmV;I0cig10>1;07#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00BKoL_t(og~iud7K0!R1yB(v?tjHKqzEAlp5w#j
z3oW^Akil*y#umevT}Aq=8;=2dhI8f@-fLh&KmZQssC!M&owCezz$XS5qYK&hE&~Hb
z2q(K33V94r3MXrSgxe`O54IoxfcH7EL}Zku3IYPOySDG~*A>J9pkDyB7_b%xIOjb*
zq!yFQC|ky00iL#mw10XH(8Quibqyl`-~!r!E<qIm14ii*pd#J{^x~pqHHfbQ{3uZX
zZ<PrMp#{`L2x2WjfZQd7<BVAm)C&dBvM7P$xC3x66u`uG7^sOW9RQ>*_m?wY7rQb9
zpyPCu_y(W{s=ULkd@YVP5Kt5Km4w9c{ty^Hz8d36CtfgK259*3z?@hM&<6c~U`DJ3
zW<}`N&NV=9JISxt8NmasBCH7ccViWh39Di$@CE77Ktbm)e!Bnw002ovPDHLkV1n>d
BsVx8i

delta 325
zcmV-L0lNOb1MLEk7zqRe00013M{MnpE**dQ-psuW{xHeXXaE2J0d!JMQvg8b*k%9#
z0RTxvK~zY`t<_r*#2^d>P%OkkEyTjLfQ4AV0<t$e3v6cy+vTGVa%PeO1xG~AIl5X)
zZ&TX>W~d?G0i6SFxVj)uvoQe?!I0&ej0wy{!vH$j0uc>&qSqA8g_9Nd94w@^lD2;e
z0~mUTC*On}Oc^8rwgGtHHhf>m3Uq)yWD=!TLaA~OGy|3*Wz1m$@&x2(&?k)vFM${V
z3JAkg)rU~$!T@qlh;hvkq6u&X@f&ED38+{Aci=1_^*l~@8fz<%$0c_JdRg3-eZIpE
znrOF*>hHe;%O^I*X&-w9<N)9;pg%DHyaa2GzMq}|%wa}39L(U(!Sxs@=gASk5IzPU
XvF0K_d{h9Z00000NkvXXu0mjfb+v%v

diff --git a/img/sex/closeRed/chest/2_job.png b/img/sex/closeRed/chest/2_job.png
index 0dba2058958bdeb6279ad769f4fa2891027ee582..29b6d9a5a3ad3f220a9df526523099ddecfbd696 100644
GIT binary patch
delta 390
zcmcc0w3>N>gct`i0|SFfTR<<6Vk{1FcVbv~PUhuAMXCD#DUVk%r(54q(gI3xlmz(&
zGyI2utEWPYfU0#pT^vIy=DeM8o9~c<0P8}h-~a31=w@h!T+A&pvHl#DRwU%Sstu?a
z3LbPxe4M(krlHvW-huF+pBV4`HSk^Bd71NnMZDdCo%X((M=hqkVEvE_R8qd5tA3B)
zkr~Ca4{QgkJg)tu_R+5`<_z~Aoo282KKnr2qkn7my8JK$YTbRG^NaA)o4*-<%>My0
z)jeTey!xq?Z&eRL^iC+A_^fj0hUpRW580oa&i~=vdZyEx_;Q55YW`VV^ONCyUB$nt
zCUP7<+QBwy1zzUgV!!NTD%c(M>Jv8SGW=ViFaO{!|LgTZPcMYkvjt@_|9>$3kp8>r
z{009RuXO(VQ@yCV@xxh=!|OXr9%swme*tnOBh2Rv3=iZjnd{0lSU(GTy#<MSy85}S
Ib4q9e0J@^PA^-pY

delta 304
zcmZ3@e3fZ}1SbnK0|Uduvb{YM^`z>5-aE6G=U+tQ8v~#qV@Z%-FoVOh8)-n!Yfl%)
zkc@k8r<~?xRupi~JgB>bHEIEC)D5w1e_JNpeWQOWQO!vBr);IzrdAg(Cl19H0jB`R
z0)PF4Zw?tiQm$aP*At6*aR=UT>j_!*EEg}3D)3nFOamxl$6%q}AanFG_l|nr1LyYN
z&nWTNe_+nAo1sVm$S_K<Qn_{UliT9zD#p(Zx2~9+zwKh*_3$NY4ci&p2HyvTB8M(>
z&tRX@-zWhz%VvRkLvq63Wp3ZUFwJ9rHJ!Wd%NM3+jDHtrxp&vIdHtK~zwY~S`43(>
x@BDX*OWgzMoTIt4<r_$m6Ne1Q)gAwz^X>c{Vk97<{Tk?T22WQ%mvv4FO#u0vf%E_X

diff --git a/img/sex/closeRed/chest/2_job_nip.png b/img/sex/closeRed/chest/2_job_nip.png
index a3dbbc31853286cdfd81fef3afdef555c2d51899..e6623cd3bc7e5ee5516138d59b7cbdec21380579 100644
GIT binary patch
delta 192
zcmbQsc!6<(L_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EKyI3+i(^Q|oVVv3`5Fv37!FSRZy)t|??ztsMQ36XIg^1ZVBpWW
zIXiW0*Xh?UsQ%CM_*-4l*2U+)KIJd5eD8kbT;tbicGsudU)XDJQBV`L|00OV4%6AN
ZemBGEUS>wYWFZxhn5V0s%Q~loCIHVyMEn2%

delta 141
zcmcb>IG1sPL_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-m}
zlc$SgNW|f{XBUbdP!Mo&<Y{}gXr<mPt-$GAH#qL~?6UnF4K(ju<*OGn=kk9EoiBOw
q=Ybz`uYKRdGf$k$&%jX7%<J*YV&@YVIbon_44$rRelF{r5}E+S5j2<p

diff --git a/img/sex/closeRed/chest/2_nip.png b/img/sex/closeRed/chest/2_nip.png
index 7301dedbd61df8b0c66f38c0df39b5240e25e013..9b3db9647aafe88b83f79f7b90d11463589157a3 100644
GIT binary patch
delta 132
zcmXS)#yCNuj)R$jfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXW;4L7!uL?_RK~>1_hoY8&du+O=POzS}-wd{%Qt>ZB<^YqMP5PY*-=3
gckcd828Ml7%kMK-p53n{57f)x>FVdQ&MBb@0MeK(CIA2c

delta 101
zcmbQnSUy1_o{^b>fnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{c~2L|
z5RLQ62@<R<4ZIx|4QGBZA2}m$Ai+LCQkjK;AwHKgbdP=J1)x#}Pgg&ebxsLQ01JH{
AhX4Qo

diff --git a/img/sex/closeRed/chest/3.png b/img/sex/closeRed/chest/3.png
index 0b56ba772a23a20d840e669f5dd8b3803c912347..f010074b8d1f0de0a8100eea399eae2ac81f55b8 100644
GIT binary patch
delta 413
zcmV;O0b>640>uN67#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00BcuL_t(og~iv=7K0!N2H;Gcz5f$0B1MCA=k(jS
zvXXD3)NFA_EJrxEs>s)F<1yg(2*I5ZqXq^91mFmPx?c%8Q<pgp_#DB-=t9=@mVp61
zgp<P&3V94r3MXrSgxfh;ZgxWefEXpQM%t)LZ3qZpceT&)&sD?(;JyHAG2lH82q8v#
zNERby)Gg<*01sP2?7w~mXkgKxDz^~;Z~-=;OHf6?fL?kFP!aC}dU8>+x{0p>{3uZX
zFO_}3E~3l@2#~v^^ji@r72+{K(?S5cwCynhxE~5&B45~iHVe=M_d@`D*axg4&U6@H
zPnjOzeT-P(+Q~Yq7xyxdfPlQf^kZw6_sh%mA<$pW1<tKJ{mTa9Wq^hpZ}yPDn3xOD
z0{wqrM9c+7Md)qk9N=z?CEII3@PJi>Z=(I&m<0&oRZIoGCZs_Hs+yVz00000NkvXX
Hu0mjfCMvWb

delta 334
zcmV-U0kQtY1NH)t7zqRe00013M{MnpE**dQ-psuW{xHeXXaE2J0d!JMQvg8b*k%9#
z0SQS&K~zY`t<~WXgCGnAU{=Tqu8<Yp3apS7T*0v$3?NwVeAe>AD*5hS&VnQnNh!(F
zMtPdXEl`CU$sNdZ-~&q+l4Uj&Ff$A(%Va1p6E6ek<QABDxf8#Z^4_?xAn(N>bwqz`
z6$BV&hr8Sa52gewKskU697d0eu)tq%hD{=R6-1Z!z!Pw4(#8x5*cGs!LI2ZK@Ddma
z@CAm9M1nH2USzB)4A20!ZrfLv>qY?=<zYKO7d}S-|2+X4K;nR1E|`*)Suk$g0I~A-
z7e#@(aog^#OTTU2J8){S1!`Fa=?yxt@+Bkz-U9gpz)Nt>=-<;P0CQOphXW0c46VmN
goF|U}hVo<Z0c__e7vDr#8~^|S07*qoM6N<$f+kIg-2eap

diff --git a/img/sex/closeRed/chest/3_job.png b/img/sex/closeRed/chest/3_job.png
index e45fc662a3ee84189da563bcf0fd0b9fa282f414..365336ee24515db02ca23e8aa61caa2dab7fbc24 100644
GIT binary patch
delta 399
zcmcc0w1s(sgct`i0|SFfTR<<6Vk{1FcVbv~PUhuAMXCD#DUVk%r(54q(gI3xlmz(&
zGyI2utEWPYfU3<rT^vIy=DeNxkn50wgzMFk>i_2JRJG@<Q&}2a^ZZZO&f*;cg1XOv
zx}m`5q3ym))A<eF{kHz06>oQ7*L$ZIzA<_~KG*(acwEO}SapAT2J468H9r|%*9q2F
z%>7`u)T+_`*=hEO@AC1A?}cw?W;6Wj(3elRyPhe1Vogwe2UM}~1+O>iw#*-X0}Xop
z&vSv_o9q4ZN`DN&b_AVbKmEySV|?s1BbZ^0Z!`9O)SK}B@cgGB!|#3$ytL~Z>!;cu
z#UQ)?wKKNcpUj)izu}#D=cF=)yBv)5^FX$i-(I?S&ZOe!jh~KxssC}F{m}kxKpXx@
zPY|wF+rR4ha~CheYxS!i_W%6Ec<ry>qq&F0IsRP-nP>+K0U-THIo!BRd##Jr1tyTF
Mr>mdKI;Vst0MPZifB*mh

delta 304
zcmdnOe3fZ}1SbnK0|Uduvb{YM^`z>5-aE6G=U+tQ8v~#qV@Z%-FoVOh8)-n!Yfl%)
zkc@k8ryb;NHV|>%d?>zAbdyuq5A6+3*YYzoyDr_Sn^5?)+~L6H17hMqLQWitEdoqk
z6RRs4H<&N}_JQdk<87UZl{R}EZivrTG3sp>k1$E_n2|2VuP-2<@NKriX&t$^g!-Ee
zc9-<l<$o#R*WXak@Rjkj3Q+VZ!)xaIU@-x?2XB+)g^s_hQ=9khA?q}r4STN{UU(N+
zQPKFJ;rsrexh%JA+4%Jfo-=R(&6WG$Ij4m2d+*`H+%4=o`v37fxm^?Wv*sV8ZehwT
z#ZvtbPLCh59%5FT5@ePJQm)V<BLH&ukNP<F_XT3TyfTVFk283>`njxgN@xNAKz4p^

diff --git a/img/sex/closeRed/chest/3_job_nip.png b/img/sex/closeRed/chest/3_job_nip.png
index 5bb4621fb7eccbb39382372cd2983c8b44e0248a..c04ad4c72fe338b49167201b770aaad50745f7cb 100644
GIT binary patch
delta 192
zcmbQoc!6<(L_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EKyI3+i(^Q|oVVv3xegd`FdS6*Uti*Vo>#(#qwv`(?LJ1J5*Ua{
zJ$GlG-Sz4A7xw;ldo61DasSfuU!U?@mb^b6wUK$ZZS6Y!`UTbXB@bR~u)6|M#SYV%
Z_krP18Z%>9=KmUykf*Dk%Q~loCID1iM8g08

delta 142
zcmcb>IFE6HL_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-m}
zv!{z=NW|f{XBCAGC<rhgFrKk*oxjWHQ(b<id1fsr3l*BI#lX<;GVap5dG;BPrK9}6
s{5klQKmXR<ez`9$=j9m~0=_a>p0(Inwxp*HXdHtlyQ`neI;Vst022^4VgLXD

diff --git a/img/sex/closeRed/chest/3_nip.png b/img/sex/closeRed/chest/3_nip.png
index a6cea645ea88027cd4379b7e33a8814c9bfd643d..e81e533d224b998d30bd0d75f519cadc297d635c 100644
GIT binary patch
delta 135
zcmXS$!8k#po`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXXNSP7!uL?_RK*}1_c3@jko{JzQ)$_d7*;Z`@~fY4001zUY{$eviIPo
j-BvfO%h?%fav8eq87y_QzuW-oX7F_Nb6Mw<z}N%;TM;c$

delta 100
zcmbQiST;c-j**#xfnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{IZqeI
z5RLQ62@<R-%+dmh4QGBFW>5`~l%F7ZScrk)OCra@89lpefGQb0UHx3vIVCg!0Pcw&
A00000

diff --git a/img/sex/closeRed/chest/4.png b/img/sex/closeRed/chest/4.png
index 4b7a0194ff57b36860b7b6dab9b31e85ff75ad79..57c6ccc6d0555fc01de3535b3fdeaebf7dc529ac 100644
GIT binary patch
delta 432
zcmV;h0Z;z+0@nkO7#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00C7=L_t(og~iv~mVz)01yD;{;s3u_(-@NUVqJ2o
zd19d1<6%l<ZlTnzR0vyBa&1_bf%vSH!mDy_fe8TtxKg6!H9===%yq!M6o+YpY}=55
z0q+oQPNf>;GC(bV+}t93EX{he9RUDx)<%o?vQZrY0s2e(=lItdVgWD?Kt~M3hyzl}
znf^#UMq}8c5U>DmTSEFDy#{Dwx!VW;I6xn0BQzl(z^vT^5&{c+-Yg;9P5e1PA#lKG
z8`D_h*4~J5&jJ+KcTbE$?E5N!E*;OB0fqnpy5u+n@WZ};251!)kVOLc(cT9N0R`&P
zhy23`Ujg((pRhxw2FyT#08HpB1U361Cy$jh$C&f^-FOkO3)5Nc2j=U-pY32^R041`
zYB#Sq0ANnoO)amRIDiK9|AF~e>q=l2LN>RaSp$q-vGn0m1P}B=)T71zyRize1GKKC
azyru8KV2FRA;XXW0000<MNUMnLSTYbiM}5I

delta 334
zcmV-U0kQtq1NH)t7zqRe00013M{MnpE**dQ-psuW{xHeXXaE2J0d!JMQvg8b*k%9#
z0SQS&K~zY`t<>8M!ypU=P*(5?S%DSq3asE2vI1k*yo^DSV%qW%wfIPv8aIK6LI`w?
zRlY6j6~qWJloZf8kcCSHC0dOOFf&ZbwHOyziIf2-c?HZ;RwB<*t_LSCNVV8VUoC&O
z3kNW}=2IHN50(TjAo>6jFio5f@&aja0xzPSmHH{)fh1r%B-;!J*y|ne0eCEz4EzY#
z32dVou}+|7gadGQVKeR{z<16&Xu<>PPA;JT0|v<13(8gjeeey)ZZH-$5F9{$T3YK0
z+Q2x#6!XICrNtCHV4v95DDx8f5=1)aE9f2I2}lUMfc^mRBiJ*v<tG4Zxiskr%#1NL
g?WT?ZO!*jm0CtfZc>{3)82|tP07*qoM6N<$f}0tJk^lez

diff --git a/img/sex/closeRed/chest/4_job.png b/img/sex/closeRed/chest/4_job.png
index 076d50f1958713250d204965e0576b27f9d27d76..0fba72eaee4a0b510cca373b0ed765da788b75cd 100644
GIT binary patch
delta 420
zcmaFLbb@(;gct`i0|SFfTR<<6Vk{1FcVbv~PUhuAMXCD#DUVk%r(54q(gI3xlmz(&
zGyI2utEWPYfU3PbT^vIy=DeNpkgrKW!nHNv{{P;|GnR6=Tr9i3uefg6^OEhyPA%gE
z>V|*=BIh1z*ZyR9ysx@p{imnQYkp7uzPIx>@Bi=nY8ndf{}!0@+ItGqk7OXP^uI`b
zhWeb@&$F58&rIjv@GiYEOewC`oZ)|PyxoCa|NjVn)tj^~hF|dC41M{8yZUTioqxT~
zGyJIo$;NZG1aLoT=YZ&xXF7e!YtOq?ya)at1DQ0x@4}`v(r+E+9gzPFazk{&yzkzx
zcd<X~EmGKbvXbFn2gt;FmU^Y*4pmEKJib5pe+s0}p4oD%{=^l}-39(vgKhD=BEQs|
z|MC9^+yD7ocsHHj;6LM&P64ma!Af@v|9Xqn9|7sgZ(&xo-1MB=>fZv8vF}w_-m{nd
kaReE_4+|HD5A*LZx*WHX{pRyj2qfs~>gTeK*(sq30B2mn^8f$<

delta 320
zcmV-G0l)sp1LXpc7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0Q*TqK~!ko?Um6DgD?z4vw~M(1+S15yh2yV`faFygz{%s7fbj4;GNK&B85^2A%qY@
z2!SHWJ-mS1i=_7O0`39ZQ$q82cmcPs@{rIp9$p}5z%3!BSv<Tz)POl5qFFq=fPa60
z9E|=tqt!jUK;Qrw1ENVhyg=lDItGq2THV77#0+@NiT#!4@bCgL1LW1(EpQ}O_wWM#
z0oI>d515Td)HH>M7YG<&_6^t+_`FHs;RQkl9MmbGDLlM@d%%#Ge%05%Jl>bc@8=(I
zCa&+7er5eET-C!1xCfM4tDRTWPLC|-@$drf0T0wIw}%&S4<LjPLI@$`@4Nxg>hUgM
SG*v4A0000<MNUMnLSTab(~+(K

diff --git a/img/sex/closeRed/chest/4_job_nip.png b/img/sex/closeRed/chest/4_job_nip.png
index 7eda197143ca01ea1f7d04961f287ab30d42ac44..42c2c24cb7306b6b0edb8f259268c81f16637b39 100644
GIT binary patch
delta 199
zcmZ3&c%5;AL_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EKyI$5i(^Q|oVVv9`5F`iTpXYLYcI2Gm{f8`V)-j^xi1nxB`|Q{
zd`@(k_x!I<nRk7^{?JB6_={(}-GXWd`)4(E5B|9P_XF|ve>rehw)Wa|{ulT3Ig4v=
ffEXb6fk4fDKJBH<l7Yw4r9fOyS3j3^P6<r__ex01

delta 148
zcmcc4xP)<nL_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-m}
zr>Bc!NW|f{=M{w-6hvGv#^0Gg^XkONrLKu<_|BL3{pv4j*J5C3csk>{<jtQBTmSt#
z{cbLQ&+~<;-})PW-`M-PF|(!Ij)CFBRaUt=ug;I<*LhokrZRZC`njxgN@xNAMtVK8

diff --git a/img/sex/closeRed/chest/4_nip.png b/img/sex/closeRed/chest/4_nip.png
index 7d91582e6ae6b6063840c20128be6cadfa4f6bfd..8ec0dd0725c71bf239a5afaafd4126667b8e1de3 100644
GIT binary patch
delta 138
zcmb=J%{W1#o`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXX@$V7!uL?_ToWK1_d6LgG>G|+se?|kRgzE?|7Xa6T<^$%ThL@?8djR
kG81-M^M#bwvmOv-o+Zv;yFs%RWH5uLtDg(YI;Vst0GP)tIRF3v

delta 102
zcmbQuSTR8&fsvVkfnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{1y2{p
z5RLQ62@<R-%+fr^<OM!5Hh*NFd5~eUQz}m`0|WngF2$JaNqs=I44$rjF6*2UngAIy
B9(Vu%

diff --git a/img/sex/closeRed/chest/5.png b/img/sex/closeRed/chest/5.png
index e2c5236f3dcf0c7766d00cca40a31ca9e6de06b2..556d068ce4ba3882bf614cbb20d61bb90d1057b3 100644
GIT binary patch
delta 434
zcmV;j0Zsmg1K9(R7#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00CD?L_t(og~is<l7k=&1yB)K{r@j+!`(;%q3jG{
zn<vMT(_V_;5lS7ULO8qP&xW-O#CN3>ek<o5m=G=iDkU1;5_Ct#+z0%WLYO|tc@7yj
z;1h!8RH{Rk0ct^ibC2Mfo9kpN!U4#+HcCX7jH(D1z#eMf!`BI7127IiR{&!415(PF
z{v?a3G2~SUz5tdjA@)yi0a{pU8XW)xuz@~87s3UYwQGPw_yT`#<`8NU{~f@F^DLxA
zV6=>B5L)dmW*2Z>niz$+t|!Eo01?6&AmV;k3w#LS1k?e4_sxK8vqI2Uc>+9~0e!ew
z07k9@n5_0V<3m&edee!qv>!e|J+Sm4E{AJCZ0ySbZr6#l+X2Ye9Pu!@03ebmJz<z$
zCPcdnFgsNAqUP7l=Ot?ypl$v8!2D?43Cu#Yj~NJmVDySrmu^M;0V_oNVClzb4<NU%
cwzdK<ff+y%5t8^2@c;k-07*qoM6N<$f=$c1SO5S3

delta 351
zcmV-l0igcb1BU~U7zqRe00013M{MnpE**dQ-psuW{xHeXXaE2J0d!JMQvg8b*k%9#
z0UAj}K~zY`t<~F&#2^d>(6rzd(t=yKEzp8nNDC=@3^q@#gi)4{D1*=FT0oMEh_36R
zyN>*88e6~&HIy2lbD#rv6O?E+As`|cQtruwz)Z9Zpph*Q(Q+et&E?WKML{Y>BR+pD
z)<pmev%_7gA`Yem$$(=33FwCVg`z+gI6)?1y^?pi2bzGTNf|Q&V68il1Mp`#XW%0c
z+pH}Z7h1sO1lDl`9v5TAQ!>5)%ZLJb-nW7|BLd3An*sMD=l=?VJf8utKqvPguWv2r
zF*V>vh_xO8<tg(gUPfT&ehc&-X|78vu$Pc+Rsd8{ThorSfFHRnSRWf-Z+LwV=pO(+
xf;FSPPfq~mGQ&O&VbC+`mibPd01V}0@B^cUAN@;h5+48n002ovPDHLkV1mhXkKO<P

diff --git a/img/sex/closeRed/chest/5_job.png b/img/sex/closeRed/chest/5_job.png
index 92a75682cb0ce49142c180ab3a26f9937db28705..bf9e35e0c7b5d90e98a74517580a77ca6338ada9 100644
GIT binary patch
delta 451
zcmey#^qhHugct`i0|SFfTR<<6Vk{1FcVbv~PUhuAMXCD#DUVk%r(54q(gI3xlmz(&
zGyI2utEWPYfT}Y+T^vIy=DeNxu&BvEfX&nA(C__)ojgt+L5rTBIeF)u{leXKe9ddi
zW&!m>fzLykeaqI{9oX@H-h=F)ub9{Tp8S1r=W*u$zxVxOc)ahsqJ{ai4Au{+Kwkap
zI>8_Ik79aCnc|<V=HKuxys=JY{!Y1u|MP$b?E3#p`IXj2x%K%<H8Vl{`<yKo_?{T2
zLKT-Yl_uF68!^;h371c}YtIt&iv8PT&8g;s`_6y_>a8bC<T+r!mopP+u=swLpjqPU
zm^8PtKd65MvP!>EVtak?=RK^CoUA9zUn0|>|M4n&#P|7)XAC#UWwKwJfAIe_kfr+t
z9?v_mroT#l>E^h)8ONrBeYAe|3y=S=uhhKzQ+lOi|9@|$`P?6Z>y$5E+8(XjV%4Dk
z8Dx}y=eB)pR=;%r#QeDW_Z9P*_y)mEZ~h+Nb>n=i_3ua5&$C`os{0EIwSxG643RN*
U6KADsZv%;Wy85}Sb4q9e0AHfmCjbBd

delta 340
zcmV-a0jvJ!1Nj1w7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0S`$;K~!ko?UvaM0x=9k(}G)|1-FnE+`_hy_Sx*kUWgB8HL;lY1-uc=$U=}3A%qY@
z2q91;xQ7>Tdy&u{Ucf!zb(hdM9$vuhv)m*!jE5I!G~g5w(<mNZpxJ;!L`0)_cmaR^
z0Fg^#e7xPLcMmVnazNe%Bx?*0FVJ$pmYAMs3=c2RX25U=Opk}<M!kD@fyV}{H|pKP
z3$z&^Ln-ILpdmcGfPaA1XQc+r_Fs~sAw0Z5g8^o9zz%`&l@K0Yz&#+@l&A-?{ZDmS
zPt?1I7jO@#H<~&8UA3%Ved@`_AFx0rKE9qUUl#W2;RW0Smc-7dr+sSr{_zJ~$@%5-
m>0$r-^P>+Sgb+dq`3K&E(G%xa3Goa70000<MNUMnLSTY>beaYL

diff --git a/img/sex/closeRed/chest/5_job_nip.png b/img/sex/closeRed/chest/5_job_nip.png
index 344a5e6dcc9f107800084818697ba08693c9af85..77ab2032f7902ee0f35c2b78412ae188510ad258 100644
GIT binary patch
delta 208
zcmZ3+_<(VOL_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EKyI0*i(^Q|oVVw0^Bz#(VR2mWf6-?R1;>bqt~Q^~&dTNmDuIC?
zGw&s@|FY4p*5Pa2rvsNV|MD@f`u@GsvoPwvhy3fy>>=-OOT1@a=l|vYmzO}9VD@?U
rUL@E4YIyZ`O2Rt+Zy+(KQEwhHwBBMiG?=-dA0*=G>gTe~DWM4fFDp}s

delta 150
zcmaFBxQuavL_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-m}
zx2KC^NW|f{XBEX76hvGu#^0Gg^XkmVrK}%sNa}oFW-kyY%D`~o^^EJ1H?5gx&gBo;
zy)S-sx!r~N?bB{bGe3^l`?+ytd$}D0!=I;YmWRELe&tucBLg&-!PC{xWt~$(69E74
BI$r<)

diff --git a/img/sex/closeRed/chest/5_nip.png b/img/sex/closeRed/chest/5_nip.png
index 28384ad935423becac4a062e2609fb1acc1f9047..d0e0ebc1bf5b53d604b1b168a7dc41878518f91c 100644
GIT binary patch
delta 138
zcmXS&%{W1#o`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXX@$V7!uL?_ToWK1_d6LgG>G|+se@DaG>GLp8mfvEDQ{+JAK)VUN=5|
mm-t{)4*RQR_nCfNU`onou>5AY)fi|1gQu&X3(GpEgeCwWsxYPi

delta 99
zcmbQuSUN!>mXVo(fnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{Sx*<o
y5RLQ62@<R!3}zBN_6kkx&58YI4lFFyU}Tt^$XcF#`|k{(LIzJ)KbLh*2~7apxF2f(

diff --git a/img/sex/closeRed/chest/6.png b/img/sex/closeRed/chest/6.png
index 77c119cbdabddf24edafc93e6ebcfdd8ec7489b1..6c0a1ac3a7d822d629d83a650bcfd039f7b7fd60 100644
GIT binary patch
delta 436
zcmV;l0Zab>0^0+S7#0Wv0001;w}I>c0004VQb$4nuFf3kks%#_|77E;17}l|9C82v
z010$bPE!E?|NsC0|Ns9t0-MwT00CJ^L_t(og~iwH7Q!G124J1;<NmL>*qalOxy})b
zKkYPm3TJ2`z9XCw<I+UA*NI^urJUm@*0lv52?qd?GY!`Sy#stUu$_To+CrA4!#Dvw
z1j+df0~rRk4aqHkg6oo8CtDH2z`E8%j>t$X6yX5aL+$tQae{CM?hBwR04ezb^pGs3
zmcg%L^ag0z5@LUK4bZ|;(>M&E02^paFp6*hp3)^yitq)#PcB7>N&Gp0hI1{Xi2${+
z((pQjE3of+*j*8f_!~gY#UCKzc!vfoV&6Z@*#)Qrj)Mb#Rzr~=_Fn*F$APk0v;(Mh
z>MMTtOb>oQOVlK~r-`erIRJJMyZ`{QxnDmf7eJSR&5M6ol!RBcwG9JhAZ@Yr7{#Zo
z!Z_^Vz{#4b6Mz8-J)L#>%7HfoPvCiLoeR)L*-w^>Yz}aD#Hx>#KT2=FDk6!He>Y|U
e@~87t;05v%Wk4}4aFW{q0000<MNUMnLSTZRCcujT

delta 343
zcmV-d0jU1l1OEb$7zqRe00013M{MnpE**dQ-psuW{xHeXXaE2J0d!JMQvg8b*k%9#
z0TM|>K~zY`rPb{X#2^R;U{_#;uHXvq3a-EkU7=$ih~K$HjQlWFo(8UZZ6FFE&{IQa
zb8JBbNu&no97y14f)Xvp1DF{@m1i~{FcV1w=wu66(v8Td>D)MZLCQ%ZC34j!_F#Wl
z9j;OnZZK6~1<?zDZekzE4Jak>B&=7eU2cI?z|tg7HTGc57r+PLZ(3{M5^&k9GXOn)
zi*SOsu8lQJTmepg!0-1}(8a3{+X3>zXP_ULa@#GC)ji-ebQMttn@ZjXnt+w5A|JXv
z7;0FBsJm`c-7E*FMWS`5*IAUm-WEfk2uXu0VDz_`3rt}x>)SXu0d4_dNtefV0x+i|
p?1#ERuMx{<z`iF(07Lp5`~Wi7BF7UTLbd<^002ovPDHLkV1f@Rj-3Di

diff --git a/img/sex/closeRed/chest/6_job.png b/img/sex/closeRed/chest/6_job.png
index 5d10b5a8fa0520b4fbef4fe9986853dfe6c347ad..97ff4221df115e344360a99a76616cc145e72e60 100644
GIT binary patch
delta 512
zcmV+b0{{J>1Ed6y7#0Wv0000ahER<F0004VQb$4nuFf3kks%s?|77E;17|zjA}Rm?
z00?waPE!E?|NsC0|Nqs>R5Abn0j5brK~#90?V9a!gCG<I@dJJTH*P7-D2Ubu<v`s1
z)sgHex#xD8>C_ki0000000000fJf1F_)1@XfrtCu5BMryeu1a^rti;23<Li4zWf3Y
z_xpYvyY5^>DgZx!&zE1|>3$G!9O6#55hZ<VKhLLt+6veU@h97eQvTTjTk|PEUqGyT
z#&N6r=V8cQe(L(^0^9Z}pw<Gy5r)s#A$R%e1t{fHKs^Oa(_Taz-uHL-M{gl~USa`C
z`4rGv0sd7>L}}k~&jM(C3aF<57cqbHSHLu_KTKWcx3K_!SNjy8FTmQ@;XJPgXzktr
z=XrgBTt7U~Er7<Sfc6UTuhRKfFM!skfEo%|A{MMo{|H&@zDan2T>pP>K)nFh`V>${
z0oxI-2N;hq{3UdSAKPUYK<QI}x`1><IKD8%orQmn%JJ)10G&?(`U2t*_f<T;B_tky
zzOP*Xy`Mc_Knln%U>TtwUTS>CyiODUT9N5%7eMbD3Xm6Y1~=GYcvJpO*z?a6=qr4G
z0o4A{0-u5c#0BWNZvooy<){as_5lC@00000+U5%<v_BQl)SLhS0000<MNUMnLSTYN
CS?M|e

delta 379
zcmV->0fhdf1fT<u7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0X9iQK~!ko?U>OGgD?z4S-~rG1+S15yaFp^{f0tH+9EKRG>Uci)$mT$-62)bVSpeA
zf*=Tjpr)eEdGi2fPSiDT9>84SvE|@?c=G^e9%#eC-SFlCZYuC)Az~Yszi~eWN=tt_
zyd78gR>4}_K>=D7)_@fFJl`x>nfofRBwRl8X>J|h3U^XqEFIbY(DR!HxWfGw7?+=_
ztNhde2JWN)jWK>3MqxFtFo2djC?L}@&H<$i7+J;d7{I_C7f6>(Tswe~dnh23CB-e0
zn7`nNR~kUcT@;YdfH|SCk{buG@&0EE6b>mLSJR0#{DuKc+(ChCk$1lNoh>N2aR4)S
zP~ep?#ar_Y)3NyDVxJoaFmne5eiZ`m;bbWJZ^7YU04x6-*kb{+P7P3jqW}a!5ClOA
ZJpuL|7)d1t8aMy|002ovPDHLkV1hNbpXC4m

diff --git a/img/sex/closeRed/chest/6_job_nip.png b/img/sex/closeRed/chest/6_job_nip.png
index bd78a6fb0d1ab62bfc260add480630a720ab0136..f9580838031664a69eb2274158461c96a68ef4ae 100644
GIT binary patch
delta 236
zcmX@i_=j<VL_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EK<*?@7srr_Id3mHave6{VR1PAzrN%$yF^R#<`r`-vvV(G@c<P;
zL4$lr?9D&-gB>Dr8(*(1|75NI{e-qcYV3jUot3x$zlhv-oN>-+e%6%F+by%XW6s)~
zP3KpbAMVi4bS?P(lk>6;R_hx|7)_`8fBR(1_aJ7U2jfGgOXp-A`fFmU7+=~zEs?EZ
X$ZcmfT(>zy2qfa^>gTe~DWM4fa~)T_

delta 179
zcmeyvc$jg5L_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-mJ
zhNp{TNW|f{=M1?T40zlg>gd_d-Mswto!~O<6`dy&v=05==Dx7r1*no?PdfK6f9C27
zJDc;^r}3Xy_<XtdbN&t02OZ|iuey1VF;QP8<L}P7I?RjK$<LTIYp&gam#xf#&l^hW
c?SYzC@nm<oJAMul-T*Sn)78&qol`;+0BC+ijsO4v

diff --git a/img/sex/closeRed/chest/6_nip.png b/img/sex/closeRed/chest/6_nip.png
index aa135d39181583efc3d046e60e197e19497996fc..301081700f4968e0b1291032c9a36cad0e15a6ef 100644
GIT binary patch
delta 138
zcmXS)%{W1#o`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXX@$V7!uL?_ToWK1_d6LgG>G|+uG2;a<Jjdp8mfvEDQ|pJAK)VtQ(Vl
lngrynXO_KO&sdYen6#e3lJo!DJfHy#p00i_EbE*SngGy_E${#U

delta 101
zcmbQuSUy1_o{^b>fnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{c~2L|
z5RLQ62@<R!4DuHw&m^$%vmKV}WMnjx=vm0ZaBUac?!LPbi9n?cp00i_>zopr0RHM8
A%K!iX

diff --git a/img/sex/closeRed/chest/7.png b/img/sex/closeRed/chest/7.png
index 19b25a072bcceb7427843723a70cd0428fcc4f1f..e239b99fab131e0fef238dfe3f20fdf5c3e6be12 100644
GIT binary patch
delta 433
zcmV;i0Z#t>0?z}G7#0Wv0001;w}I>c0004VQb$4nuFf3kks%a+!~p@B009300RLp;
zssm?JlpJyZ000SeQchC<|NsC0|NsC0Hv*f~0003^Nkl<ZScSdU(UOB83<XdyME(CS
zt|3r@iIy2c?~|+KbVFSx8)6JOF>WgL*=wc&fLMa4fdOI~NI3ws{7%pv##aM-4mYD4
z*|t~41$aZa7;;R1#0A)Qjqr6Xt{+3s)&LZV^hqL$m<H^n_B}*{a0Z?mpeqJa@&)Ki
zLbS@Ps~G(OyaHhV>UV%%EVYf(05xC(x&^a|Y2a6R57Z`nf$`$n#O+)7Gr$K<_aZF<
zcx&w=W~hZ}pb_@7FX0Fr$2cH}g#Z)wHqzQcI0AJ0yfW5*1QCedz<G`X{Bi#R>?4O)
zdjQX`N^8L)a(P$>v~mXQ!_5Oo$s%~LYJeu_XCHu;NCHaa=+#OjU;dmO04AV|94aJU
z2QC_b%aJw>)K?^RX`9spJP_SxBqzX%=6L82!54TMv1)kh)&VpwJe6{}{C8s&(1@h6
b9QXirTR{mBA(}p900000NkvXXu0mjfXll4G

delta 365
zcmV-z0h0dD1N;Jz7=Hu<00013M{Ml?000|MOjJbx0046U0IvW5<^TYh006`R0sjC1
z`QFUE4E~N^lequ@00DGTPE!Ct=GbNc009q4L_t(Y$EDQkt;Qe-24GiUg|6_fzzVFu
z3SFUNe`*!cG!f6?N7I(a;4LIdDbdxVd@ZpBpd4&~&Vh*FGJio#s|f&Ag{yKcCIDuV
z(*PU^05y`IC0)jVPJlMjLSzzK;QqQd9wG{+3R-|f0l*_S9ux=6&`G>=C7b0IzymAc
zYHY!pZ$J;gXS&qDKY{kcIszz1wTdH9g)Sln?oaTFGmwRw<y}ua2K0WOj~cgd7(AaK
zkBb0VfxAKZcV-k!dkqKD9!$OC-6*(w7Xdtkv>Ve!-RdpSA?gC(mI%uSKozC$0n$Mh
zIhaxepm)wz$N={q6#y>G!CLViU``9#Lc@UIvt_ky%?AK3{Ri*^^Ex@fmj^Gk00000
LNkvXXu0mjfO>L4}

diff --git a/img/sex/closeRed/chest/7_job.png b/img/sex/closeRed/chest/7_job.png
index 6da0f6379b943cf9096fb3e9a9e9bdd9a5814b71..6085b28dfa1ff023c28325b8e5f1f12ca9f43344 100644
GIT binary patch
delta 539
zcmV+$0_6R=1HS~27#0Wv0000ahER<F0004VQb$4nuFf3kks%s?|77E;17|zjA}Rm?
z00?waPE!E?|NsC0|Nqs>R5Abn0l`T`K~#90?V90ogCH0Lfk^WHZ`=|mMGzAz>S5gd
zsqPiHZ>BY=F#rGn000000001&!diT#FJHjLeftDo<;xdvb>BEw8*#hgZ|}<&aB<(c
zVX(F?q7;DN=F1m<aCJWkcpqY|_wxw+HebGgtNVYyLQ={BrHFPv-N5n|!oAN2a5kR;
z`YgcOVVLWsBizR?FTZ5~di5!w*8=h*oL--X?By>NnA+#}DWKm1rXl(D7_y(Q9e|^J
z3h1eT`@I~IM|&Sbw)B^`kY7Jy0FLn~;A{nq&%{5cj`l}?d!GSN_!Q7n0U_e?%lm-v
zW4w26d;bgru(eMCeHHL{)Er=Vrd&X)uN?q|PXYP@ypK1_2bg}~IzAH@(CW|cecHe`
z`4rGs0V)44pw(9lfYzq~bpghBzjTE0RXYFLZTiJRo8Q*}9Pd+rzJL%h4+*c!X2LWi
zd6jPVwF97f_bEVKK<Nnc<C})0$Jg%H78p0NZUEGNdXEBnD&Q3|GCawTZ(KsaxzfKU
zwfJ=fzBaLT0M!2S02>OB7f{RX$x8W+UsK?#!nFg?vtJDbhzn4&*8rTwm!m!awGRLQ
d0001I=LftyL%CeNGFt!u002ovPDHLkV1keP`fLCI

delta 406
zcmV;H0crlf1iAx|7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0Z>UqK~!ko?U>ySgdh-vZDCuW1zOk^Xu%d}|MUbw<>Y6%5H>qcns1^r^FWNtA`*#2
zB9TZW5)Bnh&W8sebAYM&@BrijD&^4g@ZkZ-93kP*)9~Q|Iu*EC!01`{@Bs7za4LT?
z1V@%5Jl_ED2=Fh?ssP~0L&6FkJ^y`xo}5<!pYXWW)jTeUnE`rnW(5w5zt+{9I6w>M
zQecf7-fg~?GTv!`2F|y@>W->bUN=BH=TZPxYj1`Xj4I~+2Poxi3fN~rYgIWX4$#gS
z6fpOIct%zwyw3p5oJ|3zp9ONfeE@$VpTEFj%q^gIxMM2AI}Omx85B?<p>dz9=<ak0
zCk{a7^A`vSeZIqDu#Be)VrBp;j|XH>V7F{SJo9Z&Kvdz!#XC<F++XoF0F_?`W>6p{
ztzYqlKMO9I0s3;D1*obS;2&HHh(schXa;=%Xo5exVoL+D00000NkvXXu0jG}f_QJN
AumAu6

diff --git a/img/sex/closeRed/chest/7_job_nip.png b/img/sex/closeRed/chest/7_job_nip.png
index a737ed523dc19f961f78723bd7e442aca4016275..faf1cb80043e82e49e46df7257dc4d038f4c659c 100644
GIT binary patch
delta 236
zcmdnb_=j<VL_G&H0|SFfTR<<6Vk{1FcVbv~PUa<$!x`Wc;tHhyr#xQ8oc{PU(@h|U
zxg^LhnBo6_mw;=EK<*?@7srr_Id3l=<UMS_!|ZVUH~-y|2DT>V_JFGIVz~}iB!G%w
z;J|AcceDTBMFhekA6z{n{PXH|>nEbA6Z9VZK4P=BzF7bMLx!?v?M$0~UY;|R_20am
zv(L*p*sX8iV~sg$Gx2^U!^=HPmsmqW>>|&WTQto5Da6{s?Qy%3LH1MOOV%ZyA+}sN
Y%FcL%d7|Nl+q*ylp00i_>zopr0FhK$a{vGU

delta 175
zcmeyvxSw%?L_HHT0|P^znTHOL;tcQ!aRt)9pWphoa`n0miAF#UV@Z%-FoVOh8)-mJ
zil>WXNW|f{=M1?H7;v~f)QPl-J@-=6+Eip!DAO|CJ^81iKi!rBDrAW1Sx|3c(Bvmq
zV!fee!RwzJtZN%Ce`PkZ581q!dC@%!g<p4S*S==gPz&6AncZS<p~54X3GcqMGcf#E
Y#T;yDyHr@HR1jp2r>mdKI;Vst0FkjleE<Le

diff --git a/img/sex/closeRed/chest/7_nip.png b/img/sex/closeRed/chest/7_nip.png
index 67c4bd5eb3046cfb1369ad66b12d6a9cbdf36242..6909ad8cf261ada6e28787252c6068a702d17ad0 100644
GIT binary patch
delta 137
zcmb=J#W+Eto`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXX5GN7!uL?_M##mg8~oB!EgWPv+*x$3^>xWZ_Q2)28MmpgVPl@i$!ef
lXP*7FaKW<Qh7GUT-0B%DCwN530rfL@y85}SV|Get0sxeYEx!N&

delta 102
zcmbQmSTR8&fsvVkfnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{1y2{p
z5RLQ62@<SZ7|yU?ko=Rt#?N+Gu9K0`Orqx?H^ba7tQQZSpZpl8mci52&t;ucLK6U0
CSs^e0

diff --git a/img/sex/closeRed/chest/8.png b/img/sex/closeRed/chest/8.png
index 68ea0abd8b6a2d609d4f24e030171985731bf476..425a1885e6a5feb9d1bc62a0b1d4c4f0f9195dbe 100644
GIT binary patch
delta 446
zcmV;v0YU!%0?Y%D7=H)@0001;w}I>c0004VQb$4nuFf3k0000RP)t-s0001U006H5
z0OkMy!~p@B009300RLp;ssm?JlpJyZ000SeQchC<|NsC0|NsC0Hv*f~0003>Nkl<Z
zScS#c(UOB83<Xe-MEU<O-i9;_#Ne_+Xz!Dw<kT>zG=!2EkAGWY4D(q4;yZ|UV2W4<
z(klQoToZJL@!h~#0$?|C9Dgtl0A+-5F_a7t2jD#K2p>yvdWWv<0VplfCp9sMWxyJ0
zpF=bWS76)#9WjuSHvoWWm03qI?f?)0>|56WEi7Xiw*mJS22Csj&*eQJP51)#17sCT
z6KWEdf%)6#{D13VS^#)z?N`iH3(Ej4*ijRTa09N(Zo>Y7hS&yh6V^1+$mXHm20S&v
zV-bA;I-Osc0i=yWI08A(15D)nO+dzb0y?9G)B=xhq)A{rpaP?hUs=o!z=)6yV12#p
z0eItLm)A+`iS8r649MoGFP7o;3Z0W6(kA@(m9`8J(Km0Y>+SZmDs=?pGN&yjt|I)m
oBLrVSFOk$mx3&k+H~nGY2RU9p!Q4$P0{{R307*qoM6N<$f}*{+mjD0&

delta 368
zcmV-$0gwL71OEb$7=Hu<00013M{Ml?000|MOjJbx0046U0IvW5nE(Lh006`R0sjC1
z`QFUE4F2Psx~KpE00DGTPE!Ct=GbNc009z7L_t(Y$EDTn5yKz|24GiUg{;5|tiTGa
zkQFj^C4Ql?QCffGsyuhEjYdNV0glojOxrtv*sucl0TA&~1%Dts%o>OYo0MZTYd{@|
zWoEWy4WyFz)N<?-g9k_^xe@hZ3EHUng+^?GE<qH~HehVE_5cS!mQJL(LYt)v)Cilg
z1VcRoaR8c?HG_A7%z=Datare=R1e_+#5SXdEpVC)8HEePj5f<t(u%u4pK<C7-vn}A
z*JPG41b4wT1!+-Se*zuf1nqCq0Kyv31K4j7c7PRnCf@tT1JDRcyEcn_0xW@4agW~}
zVr__N%PoN*-v>CeNd0n3bq{EtOPM%b4#Q#o2FhEZd<~@g#0A)te*qtpIy32feLD#N
O0000<MNUMnLSTaQpOZuY

diff --git a/img/sex/closeRed/chest/8_job.png b/img/sex/closeRed/chest/8_job.png
index f840d4c38847512c27ec2974ff5cae49a4bb8664..8ce3dc64e8b4c02b42b4b8fc9b7ee14ac6c24b54 100644
GIT binary patch
delta 598
zcmaFN{F7yZgct`i0|SFfTR<<6Vk{1FcVbv~PUhuAMXCD#DUVk%r(54q(gI3xlmz(&
zGyI2utEWPYfU19cx;TbZ%y~O2dRnuBfJ<w}o&SBurzJDEvPQp6Tk$I-kN5CV8<W^}
z1&$^pbSb2VQU7GO|ANAMXBhR50vV<IHk)mK^qH~VUf-_qSY`I_dw+uB80zO82g%ii
z7K9|7G04$A@VVk6=azHoT;H@__?%-oF#W?L;f%TSx!MwACukMAzf|h-K2`bd{{MIz
zmJHDZAA8kf(;p|E4BnIexNXL|`RxpQnO-z4ob`6LPsAq~{oRcB9w|C(W++$86*s8S
z=KT47`tkhZOMiZ7c6e*Ua)SGVdQrW&!JZzkN-1aI&ow&_?47<rs*+=cZ-eyXc$ZVG
zR;=GS*UWBjxW%F)dM&Tg%G}TLai&jKz4HPyIVKa%2YL$(A6J~)Z79=thj&3|J3}nf
z4(=ap=kGG?s^FL)E>Jgh-=>DA+l@4em`XniEO0#VPiU9)s*+?=JGnZZ$Dgae7)v|U
zi}N#HV(Ob_P_stt`kH)=_~)iM44!gKPgvhfT_dmkd(w+Eq1op}CH@JAn>B=i#Fu#8
zdAy~9u{Oxw-|F$<wzvM)=UA&+ubVZ**%dP?K5%3VxwL-Mv6TnTdHy+4@~l1Ht8(6f
zn0w}Tb~pa0VP|~AR8-s|cQX3i`;V4PnIh??%pRZJr7f%l6m%Y(oWr?9a1QT+x#Im_
im^?lM<I}_XCv*DmphUsPQK7)(!QkoY=d#Wzp$P!D$OkF_

delta 447
zcmV;w0YLuw1mgpc7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0eMM8K~!ko?U~z=!ypVrX+bT}f?7}uwBQzKKYkLh!CEiG3>w`pXO5iQqddk*jL~Q`
z8jVJy(P+8`2It)iRC9o#dG`X<0yZ~+<M8eUsyP8%M{pS4y+A90bOaoZ!n+q}ClG&6
z0N^ORdx3fZ2XG#l4;>=Ix$|G*vIKx==gToZ=Jb7l1OJ>0697jhylJ+PN4#<Y|KZXE
zAS&phf)m4Yg7^v-AONL;+mlq{(|l)mD@e=&+Hko7)BYMM3QqSt2>zJM6<8*0;4pcA
z=HA;1!B$*~09O$Fh5LkO&gT};hKqj@;0iwH+yWYL0RoOGSiIB#s1j_%B?u%9=j&BE
zMz)VJmKOxM1vKL03#1LVFKrYR<aqr8>bL-bc;xujypA}+zwn$OF$-wP1qggcTqwAv
z%uUQQf~(=p0-ACG0>;uF69%lc@ejamNr^LpIc^>-h~)wVa!F~bx7<$tC%h{N8fF2t
pJYBF%foC}j8p2n(3TQNg<^zi+yieA4i17db002ovPDHLkV1j<e!07-0

diff --git a/img/sex/closeRed/chest/8_job_nip.png b/img/sex/closeRed/chest/8_job_nip.png
index bd3128d2f81fd6f619eb7f4a372ae78e8a15abad..02cd4a877c972d7c4c7b0395df29bec532b86d63 100644
GIT binary patch
delta 245
zcmX@c*vd3PqMn19fq_A#Eua@jF%}28J29*~C-V}>;SBHzaRt)<Qy#BkPJeuw=_ZiF
zToU9L%<%ueOTaZnAa}N>i(^Q|oVS-8`5F{>SR9`G@4vRWGbv|@$+<bZ8Fy`A1FC_6
zf=#(M&3{<3vbc)>P^mXJe*9<ZXRZ}_0S+~d*Mp7E#apg#;9~7rcY%NLpQ~qjn8MF#
zE9`D~!4&<vcFz9Um1X~S?+!fy5lVluSU%zD9;Q{|0-+C?Yi5Q!lrf6B$OqWY*Q;i{
dSqZjq!6eyF2bp(fHcGmI_@1tQF6*2Ung9}`Tgd<b

delta 182
zcmZo=I>tCbqMnJFfq@~<%tHrAaR&H=xB}_l&u{%(xq97(L?a-Fu_VYZn8D%MjWi%9
z+tbA{B;xSfbB=rs1{^MdW;r&p&%aE`%j!{yxV1#$Y`wPH5+9He3=bM>*Bw}tGq=`A
zT<k~lt()q_iH_DQcHe2+U@-H#_>bn>GjA8XP1Vw0um6Gl@S5VC`wn>5E1Y=Eed$m0
f#Xoh73=h`xIbC+_HDRpS4>Hcv)z4*}Q$iB}7fVU!

diff --git a/img/sex/closeRed/chest/8_nip.png b/img/sex/closeRed/chest/8_nip.png
index 349f3725420f119679372ce818ca1fc6a66fd9fd..432297f96005abfda08bdeae38124afd28d45c11 100644
GIT binary patch
delta 138
zcmXS)%{W1#o`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXX@$V7!uL?_M#ydg8~oB!6*OcUyI`AY+{_bvOiakiGhKy=oL>&81w00
ll?k`w*;nndXWnPbpykhCS$wMMA<zH@Pgg$|mUT`EO#ozvED`_!

delta 101
zcmbQuSUy1_o{^b>fnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{c~2L|
z5RLQ62@<Sd82?D{R2!UZKDfa>$)SOlEqMb2Lq#@|=IozO#DPi~JYD@<);T3K0RTiu
BAaMWy

diff --git a/img/sex/closeRed/chest/9.png b/img/sex/closeRed/chest/9.png
index f56f502ce881b955b17cebfbbb86ae50ae9af93a..eb47ee319285b9f1a4cc597ad51be309618aa12c 100644
GIT binary patch
delta 444
zcmV;t0Ym=#0?GrB7=H)@0001;w}I>c0004VQb$4nuFf3k0000RP)t-s0001U006H5
z0OkMy!~p@B009300RLp;ssm?JlpJyZ000SeQchC<|NsC0|NsC0Hv*f~0003<Nkl<Z
zScS#c4HJSO3<h8kru_e3Tw{`aY)H3J?_FiWo?I7H+m_<o-haipZ9WRXUGcsLrU*3<
z-T}brErDkUUkw~70DL3+{=gUj7zv?bND&YN;5d4Oj&pIif@5m{Oo`M9MHoU2a8vnn
z-m`=$AUA+V1cYD>0C>-paYxRr0K5m_FTDlugT=g!%YeQGp$RoGF0X;yge|}?Ag(w!
z(Y%RjVE*zcUw<to6+jyqKQh&V8X!U%DTsx@Bw+-cCpQh3uC&#E2ovB;c?QZ^IA#ab
zLt}vE;r+F&jQ~0s-x&er3*lpG!Vrk@8K|)s{|nH3OP~(|GLg!k_QVN5zQkNUTGST6
zXu;+iKj-==s{#Ca?>BHNy_@Kf&xWD~LO|mFL4B9CDK*a(o2mhT1R*(c89r<N0I31)
mV)<tBAD^v`0Wczd0K5RauR<Xijd1Y*0000<MNUMnLSTaQ+O~=S

delta 364
zcmV-y0h9j91N#Dy7=Hu<00013M{Ml?000|MOjJbx0046U0IvW5nE(Lh006`R0sjC1
z`QFUE4F2Psx~KpE00DGTPE!Ct=GbNc009n3L_t(Y$EDSQ6@(xN08m$Og;rn%R$v8I
za0SOcDN{7>z>9mYXYva>dKp3p@wg*~W&8%Q1T+x;0El!n5q}{*j18EXRFz{kHo$?D
zG!bcH18$@oC0)*u;tt?SY9Nln1btSGKnW)pDzE@_1A?CGhqwWNco5fGV_)SKXeD$F
z6HNIEcmv=nEj7pscn$bVvkXA`%~_Q&fe4<(9w>rm;Q>iKrWRMn9U!Ij0M`_P5AYHs
zDJ?DcfHKT^T4m&UQIZ-ykRPD3{1%jXCs2<$h@68BaLy0y0tXoTD?c?Of3*pqpO@@e
zqmlE4F#!T${rcVmL{gt)8x(QHkfXLUnV{cS)sbE4-VSU)FTn=}MKG7h()8p20000<
KMNUMnLSTYIB8)Ep

diff --git a/img/sex/closeRed/chest/9_job.png b/img/sex/closeRed/chest/9_job.png
index bdfd12b8c68a402e89786b8a3f00a4426448d8d2..8649716d0d524d4ba4c26e2372ec31e96adfde87 100644
GIT binary patch
delta 734
zcmV<40wMj^1b_yR7#0Wv0000ahER<F0004VQb$4nuFf3kks%s?|77E;17|zjA}Rm?
z00?waPE!E?|NsC0|Nqs>R5Abn0)k0IK~#90?V8bc!XOYtC5rz4A6KLtSav}O!6hd%
zk0moKb7O6dw;KdO5ClOG1VIo4K@bE%(4}My{F;9C0WR)0AHlEXS0CW&{@b>-M%?f4
zAMaNm;Nt#mdpwMPX^W5o;2-m=4{&uq38+UHV=a$>f6T8wz{UO4UXO6Aj|Yw5{&Ip_
zb0ee)$M1hGKLD%;pcD~SX@umL6T+IcX~K;C&*TRHeE`<>6-eJoWWOu9<faJb?0+6V
z0O$kYcBfi_>C33(&k^{aKHs7v%-TOMq1QjUf2$t=Rs|q`7Z_Ki0erb>LdXa&)8{iF
z2qU!ZpTE(42k7?*89cr32I}9xwLbt@6+pSbaJam{SZ+Q>`ZksS5;|^wDIwp#$3MD%
zn;!sH0+83o3ydX81xf&1g7k-)G21o*&=_fdKEF$#?%Mp^-*^6gKLD%)Kq|mTv=-pk
zUvJg?VLb<bAOYn5s5XEUKyCi=`Dgk8U>yK^3!tm7R~<lH=K%Z+M*{5m6<9vM<UYy|
z04o9TA-x6A4O#(M`wM^^Kn>u&^N;xfKp((Z0q);)`6V9x(iIWFOn@8!2RM2I4E6^A
z>HxkMkVfPMH~?h?@gu4Hiui%-On_wo$K3#9egM#a22d}cTwoIL8RGkc$@Gf!q2x?}
z9zYG?=nXLL2LOElrHI-?1^(p>o<ZF<QH#5_{~mz!nsxjDpbem0K>lF4^yR9UL6!T%
z73}MI;so433NT(n6SVyRpben4fLH>r&}UF__x)dd<re_U32pv3;XZ%m1OT86z(uqa
zSgUY7RPzCb0!p{fe80beB|iXY1316N0Jix<!hXL`Xg$-Z1ON~OLC~4>2UYM};Xg*n
QfdBvi07*qoM6N<$f(R8$hyVZp

delta 564
zcmV-40?Yk?2G<0T7zqRe0002tcD;;|E*gLN-psuW{#b$RFaQ7m0d!JMQvg8b*k%9#
z0qsddK~!ko?U?Jagdhw?X(27x0xi%&TCfG%zsfTKG%~K^g(1JzJqdmX_o-5|X3d&4
zYu2n;vu1r-&^iA+z+(>3HUB)oV}YgCq5I*V2YAd4R62Aw{PO@m6399Lbuaw$06%}?
zSqFg883)c$>$drq_&@@{c<e|VI7ioTfBqdlfB>EZ^zReG(NOFS8s=Z&0|-DW9?)GR
z%7elFa9#ZhE%P97X}-qC5+DKNHFA6n4MzuBfz_>0nK$Kpj9}98C70%F`Nk4p0f7Xx
zal;z!T@_wKx8_qrn6GnbzQRWlSRsE4xblEW08RQ_gXLNfbh$nnsI4!Z|CA3RkODvm
z$OG)h+s65EycB{U33>s(K0ALKA4K3PfIr+afsF~=7OcMnp$vGJk0Njpz?=(UyCBvD
zr42ae0|*EK6usn@rzfyo5DP(R1EhTY3lsrdM+l${Gr;g&ew6(xZxh5qP}+Y0f%h+v
z1z-VP!$Laz4_fpGx>*o&L1_a-K7au2;C~t7osHPxG1@9IpFbBwD)^B1FTetXzs>a4
zmF@5qxJmix0+CCCNY;PK`xmGMun}Uyy~9_;T5EcTzEzMlRJg%wE}x()0kxC?c|xh0
z1&;u9f10_Xynlh$OAu7`4ZI-as$qYpz^qySxBdWX2@M{<a43ub0000<MNUMnLSTY#
CQ~Q1Z

diff --git a/img/sex/closeRed/chest/9_job_nip.png b/img/sex/closeRed/chest/9_job_nip.png
index 9b01071103ccff067330498e07064316af81efb7..2ae07064d63625ff58348499e651eaf50c3b5935 100644
GIT binary patch
delta 255
zcmX@h*v~XUqMn19fq_A#Eua@jF%}28J29*~C-V}>;SBHzaRt)<Qy#BkPJeuw=_ZiF
zToU9L%<%ueOTaZnAa|*!i(^Q|oVV8<xegofxE?(5-M)nRuDa@`pL#QIO0h0xZ<ApM
zDuV(3E1I?K;lc?ke?JZL+%SRRbnM!S_uHR-V=DRl_xB!#?B~1vJ?eMvZTR~;{W<H2
zbLT6aRvmkJv(hY~Dz2fV!E(Q6at!+p>+`H<&T~)T`|#Hz-|;TP$p-5=K;DH|hj6Qe
rUoj2a*<X0+2Q-`&-}Cz)*xrVlc3M&_k+=K)1%UXTu6{1-oD!M<YV>8l

delta 189
zcmeBYI?FggqMnJFfq@~<%tHrAaR&H=xB}_l&u{%(xq97(L?a-Fu_VYZn8D%MjWi&q
z$kW9!B;xSf3x-?`1_CY@O)_m_XT=yT-y&?J&7&dB`R}?;_a^xuE}+r|)?e!yt5|R4
zHR_dT@BaI*!k_!a<d)q+JpX6g+6&BE(wDhw!R^mx%vB3ylIN+t`1Yqkj)PHni?RIz
o_9@)Ee%3z7HLz!3__0^`hq+JfjtTc)0?lObboFyt=akR{0M;c)lmGw#

diff --git a/img/sex/closeRed/chest/9_nip.png b/img/sex/closeRed/chest/9_nip.png
index 08585fa7079dafe657b0527d2d0f23a8cf5458f7..f0244f61698ef502481bfe02e95f406c532afe85 100644
GIT binary patch
delta 137
zcmXS)#W+Eto`aczfno0U#y3EUu{g-xiDBJ2nU_EgTYyi9E0A8roZeY{%n`_9Dhcun
zX80dHQE4lXXX5GN7!uL?_M##mg8~oB!EgWPv+=HK3^>xWZ_Q2)28JJTesdeoWF<t}
l^XL42>=61r{Xi-+?|lYK<71cdfchCcUHx3vF*_wR0RX9DF1P>y

delta 101
zcmbQmSUy1_o{^b>fnmb($8&)cTYyi9E0F%Ta<$5zSyzE9#*!evU<QY0H`0I{c~2L|
z5RLQ62@<T#tUnATz9mdzZ%*t#(!e0ibL;>EL*Q&C%}-p@w*i$hc)I$ztaD0e0stqK
BAHx6u

diff --git a/img/sex/closeRed/chest/base.png b/img/sex/closeRed/chest/base.png
index fea23a48910a83141546db05933280b77c8785b6..f777c0a6cb120bb574038c6740ac7aed52108ee8 100644
GIT binary patch
literal 657
zcmeAS@N?(olHy`uVBq!ia0y~yU~B-g9XObQq)J;rFOXs^4sv&5Sa(k5C6FT>;1l8s
zq>C9C)-y0XV_-PK$T*XM;Xe?iJYL0|9y~>+2q?{2666=m@E;1ynPy*MU|{0+ba4!+
znDh4b>%3+I5#|RMSZ@5b|Hz@KY`);>mQO0b|0L<o&(7?UP%S=els7lA!esN_a+^<P
z{Q3vp&Hb*(b6)be*#j-7d(R%S-uNptL9L~tN>(u5^WmraA3rd?`6p?xcCuLT?g?`J
zk0mN+w~HryulIgoq4IEppR`i`XP}CEzQKobJ*@71_-6Rg_UHM^3dXYc#|qmkJuK~J
z8^MgdV88W$)UO>j5Pq%jh1s@7tQGY!4*zUH?wH>2!#zkpE#B?tMT0A>Pjuzt8t(3{
zxGm#+t3meJ^eGk56XV^U<bp-FH2h*L4Y1M^pSb7jVeSpp<t3b!TpisjbQS8a1NpyC
zH+(z2RANKC3q<{WE)V|ePwXE8Jy$DeaDH!tQPRA}tV`k@{?&pkzTWV6N}bEk&o<9z
zYeO`IGhY6(`AnsQ&Eb>vCqM>%mFHQ<bgIM10USbmZ~M*iTUKX&KSBlUdyt#J&R~nz
zhq^$T@#r?C%Eh3d(r1}sE_C!TOXX$|FQ2U?L0e&c`~myV?`neYmNr0q01Pm&Q{1z*
zF?|vPF=Owjl=Pj?SAlss^b61O<L9D1);IhCyLxx`32|Z1x)}Bow{7+?>|QT6G5^_A
ircd8(_b_b#&#L#L?8np#>&k%Xg~8L+&t;ucLK6TBdN3{k

delta 475
zcmbQp+Qc$Jf|G@rfq~&++1{Rsdb0ID@15Dp^UvVqr3|1TV@Z%-FoVOh8)-oHR8JSj
zkc@k8XWiv(HsEQAJgB|FDeMDRq@wl)ret#m4$ielntR_VnezYr?RTxbC@^~E<P#>o
zM)T9FugRA2i5rM>X#G4QHQ}H|%z-!s`MKFni@rz##Xo3F2)dN!T|7PUc>!a8JyWep
za_Cw?um%sw>mK{=eyDqRLPAC_K~JE(!sXP>?PY2=EP+NWsN7m9a-PMyoqLDq3$rQP
z93}{YOm_Hss^zuYImRa-9SVk7uY`_oRjP_neFNf8Fu%g`s_RuB$biKTzeGK*Gi33J
z7w8A<H#u22aYONr1NGgkUlJME+qo@7Bi1>1>Nw6~+#{p+ARwWBsppj6u5Awr7}qmp
z#^yJc$~GNlJ;Qn^T%m*!?AVNHMYkvN9DK<1pDBZ}pXp^HgK0bWo^XW|0zm!o3u*$U
z%;)|hqxT_<u~x$2@I$6&OuqyYo)<LMGj3_v+hE6|0Q7z_qx(haeYF8VmozvtzAgMG
zD!YsE4#?#NZ#Aau-zf86{a0Q8#3GPv?uYeYsVDN2Sc)_MZC3jUj4%dIS3j3^P6<r_
DwD-i?

diff --git a/img/sex/closeRed/chest/chest_job_big.png b/img/sex/closeRed/chest/chest_job_big.png
index 612e1a615ead709eed5c233fd0cc497462bc9c4e..6132258d01422d6514c59f41da7a3ec88de01753 100644
GIT binary patch
delta 871
zcmV-t1DO1>1&9Zb7#0Wv0002JWHyWd0004VQb$4nuFf3kks%s?|77E}3vsFgXK&gC
zbpQYW33O6UQvm<}|NsC0|Nl1vo74aR0|rS%K~#90?VQ_k>mUpONn+>p|G)T@suUYb
zK*MBYm(^1fX$AGH@hwTXZQ}kJHzn>rkzZML@bJIkgZBjB=jKCM+K=nC@bJIk5fI*$
z5BoQ5JijXcf`@;9oku`;e*w2;dq5wutbvDrl}A8$S3Z<2wsAXzori~ig-1YmSN?Dt
zCWGxEtO4NRdwB$ecjd$5VU=jDkNGXH4QqFRhetqoZvmG@PxmgriMIx5W#Q-M5fI*$
z58?YDTo&B#>uSN<7Cn4@0`PP52ng@We>PaxBOb#(Jm(gFJ$&sD4nI4Ofbi!N@cE1-
z%OcCD-acM}FN-~aIv?MMhetqoe*w#qs9zE+wrEX2t9U+Zyez-)@CXR+%O6Wbzjzt_
z_zLS3QyS<)#2$4%O#psw9s%LK1=LRyBQ6hG>=xDp((v%`Egk{k&nRHT<w9DPO07k0
z35JL7;}H;l{)_@fJU2+M%LXy8PoR%qSNPd^1cX1AfN~Q?mdxCsTtekhoi3o9g4%q#
z&13xo@H6oU2!BQaQ;9BMdQ@i%X!F~w{SUy;!XqI3)db8-s3xGsYs1R~;uJ>s(edHE
zc?5(%lYrX-t--cN6R^d%1k`v<erp53pN~gCcvrrEDWLVWI#Db>M$z*<0><9jjmk8E
zmVhn3J-#*jS@_ZI_ii2m|2Tho0mJu4QjbNqn<ysPGB0w*30NDbEpQaj{$g_vpFR@)
zE<Qd~_Z)u)9sv>1S3tdmNcVVzpPw(<SBRWhUrXTBUC&1W$991C^63=es=W91>){db
z!~#u!B4DXt5-z3lj}Y!#@3Y$QI-e_~$H)%wPCg!hJ;$GgM?eI0<qJs?x=r_G_k$<>
z+6s^D0Pxr6yA`Wv5fJ`m0p(;;Vy{=q#tUjan{LMBh)eH2>I#qT0Pxr60|LT(@?Y`q
zGd@0)L`S}^uT<Cyw>z|G_^a~)0pXnm456k*Un}3zw_P)`1CYOdJ|G}@X935er+K|*
xWCtLB{rq4cAo;O8K@bE%5ClOG1VQ}e_z#v?3fu-SDc1l1002ovPDHLkV1gYOoBIF&

delta 655
zcmV;A0&x9^2eJi_7zqRe0001Zl-rGwE*gLM`1r{={=E$T6I27;00001bW%=J06^y0
zW&i*JMM*?KRCwC$n(cAJAPk0CffZPR6<9$lutHbp*!34i5;UAoG`ZTZek3P7Kzt9_
z=NLP`MF{?ku*UYqYv6tEK79cHox4))a#jWJa|pBx6l>M**w+v6mmC7^0{7YhJjZ`W
zPw*EU0w)OEuZ!XAz)B(k?{Em5A<&mAWz&Oq0Pk@Kv<i&viWU9iS@WI`2flL%v<ghV
zS+OEbs)J6S&LPk$a6N}lV<h~Y=eXo*fTwc^Gz%nVEOi8GE>H2ta|oO#FbAJV3XDk%
zptuK55NH=zDtQw|%>cEKCHLSEXy<=tW$_m%Msdwt8n7N&a}N%Ic7gmpF)sgHL<>GZ
z2JdhPoG6fDSpPe-7IF!LcQ^!26d1$SVErx)JRhLL>G2!_X9-;HV(4g4mS`3Nv*KC(
zz(Y9%P81lVz#No7!E<PS;E@~x|4iVvM61BciKRpXKI;GPIRs7;xEE>zEl_`REwFM5
zy#u%phrrna`L^BqfQCP`ZUsg!p13vwHE;UMXX5YYqvN~EA<!z&@qLo@RR*dXciRI+
zwa+O96S<cYK<OeUWB>Pa2($`hE!JHU$M%jFosJ7V--oL?jV9nCr$6S_<7+ttngtev
ztGGkxR$wXfSNUOhFag&%8T)&Gf<vHLpewJj#`IfS1Xo@S4<_LL90JV(mkZ?*v8Iuy
zDHWlvFMKco_va937U;gdz8w#lE5F+CU;-Y%A<!()Nq;)mew)hc3Ald_fo6e&_#RcR
pP00Q7Q9$5O2m*mXAP|T*#}7Z}+&@3_P-XxC002ovPDHLkV1m1>ApHOU

diff --git a/img/sex/closeRed/chest/chest_job_big_nip.png b/img/sex/closeRed/chest/chest_job_big_nip.png
index d27ab34777c17a07399923303a7c6be2cc39b901..177be6c60fa74ff7eaf427ed003f952dba603cfe 100644
GIT binary patch
literal 216
zcmeAS@N?(olHy`uVBq!ia0y~yU}^xe9XObQ<lYps9w5b79OUlAu<o49OCX0cz$e5N
zNN?pXT*aL3sQf4a$YCxC@(X78|KBCxnj(;!=jq}YQZeW4<%7Hj6nI!1+y8a@X)#Qx
zR#-gqebk;lEua#-K<RvX&wp7ZwiAh~E0=zrbAO4v!~46Z8NME7KJ&)LZoj8p!@d3O
gJOSsefTrAe!@Btf<HO!`dw-Cbp00i_>zopr0EDJLnE(I)

delta 145
zcmcb?xR7yzL_HHT0|UeND|)&>iZj3`#1%+iD9HGmkiw$;WF?TpSQ6wH%;50sMjDXg
z=IP=Xl5y|t`GtZ940xCwCQo`Ne(9xA)<)Zg$9Mh;b9xB^6@fwenz_YuJ~H2*b6$Ms
s73RB^^$A<OHQ8@{-q(1*x9<E#^_#om!x9)6xEL5bUHx3vIVCg!00k5^9RL6T

diff --git a/img/sex/closeRed/doggy/anus.png b/img/sex/closeRed/doggy/anus.png
index b5f3f711a6a91c60ec2f10862307db1d44bfc349..adbd4c3bdb9204490bdef5d188e05853cc7c0803 100644
GIT binary patch
delta 850
zcmV-Y1Fiho1l<OZ7=H)@0000ahER<F001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK0Cg__
z0P0@=06Lcd02gq46}kZc000$GOjJbx0046U0RI30nE(Lh0094F<NyEv+2m4f00007
zbW%=J0RR90|NsA`f2R8Y00P8GL_t(|ob8;^Zo?oD1e3J+|9@X@T;k$1V2&F$M)L7c
zRgP!2W{XKIwU_H-T)^Nwq4}Ws^!f)(U=)A^x7*j(^>2KhXLOnXKh5*$^+y3S6tIlz
zHGS<>QJ&F>_tQL|UVjvDd;w`B#rJcps!#D=I`MvbOg=J10h1K4ZYEi>-Cp#(kKRt8
zhaQy=3{k-01%KQh<9#9B@A>$0RK+uT;R((2>Geke#}`mmtjE(Ubp_`MU7kQY&GYH?
zM*%YwP*-G0+E6sSpWd553q2wq8lr$H3fNQR*Gda%4DY2|6WF51<Re2AFi8Q+Y59A*
zVifPA^91_nQTf0yY67DGT)^wFDm1+37r=G-lKd_M6@O^>DByW&dZ@H2@^L+HqxUAz
zLaXvS3{;@vqkzYFT}0dCpWrQYoww1te6xWHbbJ)>wurXJ^}L0)-$Kf?F5hgR0v#U(
z+$@Vo$sc(O<M~Dd6)5>Apt^{x1u(u%du}220$9G$Km|%Z3iv&Be;d*A>`egOL}|Xs
zKm}Sp3V)~w@*>jmE!tB+-zG}(O$I8^@=-t(5Cud5MZvm_X!#cHE5N>qvV4<)3bcF_
zP!+6;NXxfqUjaRjQb@kZKm}U<^aa#DN@szRZ_}Pf5nEcBZ!}PWl0QWO<rniw>CX-7
z0?ISG{WzKwU@_3^j{;!+fCBau^#zm*pgf`X3x8<SJfB{F6fi>pwNv)CkoAMa2;NWE
zC(uTZ$cKg~VB!L7n-J&ybiDu@Jt7|(qJSw1ct349k`|Dq0M7g9@&wrFQTf0S1x!=G
z|MB{dCtlUdt6JVh*LW+f%I`2xfr>wU0bBfi{C^uZnzzzr-cD=sy9`vI;ZI+{`Vpe8
z-%I}i7;mRbd=IV2?=(<>f{z055<K!2(nBAA3yT7V=XV-v0{R0G-cFYbu+xhCP6HJv
c_%jvo19$Sar3UWXF#rGn07*qoM6N<$f}DPbumAu6

delta 573
zcmV-D0>b^>2H6CV7!3pi0002tcD;-M000t^Q4@do`1rHz=NkY300DGTPE!Ct=GbNc
z00H$$L_t(&-tC&vm4hG<MW+Q?paoi>1^aI$YK%veaGBvJ!wFv=?|s3yBiWB#2|=0*
zxr{B!)BgN`zg{4wuq`tOEPydj`_E7yrI5Z`!~qLn%+vl86j;}4<aMQ*)4^L<0C(gE
z1s8t>wu7=O?-Qfu4J?3r@?*m97g&~aO3Qwof`$VYz?i4~Cn#_+w(I3)Aa7#<jCtCB
zh607LE9r7jm^ZNi=KQGOp+ITGa!MV%g#~a&eo$~xATIH%(Zd^90Qcm_1Rn*CRWlU)
z`wyURf5;mJR|VF)Ie$iW7#d!|0$7u`3BG>{#A8P9YdwEr0j$cK1ZM?4Gm7VoRQ!nr
zuqtm7oE3P^NXN%sF@A*&g0}+K83jFmU;(VlTLf<f;{B8;IeZE58Eoebg69G;==mKB
zU}fGQ{0saG3<%pPQSv($z{<Qqa9tn<HNRs4tjrq(Zv_%OAn?@w{6qzk`uY49$fbX<
z{T-nYhyxbDn5X?GC{P;3g!Tf&+gJc&p7x)i!1YdfMpEeEO)P*pKPosYP&*^Un^*vI
zepK*K;JlY}$dv-f8(0AM<i`Xb1wQNemx{yALCGsv0BiC#!Bv4bKUWGmUc&-dkv9sS
z3T(e63SY;oSOE9ut%9clG@-Fqq>d$rU$MCgjPWWK!2Nlv@aqL$I6x51u{a$900000
LNkvXXu0mjf@p$|o

diff --git a/img/sex/closeRed/doggy/anuspenetrate.png b/img/sex/closeRed/doggy/anuspenetrate.png
index 6166004bacb91b21f4cbaf3a870f365fc28c5050..3937adacdd53ef9e650fec45fc04921af9d3dd46 100644
GIT binary patch
delta 935
zcmV;Y16cfs1+fQ^7=H)@0000ahER<F001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK0Cg__
z0P0@=06Lcd02gq46}kZc000$GOjJbx0046U0GR*){{R5y0094F<NyEveoqRN00007
zbW%=J0RR90|NsA`f2R8Y00S6FL_t(|ob8;^Zo?o9Mc1bL|9@XzJCp$lHrKwOpv62*
zZO_H#1d>kLz8>%KMGT&2XnwHsv;7ZPzz{$MJm2H-H?H6xje+wVUC(c=J@I5h2)J0l
zwmqLI#23Z#JDvE~@7Qxt-cRTGy$i|q9|EoykVcAly{t`)<jZB;U+JZAbjf?F=lc%<
zs|d(V>>*ea<A3-v;rn;wS8em-^!Wm?RnPYy0<IU3i!C=2+62p&bWZsEloL`T63@`}
z{Pybk{zJg^0@@MhCT8)n0wjT>r3FN3zW)%gf&e)phe#WF1g|Y(ez)BON9zmNub%He
z1gs%Ii_n`G!?zX@=lyhl0WqFP2my--_<XEx0gD*L*MCd6ZAU)mwinPxx99g<fbN7*
z3m5`u0rfy5X7cF^eLdt0z(Z@i^#XJzumLmqTMIZh(cZ}O__~2I6{#Pi@e4pY#^n0J
z1U6tEe|rH^6ZJ-($79C`N82v|bbdI24VcG=0I`X36V2oq0T}JM0MH{8Oke|M^0ya&
zY@#0DDt`dw6Mf|In|Po0TmbkH3?=jeLV#BNbOHTa8B&0k@6&bxwwow3KbW8ggn)|$
zNSi2cWM2Uozp4QAAp%O!146)}0&*L^0x+Ii0EG6<&mX}>f*ue8LV$Y#5IO{e06jn!
zuy15<0SLdY0QMoINYDd9z_J4NHoOHO{JH}8BY*fWK@SK47YmSn6_Eqj0(^7`*h0V{
z0qr;Qhti)L$N@e6zYAdd4*^v5Lj-6M@&S|uu)K%H1?aSQ{!##$5CWL$2MLfqqTPb`
zFA^hoD_#CNjiY_@ml<sTAz)<z{af%D-by1!2uAznFEiNwL%<pW&L8`{f<1<f;Vty>
z2!HX@zWL7rh=dTZjDX{)|M5f}{dspT-==F;=26-@|2c#0KLk+KPZUt%=W%=t8_jF<
z`7zQ@d*-h*q|d+!Y``4;_5${=5OTa;0LSZeZvic|XMW@eG$gPAGx!idZ$Xadjt~oN
zpC35_O$ltk3_b+Bv<-w6!0<ASETDz9&LEH9#Nh-sU<Q9D0Y91E-6aCr+WY_j002ov
JPDHLkV1k|`p_c#v

delta 620
zcmdnU-oZLSf|rGvfq~&++1?%?B{VTmxc<kFAJM<A-34+POM?7@862M7NMm4NQt@<g
z49U3ncGk_p!v;L87n!0HxHB4ccl-}qWNqWHPQrSoL~>o_o(t76!9|}EIUU=$ciL=!
zQT6IM@4xa!iNm|<&K=%rB`uNESn;O5p0W4ziG;2nUE=eCx}LEl0L97`Hmpfi`l|J=
z{$p*w)NQE)OdoH&cTQOCQFc^!AHR)U|J&5(Rl?jylJ_$=>XzB7u5S9#x1I57u7a3o
z1M8!W_ZuC|3PaC)IJ7{PK}VqfuN+HPXReBU>a(X}TUUWa^jJ=Hu6o4w|K6gL?GXxc
zziT;OIPVrN|FO~8cIUL37LXa84O!($^?l1r_VMNJYXyl+KM*=`?k5p@u8>?uW{~B^
zjeDF9+nDDGf!*h;u>QvRjJ|%>DJ-`t-h5ZPFfZ`z<q7R2g`XAkH#pdQ+bx_iZ?jp#
z5ow)<=j-+xe)z@|Wv|-I(7ZoL;SzfW-wvSwfeQw^8^wSo|94N&+J98Oabf*|s#A*_
zrtJ@D*ynPFF`kKw>DO+i3hveJjXwl`WH*NJ9?4R0Jdn>F01Su_{tUy0J^j9oTp+ix
zH~yLXNwV)D-}{Gu_nSf-xS+Bv|ASm!z9883+>NjIPFa($`OM5Nf1;vT$MHIKrsr05
zL4`ic4Ne-@Txg1pPzV7A4d<IbQHEze3LTF+a0C<&UI~A-1J9iQ$aP(M%SMpDgcb-h
r@on$ug@jSDjf9D~0Z3y1-UH$q%n>qjqRJ7#1jOL!>gTe~DWM4f#8?|v

diff --git a/img/sex/closeRed/missionary/anus.png b/img/sex/closeRed/missionary/anus.png
index b5f3f711a6a91c60ec2f10862307db1d44bfc349..adbd4c3bdb9204490bdef5d188e05853cc7c0803 100644
GIT binary patch
delta 850
zcmV-Y1Fiho1l<OZ7=H)@0000ahER<F001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK0Cg__
z0P0@=06Lcd02gq46}kZc000$GOjJbx0046U0RI30nE(Lh0094F<NyEv+2m4f00007
zbW%=J0RR90|NsA`f2R8Y00P8GL_t(|ob8;^Zo?oD1e3J+|9@X@T;k$1V2&F$M)L7c
zRgP!2W{XKIwU_H-T)^Nwq4}Ws^!f)(U=)A^x7*j(^>2KhXLOnXKh5*$^+y3S6tIlz
zHGS<>QJ&F>_tQL|UVjvDd;w`B#rJcps!#D=I`MvbOg=J10h1K4ZYEi>-Cp#(kKRt8
zhaQy=3{k-01%KQh<9#9B@A>$0RK+uT;R((2>Geke#}`mmtjE(Ubp_`MU7kQY&GYH?
zM*%YwP*-G0+E6sSpWd553q2wq8lr$H3fNQR*Gda%4DY2|6WF51<Re2AFi8Q+Y59A*
zVifPA^91_nQTf0yY67DGT)^wFDm1+37r=G-lKd_M6@O^>DByW&dZ@H2@^L+HqxUAz
zLaXvS3{;@vqkzYFT}0dCpWrQYoww1te6xWHbbJ)>wurXJ^}L0)-$Kf?F5hgR0v#U(
z+$@Vo$sc(O<M~Dd6)5>Apt^{x1u(u%du}220$9G$Km|%Z3iv&Be;d*A>`egOL}|Xs
zKm}Sp3V)~w@*>jmE!tB+-zG}(O$I8^@=-t(5Cud5MZvm_X!#cHE5N>qvV4<)3bcF_
zP!+6;NXxfqUjaRjQb@kZKm}U<^aa#DN@szRZ_}Pf5nEcBZ!}PWl0QWO<rniw>CX-7
z0?ISG{WzKwU@_3^j{;!+fCBau^#zm*pgf`X3x8<SJfB{F6fi>pwNv)CkoAMa2;NWE
zC(uTZ$cKg~VB!L7n-J&ybiDu@Jt7|(qJSw1ct349k`|Dq0M7g9@&wrFQTf0S1x!=G
z|MB{dCtlUdt6JVh*LW+f%I`2xfr>wU0bBfi{C^uZnzzzr-cD=sy9`vI;ZI+{`Vpe8
z-%I}i7;mRbd=IV2?=(<>f{z055<K!2(nBAA3yT7V=XV-v0{R0G-cFYbu+xhCP6HJv
c_%jvo19$Sar3UWXF#rGn07*qoM6N<$f}DPbumAu6

delta 573
zcmV-D0>b^>2H6CV7!3pi0002tcD;-M000t^Q4@do`1rHz=NkY300DGTPE!Ct=GbNc
z00H$$L_t(&-tC&vm4hG<MW+Q?paoi>1^aI$YK%veaGBvJ!wFv=?|s3yBiWB#2|=0*
zxr{B!)BgN`zg{4wuq`tOEPydj`_E7yrI5Z`!~qLn%+vl86j;}4<aMQ*)4^L<0C(gE
z1s8t>wu7=O?-Qfu4J?3r@?*m97g&~aO3Qwof`$VYz?i4~Cn#_+w(I3)Aa7#<jCtCB
zh607LE9r7jm^ZNi=KQGOp+ITGa!MV%g#~a&eo$~xATIH%(Zd^90Qcm_1Rn*CRWlU)
z`wyURf5;mJR|VF)Ie$iW7#d!|0$7u`3BG>{#A8P9YdwEr0j$cK1ZM?4Gm7VoRQ!nr
zuqtm7oE3P^NXN%sF@A*&g0}+K83jFmU;(VlTLf<f;{B8;IeZE58Eoebg69G;==mKB
zU}fGQ{0saG3<%pPQSv($z{<Qqa9tn<HNRs4tjrq(Zv_%OAn?@w{6qzk`uY49$fbX<
z{T-nYhyxbDn5X?GC{P;3g!Tf&+gJc&p7x)i!1YdfMpEeEO)P*pKPosYP&*^Un^*vI
zepK*K;JlY}$dv-f8(0AM<i`Xb1wQNemx{yALCGsv0BiC#!Bv4bKUWGmUc&-dkv9sS
z3T(e63SY;oSOE9ut%9clG@-Fqq>d$rU$MCgjPWWK!2Nlv@aqL$I6x51u{a$900000
LNkvXXu0mjf@p$|o

diff --git a/img/sex/closeRed/missionary/anuspenetrate.png b/img/sex/closeRed/missionary/anuspenetrate.png
index 6166004bacb91b21f4cbaf3a870f365fc28c5050..3937adacdd53ef9e650fec45fc04921af9d3dd46 100644
GIT binary patch
delta 935
zcmV;Y16cfs1+fQ^7=H)@0000ahER<F001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK0Cg__
z0P0@=06Lcd02gq46}kZc000$GOjJbx0046U0GR*){{R5y0094F<NyEveoqRN00007
zbW%=J0RR90|NsA`f2R8Y00S6FL_t(|ob8;^Zo?o9Mc1bL|9@XzJCp$lHrKwOpv62*
zZO_H#1d>kLz8>%KMGT&2XnwHsv;7ZPzz{$MJm2H-H?H6xje+wVUC(c=J@I5h2)J0l
zwmqLI#23Z#JDvE~@7Qxt-cRTGy$i|q9|EoykVcAly{t`)<jZB;U+JZAbjf?F=lc%<
zs|d(V>>*ea<A3-v;rn;wS8em-^!Wm?RnPYy0<IU3i!C=2+62p&bWZsEloL`T63@`}
z{Pybk{zJg^0@@MhCT8)n0wjT>r3FN3zW)%gf&e)phe#WF1g|Y(ez)BON9zmNub%He
z1gs%Ii_n`G!?zX@=lyhl0WqFP2my--_<XEx0gD*L*MCd6ZAU)mwinPxx99g<fbN7*
z3m5`u0rfy5X7cF^eLdt0z(Z@i^#XJzumLmqTMIZh(cZ}O__~2I6{#Pi@e4pY#^n0J
z1U6tEe|rH^6ZJ-($79C`N82v|bbdI24VcG=0I`X36V2oq0T}JM0MH{8Oke|M^0ya&
zY@#0DDt`dw6Mf|In|Po0TmbkH3?=jeLV#BNbOHTa8B&0k@6&bxwwow3KbW8ggn)|$
zNSi2cWM2Uozp4QAAp%O!146)}0&*L^0x+Ii0EG6<&mX}>f*ue8LV$Y#5IO{e06jn!
zuy15<0SLdY0QMoINYDd9z_J4NHoOHO{JH}8BY*fWK@SK47YmSn6_Eqj0(^7`*h0V{
z0qr;Qhti)L$N@e6zYAdd4*^v5Lj-6M@&S|uu)K%H1?aSQ{!##$5CWL$2MLfqqTPb`
zFA^hoD_#CNjiY_@ml<sTAz)<z{af%D-by1!2uAznFEiNwL%<pW&L8`{f<1<f;Vty>
z2!HX@zWL7rh=dTZjDX{)|M5f}{dspT-==F;=26-@|2c#0KLk+KPZUt%=W%=t8_jF<
z`7zQ@d*-h*q|d+!Y``4;_5${=5OTa;0LSZeZvic|XMW@eG$gPAGx!idZ$Xadjt~oN
zpC35_O$ltk3_b+Bv<-w6!0<ASETDz9&LEH9#Nh-sU<Q9D0Y91E-6aCr+WY_j002ov
JPDHLkV1k|`p_c#v

delta 620
zcmdnU-oZLSf|rGvfq~&++1?%?B{VTmxc<kFAJM<A-34+POM?7@862M7NMm4NQt@<g
z49U3ncGk_p!v;L87n!0HxHB4ccl-}qWNqWHPQrSoL~>o_o(t76!9|}EIUU=$ciL=!
zQT6IM@4xa!iNm|<&K=%rB`uNESn;O5p0W4ziG;2nUE=eCx}LEl0L97`Hmpfi`l|J=
z{$p*w)NQE)OdoH&cTQOCQFc^!AHR)U|J&5(Rl?jylJ_$=>XzB7u5S9#x1I57u7a3o
z1M8!W_ZuC|3PaC)IJ7{PK}VqfuN+HPXReBU>a(X}TUUWa^jJ=Hu6o4w|K6gL?GXxc
zziT;OIPVrN|FO~8cIUL37LXa84O!($^?l1r_VMNJYXyl+KM*=`?k5p@u8>?uW{~B^
zjeDF9+nDDGf!*h;u>QvRjJ|%>DJ-`t-h5ZPFfZ`z<q7R2g`XAkH#pdQ+bx_iZ?jp#
z5ow)<=j-+xe)z@|Wv|-I(7ZoL;SzfW-wvSwfeQw^8^wSo|94N&+J98Oabf*|s#A*_
zrtJ@D*ynPFF`kKw>DO+i3hveJjXwl`WH*NJ9?4R0Jdn>F01Su_{tUy0J^j9oTp+ix
zH~yLXNwV)D-}{Gu_nSf-xS+Bv|ASm!z9883+>NjIPFa($`OM5Nf1;vT$MHIKrsr05
zL4`ic4Ne-@Txg1pPzV7A4d<IbQHEze3LTF+a0C<&UI~A-1J9iQ$aP(M%SMpDgcb-h
r@on$ug@jSDjf9D~0Z3y1-UH$q%n>qjqRJ7#1jOL!>gTe~DWM4f#8?|v

diff --git a/img/sex/doggyRed/active/body/doggyactivemouth.png b/img/sex/doggyRed/active/body/doggyactivemouth.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f9af45926cb80e844396efed5aee6dc37b31e6d
GIT binary patch
literal 473
zcmeAS@N?(olHy`uVBq!ia0y~yU;#228911Ml+^DpVn9kE*(1o8fuTx`fuW&=f#DZW
zsNn?zL#aLk!>f1(2CL}|4B`bfqPrM@5<CGuA+A7rKLf)m=Jfyn|NoAesRiV-lmz(&
zGXVLUbsai@7WjC&IEGZrd3)g?Z-WC5^FfFIu8TdcGpw(E<HP#x98d#2!H3JmckUIs
z|Na}K5VxRq|KB=I0sRkhXBpmp_in6c{Py?T@1+j=9IPFX6fB^p`|#Rz;0(LRHO9mg
R-7I^MI!{+Wmvv4FO#rysP;>wQ

literal 0
HcmV?d00001

diff --git a/img/sex/missionaryRed/active/body/activemouth.png b/img/sex/missionaryRed/active/body/activemouth.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b67043cf483a17fdf39c3e6ddf8400f07836930
GIT binary patch
literal 520
zcmeAS@N?(olHy`uVBq!ia0y~yU;#228911Ml+^DpVn9kE*(1o8fuTx`fuW&=f#DZW
zsNn?zL#aLk!>f1(2CL}|4B`bfqPrM@5<CGuA+A7rKLf)m=Jfyn|NoAesRiV-lmz(&
zGXVLUbsai@7F2t>IEGZrd3$ps?-2(c7Q^|!^>5wyahY9DViVKbB~@}jE%XO<b3X6e
zp1))H-a3&E@r?8N>*ZM=v6}6dUVtKS>+|i`?u`|V-~N326{rxmz;-{9^e5I^`4f=D
zPl#JQ|Hf**^?E<kN2a$w-+o=(z(jwKA=&u<6Qk}##>DO;c7Y&KPgg&ebxsLQ0I~UL
AVE_OC

literal 0
HcmV?d00001

-- 
GitLab


From f514284ce263aeeeb089849e7b6b4d7b6b3a670b Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Sun, 21 Aug 2022 21:17:25 +0000
Subject: [PATCH 05/50] Update classic and default tail colours to greyscale

---
 .../demon/flaunttail/classic.png                | Bin 286 -> 331 bytes
 .../demon/flaunttail/default.png                | Bin 291 -> 335 bytes
 .../demon/rightcover/classic.png                | Bin 286 -> 324 bytes
 .../demon/rightcover/default.png                | Bin 305 -> 343 bytes
 4 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/img/transformations/demon/flaunttail/classic.png b/img/transformations/demon/flaunttail/classic.png
index 5743ffbfe12a738bb25321d984e9d117b6b89caa..b6913e14ab5c11e0c519dc2d8f19db71289f064a 100644
GIT binary patch
delta 297
zcmbQobed^`cKy1tva;sp=5K00PctwuFqQ=Q1v5B2yO9RsBze2LFm$lWdH^|`1s;*b
z3=G`DAk4@xYmNj^kiEpy*OmPl2fv_*PO3+BBv5F#r;B4q#jUs345u|4@VEw=-kLA{
zUjOTwB94{8f1Q3jxfl2FXo8O@P$d}DL+JzId)1F0XRca*Ykh*9biKoYT|(dD4d(aS
zD=k=L8Y6nY>0txk_rT+~3rrr|a-MtTeL<aF!q>k7Y^UQd^7pXEJl@^px<`NiuQv@|
zOz*x|%$502*%0=Fe_F$3=Bk2!f{b(THp<Rpz0CO6E@1OvjlVKdd>zNbuRdgCP=eYI
bqV_+L*XmP0T70*AF^KEw>gTe~DWM4f8Ypji

delta 251
zcmX@jG>>V5c0EG~TT>?QJj-H<2@DJjj3q&S!3+-1ZlnP@hdo^!Ln>~)y=E<R$Uwlw
zQMKA$b(g&1@*`q~o$43DF3#nz`@x<JREPrpguH(8r@~>a<u&aa>7UscKYK;IPndr;
znx*H3%(<L<3JVTBU-9Vphl~SXc|wEsmmK>0vmx@gTFsq$dApwtj~TDm^gd8|cli7R
zr4kMa&jWS+>c1Z|-j~j3yRUGA`-R|yd(Ibk?{IcF`~34?CGKy$Ot1bq`aUzgwBNa%
j`BCMh`^v~}c`(0*L90*wXtJoUA4uHO)z4*}Q$iB}aeZf8

diff --git a/img/transformations/demon/flaunttail/default.png b/img/transformations/demon/flaunttail/default.png
index 35a006f3ed867baf07c65caad644f7b2350f4195..a24e10946f9912adc4fc97b5a4134af9ea819a1f 100644
GIT binary patch
delta 300
zcmZ3?be?H~PJL5T)4X}}4j(=&=B=2)z`(#*666=m;PC858i<qR?e4<R!7A$k<Zu>v
zL>4nJa0`PlBg3pY5<o%r5>H=O_GcXY0(#bmK6qUK3hnW9aSW-r_4ew<sm%rgt`|L*
z?f0Cr<795GcSKLJyS;!_b-vvP0gg~cpjw7{5CH`>SJ&U~eSDj_%6IMj1Uu<^hXXO3
z+7U-i9+MXgxG3d!bbUgxL;LR)k8^jJKDgyP_saT$y7~iO{tB|4j=#vdjXmb^>L%Ac
z`S!JC4yugb>-YHa{ityewmZmSVY|TmoW0V5&E^{pZB8h6*w26EjX_jtiGz(@sA@Yq
d%z6<0N4=iuvr%g8k}I_!uBWS?%Q~loCIDb3Yajps

delta 255
zcmX@lw3umvPJIYlQzq}cMuEc*Wi?+gFfcHd1o;IsI6S+N2IL&|ba4!+xb^nxM$tnC
z0xpiK*XIkVns{bUX~<0y%3tu<aI*eCiRd0ipi*S;A=EZb`uT0<tg{>E9kiQm&N0LN
z5Le!#GtYFH+)DV<&GH2T9#)5Z%-&)8prWE(Yi0byy7~iaUMudoTOVilv*9h{@tWQT
zYH`!&AMC%Nn4rRV-E!WW?d&yj3nc5B6Z99jJN)8tO)qS3nDzbnbw{x`(kxegw$D2A
n+U9h<rNTV*pSDcMj`?>|n(4Dqs@11FPmr*utDnm{r-UW|LSJM5

diff --git a/img/transformations/demon/rightcover/classic.png b/img/transformations/demon/rightcover/classic.png
index 40da3849e5b9345058ba8ca5dacfa60f661889ab..52f61810dda48b9f9a2cc65dd143f7645de2ddb2 100644
GIT binary patch
delta 290
zcmbQobcAVwcD+SeSy^*)bCun$vkVLjj3q&S!3+-1Zlr-YN#5=*3>~bp9zYIffk$L9
z0|U1(2s1Lwnj--eWH0gbb!C6X!7nJn67cu(VxZ6#PZ!6Kid%258S))+;Bj>{&$F02
zd#}9dau%hFmv(GebLNYE<-|#$N<gI`P!FLP7#jA^JN)}&!}07gd-(#t-gm5L*h8+q
zs54VouYKk%kaHw6?!h0eYiviJi<~_9x5gnQwK)DX^Q`$7w?FvCxY17Gy-dMghnsh<
zKWljX?B<>K{3{N!&*1-YZ||(%PZ@94cKUtRkmv7sHSekVH1;q5)wi)j?Ue@6cMeI1
Ww5m?6f2f@c;(EIJxvX<aXaWEgCvUX?

delta 251
zcmX@YG>>V5c0EHT@4OJUCi8P@lNcBn7)yfuf*Bm1-ADs+4tu&dhE&{od(DvVu!4ZA
z<1CXodcN=6&uYqcTw3<?XjjFu_=;^gF4;h($l!qg`A0uLH5^}Ew$Co%T%eWy0=tBs
zoW_!UW((enzIw)bg?)>pp22?6<7`{LYnDv1b+m|=zwqmX*o&8r5pn|m+*UvM#`yBz
zSH_q5B_#*`H8hES`(t65kUwwF;eX<cCz)O{UtwQ!cXESiO@)KM{US-Zr%xGm_w?7i
lTk6jK<a_63W+b=dJ!G;oaW*XJTfzqt^>p=fS?83{1OTD~WnBOO

diff --git a/img/transformations/demon/rightcover/default.png b/img/transformations/demon/rightcover/default.png
index d1b0c2851150dca4b3c483a83361768ce3880530..03f2f7b7aee3dac1a5821ff4550ab744b0ddfbed 100644
GIT binary patch
delta 311
zcmdnUbe(B}W_@B(PFY!5b93|L$&>3oZ9c%jz`$4%<QL4~@a#q!h?C^)?!wT)D(eB{
za29w(7Bet#3xhBt!>l<HKtc8rPhVH|XB_;3!YV44Qr7^5j(EB_hE&{odrgt=kb{Wp
zMZ?86Z<!}Y$g-Wic0pqSr`YGCr<Xkcas8g!+xjKRK=sJrK>Ya+c5(%kDc^rKT>mP0
z_c`;s*J42O+Nu|J@&Tb2Yt0hm!cV+qeZqV!D=y)$);3;=`N1h_K-GrXX5Y6~I(#<%
zB{s({AxGZeyiCC!hs`_J&t>kLeg0Y9{{}8Q2fGK=-?QGC^Ut_DJ;SvBlR?FS74IVV
l9ec+3_kZVIW+aFBJ>=!rH0rIG>6QZ$^>p=fS?83{1OP-&d8z;a

delta 273
zcmcc4w2^6oW<3J~LyN%iOx}4RY)$9?Sgr)}8B2ovf*Bm1-ADs+E_=E-hE&{odrdLu
zsDVW5MTwGa-%M5?UT`zYMD2o6#2L}@L)ORtpS<oj`=kU=IWqXL+`V$2+=oy1=Dug&
zQ)jp8^WTR4zhOYmo4p|R)=jLJe%9w5*c1NZEcXlc9$CE&_1b;B68D#Td}Dc7W1nzl
zs;<H1<_&TJ|J=e4US?nN`#bZc`!8NJ{AT6~+wuJRNyhKbPFm0TucQ#EP}@*<U~9Ed
z0k6EA!R7vpcK1r#gqH6U=U2bH$oRAN(HA6VH7x(Y%6K&6=(Mba#|#Wy3=E#GelF{r
G5}E)=l6e#W

-- 
GitLab


From d479eb50a753ef515a901499f1eab16bb77ffc5b Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Sun, 21 Aug 2022 21:30:32 +0000
Subject: [PATCH 06/50] Docs for ironman

---
 docs/ironman-debugging.md | 48 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 docs/ironman-debugging.md

diff --git a/docs/ironman-debugging.md b/docs/ironman-debugging.md
new file mode 100644
index 0000000000..caad657147
--- /dev/null
+++ b/docs/ironman-debugging.md
@@ -0,0 +1,48 @@
+## Ironman
+
+### Summary
+
+Ironman is a gamemode option given to players to try to facilitate an experience designed to prevent them from cheating.
+This means debugging and exporting are more difficult, it's exactly the type of mechanic ironman aims to prevent.
+This causes us pain when figuring out problems derived, and reported, by ironman players.
+
+### Debugging reports
+
+#### Exporting
+
+In ironman, autosaves are the only available way for the end-users to export.
+
+For debugging purposes, there is a secret order of actions that can be taken to export data.
+
+1. Save the current game. You are taken to the main menu.
+2. Open the save menu.
+3. Identify the save slot, and mouse over the coin icon.
+4. Click the coin icon 3 times in succession.
+5. Click [Copy Text Area]
+6. Paste the text to a developer/report.
+
+#### Importing
+
+When importing an exported string of data, such as retrieved via the exporting guide, you must use the browser console to deserialise it.
+
+The data given to you will be a JSON object with two parts:
+
+-   Data
+-   Details
+
+**Data**: This is the full save object of that slot, typically located in your localstorage.
+
+**Details**: This is the full details object, which contains metadata about your save.
+
+When ironman was created, the save details structure was chosen to house the signatures of the ironman games, which are calculated using a hashing algorithm. Save details are never exported to the player to look at, and require them to access localstorage to even view. Therefore, we package the save details object with the export to ensure all information regarding ironman is available to the developer.
+
+##### Import functions
+
+Two functions are available to you to decode people's ironman saves:
+
+-   IronMan.importDebug(data: string): CompositeSaveObject
+-   IronMan.importAndLoadDebug(data: string): CompositeSaveObject
+
+**IronMan.importDebug**: Returns the CompositeSaveObject, which is essentially an object containing two properties: Save-data, and the save-details. Useful for seeing what the deserialised data gets turned into, without having the game perform any processes on it.
+
+**IronMan.importAndLoadDebug**: Returns the CompositeSaveObject, similar to _importDebug_, but also loads the data into the current state, as if you were loading a save game.
-- 
GitLab


From 43632453d4f12f002e7fc407e33fda6eedb27d5b Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Sun, 21 Aug 2022 21:42:41 +0000
Subject: [PATCH 07/50] Expand exponential curve out from randomExp

---
 game/03-JavaScript/base.js | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index f76ca35a60..29efd204b0 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -539,6 +539,29 @@ window.mobBtnShow = function mobBtnShow(){
 	$('.mob-btn-h').hide()
 }
 
+/**
+ * This function takes a value, and weights it by exponential curve.
+ * 
+ * Value should be between 0.0 and 1.0 (use normalise to get a percentage of a max).
+ *
+ * An exponent of 1.0 returns 1 every time.
+ *
+ * Exponents between 1.0 and 2.0 return a curve favoring higher results (closer to 1)
+ *
+ * An exponent of 2.0 will return a flat line distribution, and is identical to random()
+ *
+ * Exponents greater than 2.0 return a curve favoring lower results (closer to 0), reaching to 0 at infinity.
+ *
+ * For example, see:
+ * https://www.desmos.com/calculator/87hhrjfixi
+ * 
+ * @param {number} value Value to be weighted
+ * @param {number} exp Exponent used to generate the curve
+ * @returns {number} value weighted against exponential curve
+ */
+function expCurve(value, exp) {	return (value ** exp) / value; };
+window.expCurve = expCurve;
+
 /**
  * This function creates a random float 0.0-1.0, weighted by exponential curve.
  *
@@ -551,15 +574,12 @@ window.mobBtnShow = function mobBtnShow(){
  * Values greater than 2.0 return a curve favoring lower results (closer to 0), reaching to 0 at infinity.
  *
  * For example, see:
- * https://www.desmos.com/calculator/o3rxbwzvdu
-
+ * https://www.desmos.com/calculator/87hhrjfixi
+ * 
  * @param {number} exp Exponent used to generate the curve
  * @returns {number} random number weighted against exponential curve
  */
-function randomExp(exp) {
-    const x = State.random();
-    return ( x ** exp ) / x;
-}
+function randomExp(exp) { return expCurve(State.random(), exp); };
 window.randomExp = randomExp;
 
 /**
-- 
GitLab


From 8bc606552c3174f28c0faa5f84ab7727404408d2 Mon Sep 17 00:00:00 2001
From: Purity <purityguydol@gmail.com>
Date: Mon, 22 Aug 2022 12:37:59 -0400
Subject: [PATCH 08/50] Sydney Science preparations

Some code prep for implementing Sydney in Science class.
Also causes Pure Sydney to be more strict on the player skipping class to talk to them, and gives Sydney a cameo when the player interrupts Sirris' second period Science class.

This is my first real MR in a while, so sorry if there's any jank.
---
 game/base-system/time.twee                    |  8 +-
 .../loc-school/classes/science.twee           | 54 ++++++++++---
 .../overworld-town/special-sydney/temple.twee |  2 +-
 game/overworld-town/special-sydney/walk.twee  | 18 +----
 .../special-sydney/widgets.twee               | 78 +++++++++++--------
 5 files changed, 99 insertions(+), 61 deletions(-)

diff --git a/game/base-system/time.twee b/game/base-system/time.twee
index 581e775cba..3e7f07fef5 100644
--- a/game/base-system/time.twee
+++ b/game/base-system/time.twee
@@ -1123,7 +1123,7 @@
 		<<unset $averyDismissalSceneWait>>
 	<</if>>
 
-	<<if $sydneyScience isnot 1 and $days gte random(7, 12)>>
+	<<if $sydneyScience isnot 1 and $days gte random(14, 21)>>
 		/*<<set $sydneyLate to 1>><<set $sydneyScience to 1>>*/ <!-- Uncomment this when Sydney can show up in Science Class -->
 	<</if>>
 
@@ -1148,7 +1148,9 @@
 		<<else>>
 			<<set $NPCName[$NPCNameList.indexOf("Sydney")].title to "faithful">>
 		<</if>>
-		<<unset $sydneyLate>> <!-- Remove this line when Sydney can show up in Science Class -->
+		<<if $sydneyScience isnot 1 or $sydneySeen.includes("science")>>
+			<<unset $sydneyLate>>
+		<</if>>
 		<<if $schoolday is 1 and random(1, 4) is 1>>
 			<<set $sydneyLate to 1>>
 		<</if>>
@@ -1172,6 +1174,8 @@
 		<<set $sydneyDaily to {}>>
 		<<set $sydneyDaily.sex to 0>>
 		<<unset $sydneyScienceWarn>>
+		<<unset $sydneyClassWarn>>
+		<<unset $sydneyScienceWalk>>
 		<<unset $sydneyPunish>>
 		<<unset $sydneyTempleSkip>>
 
diff --git a/game/overworld-town/loc-school/classes/science.twee b/game/overworld-town/loc-school/classes/science.twee
index b88a6177bb..97485ca153 100644
--- a/game/overworld-town/loc-school/classes/science.twee
+++ b/game/overworld-town/loc-school/classes/science.twee
@@ -33,7 +33,12 @@
 			<br>
 		<<elseif $time lte ($hour * 60 + 5)>>
 
-			You enter the science classroom.
+			<<if $sydneyScienceWalk>>
+				<<unset $sydneyScienceWalk>>
+				You enter the science classroom with Sydney.
+			<<else>>
+				You enter the science classroom.
+			<</if>>
 			<<npc Sirris>><<person1>>
 			Sirris is preparing at the front of the room while the seats fill.
 			<<if $worn.over_upper.name isnot "naked" or $worn.over_lower.name isnot "naked" or $worn.over_head.name isnot "naked">>
@@ -46,17 +51,33 @@
 			<br>
 
 		<<else>>
-			You enter the science classroom.
-			<<npc Sirris>><<person1>>
-			<<if $scienceExcused is true>>
-				<<unset $scienceExcused>>
-				Sirris cuts off mid-sentence to regard you. "Excused tardiness, please take a seat." <<He>> smiles at you.
+			<<if $sydneyScienceWalk>>
+				<<unset $sydneyScienceWalk>>
+				You enter the science classroom with Sydney.
+				<<npc Sirris>><<person1>>
+				<<if $scienceExcused is true>>
+					<<unset $scienceExcused>>
+					Sirris cuts off mid-sentence to regard you. "Excused tardiness, for both of you. Please take a seat." <<He>> smiles at you.
+				<<else>>
+					Sirris cuts off mid-sentence to regard you. "I'm sorry, but I'll have to record your tardiness. Both of you." Sydney looks ashamed.
+					<<gdelinquency>><<lspurity>>
+					<br><br>
+					<<detention 1>>
+				<</if>>
 			<<else>>
-				Sirris cuts off mid-sentence to regard you. "I'm sorry, but I'll have to record your tardiness."
-				<<gdelinquency>>
-				<br><br>
-				<<detention 1>>
+				You enter the science classroom.
+				<<npc Sirris>><<person1>>
+				<<if $scienceExcused is true>>
+					<<unset $scienceExcused>>
+					Sirris cuts off mid-sentence to regard you. "Excused tardiness, please take a seat." <<He>> smiles at you.
+				<<else>>
+					Sirris cuts off mid-sentence to regard you. "I'm sorry, but I'll have to record your tardiness."
+					<<gdelinquency>>
+					<br><br>
+					<<detention 1>>
+				<</if>>
 			<</if>>
+
 			You
 			<<if $worn.over_upper.name isnot "naked" or $worn.over_lower.name isnot "naked" or $worn.over_head.name isnot "naked">>
 				hang your coat at the back of the class and
@@ -113,6 +134,10 @@
 
 		<<npc Sirris>><<person1>>You open the door to the science classroom. Sirris cuts off mid-sentence as you enter, looking surprised. "Can I help you?" It seems you've interrupted the lesson.
 		<br><br>
+		<<if $NPCName[$NPCNameList.indexOf("Sydney")].init is 1 and $schoolstate is "second" and $sydneyScience isnot 1>>
+			You spot Sydney right at the front of the class. <<nnpc_He "Sydney">> looks to you with confusion.
+			<br><br>
+		<</if>>
 		<<set $scienceinterrupted to 1>>
 
 		<<link [[Apologise|Science Classroom Apology]]>><<trauma 1>><<stress 1>><</link>><<gstress>><<gtrauma>>
@@ -153,6 +178,15 @@ Embarrassed, you apologise and leave.
 <<set $outside to 0>><<set $location to "school">><<schooleffects>><<effects>>
 
 You mock the teacher. "A white lab coat is a good idea <<sir>>, it'll hide the stains." Laughter erupts among the seated students.
+<<if $NPCName[$NPCNameList.indexOf("Sydney")].init is 1 and $schoolstate is "second" and $sydneyScience isnot 1>>
+	<<run statusCheck("Sydney")>>
+	<<if _sydneyStatus.includes("corrupt")>>
+		Even Sydney struggles to not burst into laughter.
+	<<else>>
+		Sydney's eyes widen in shock.
+	<</if>>
+	<<lspurity>>
+<</if>>
 <br><br>
 
 Sirris looks exasperated. "Right. I'll have to inform the head of your behaviour, you know. Please, just go."
diff --git a/game/overworld-town/special-sydney/temple.twee b/game/overworld-town/special-sydney/temple.twee
index 0c44a27716..555f7af8a2 100644
--- a/game/overworld-town/special-sydney/temple.twee
+++ b/game/overworld-town/special-sydney/temple.twee
@@ -1552,7 +1552,7 @@ You creep up to the door.
 			<br>
 			"I'm sorry, that must have been traumatising. I'm glad you've come this far with <<phim>>."
 		<<case "science">>
-			"We met in our shared science class."
+			"We met in our shared science class. I was late that day, and showed up in my robes."
 			<br>
 			"Noted."
 		<<case "shop">>
diff --git a/game/overworld-town/special-sydney/walk.twee b/game/overworld-town/special-sydney/walk.twee
index a8bf42c095..98dc9a2508 100644
--- a/game/overworld-town/special-sydney/walk.twee
+++ b/game/overworld-town/special-sydney/walk.twee
@@ -1332,13 +1332,13 @@ You shake your head, and Sydney frowns. "Suit yourself, I guess." <<He>> turns o
 	<<set $location to "park">>
 	You and Sydney cut across the park again. <<He>> bursts through the front doors of the school, and heads straight for Sirris' classroom with you in tow.
 	<br><br>
-	<<link [[Next|Sydney Science Walk Late]]>><</link>>
+	<<link [[Next|Science Classroom]]>><<endevent>><<set $sydneyScienceWalk to 1>><</link>>
 	<br>
 <<elseif $schoolday is 1 and $sydneyScience and (($hour is 8 and $minute gte 44) or $hour is 9)>>
 	<<set $location to "park">>
-	You and Sydney cut across the park again. You think you'll make it in time.
+	You and Sydney cut across the park again. You think you'll make it in time. You hurry through the front gate, through the halls, and towards Sirris' classroom.
 	<br><br>
-	<<link [[Next|Sydney Science Walk]]>><</link>>
+	<<link [[Next|Science Classroom]]>><<endevent>><<set $sydneyScienceWalk to 1>><</link>>
 	<br>
 <<elseif _sydney_location is "shop" or _sydney_location is "home">>
 	You exit the shopping centre with Sydney. <<if $sydneyromance is 1>><<if _sydneyStatus.includes("corrupt")>><<He>> takes your hands in <<hers>><<else>>You take <<his>> hands in yours<</if>>. <<takeHandholdingVirginity "Sydney" "romantic">><</if>>
@@ -1381,7 +1381,7 @@ You shake your head, and Sydney frowns. "Suit yourself, I guess." <<He>> turns o
 	<br><br>
 	Sydney bursts through the front doors of the school, and heads straight for Sirris' classroom with you in tow.
 	<br><br>
-	<<link [[Next|Sydney Science Walk Late]]>><</link>>
+	<<link [[Next|Science Classroom]]>><<endevent>><<set $sydneyScienceWalk to 1>><</link>>
 	<br>
 <<else>>
 	Sydney walks up to <<if $NPCName[$NPCNameList.indexOf("Jordan")].init is 1>>Jordan<<else>>the figure<</if>>, and they talk for a brief moment. <<nnpc_He "Jordan">> smiles at you as Sydney runs back to your side, and you both leave the temple.
@@ -2275,13 +2275,3 @@ You chat with <<him>> on the way.
 You reach the Elk Street without incident. Sydney waves you goodbye as <<he>> enters Sirris's shop.
 <br><br>
 <<link [[Next|Elk Street]]>><<endevent>><<set $eventskip to 1>><</link>>
-
-:: Sydney Science Walk
-This passage should be unreachable. If you're seeing this, you've found a bug. Please report it to Vrelnir, and take this convenient portal to Starfish Street to escape.
-<<link [[Next|Starfish Street]]>><<endevent>><<set $eventskip to 1>><</link>>
-<br>
-
-:: Sydney Science Walk Late
-This passage should be unreachable. If you're seeing this, you've found a bug. Please report it to Vrelnir, and take this convenient portal to Starfish Street to escape.
-<<link [[Next|Starfish Street]]>><<endevent>><<set $eventskip to 1>><</link>>
-<br>
diff --git a/game/overworld-town/special-sydney/widgets.twee b/game/overworld-town/special-sydney/widgets.twee
index 8374f4951a..68964e3a0e 100644
--- a/game/overworld-town/special-sydney/widgets.twee
+++ b/game/overworld-town/special-sydney/widgets.twee
@@ -108,28 +108,11 @@
 	<<unset $schoolShopAction>>
 	<br><br>
 	<<sydneyOptions>>
-<<elseif $hour is 9 and $sydneyScience isnot 1 and $sydneyScienceWarn isnot 2>>
-	<<if !$sydneyScienceWarn>>
-		<<set $sydneyScienceWarn to 0>>
-	<</if>>
-	<<set $sydneyScienceWarn++>>
-	<<if $sydneyScienceWarn is 1>>
-		Sydney looks up at you. "Classes usually start around now. Aren't you going to be late?"
-		<br><br>
-		<<sydneyOptions>>
-	<<elseif $sydneyScienceWarn is 2>>
-		Sydney looks up at you. "Are you... skipping class just to see me?"
-		<br><br>
-		<<sydneyOptions>>
-	<<elseif $sydneyScienceWarn gte 3 and $sydneyromance isnot 1>>
-		Sydney shoos you away from the rental counter. "If the <<nnpc_Title "Leighton">> catches you skipping class, we'll both be in big trouble!"
-		<br><br>
-		<<link [[Leave|School Library]]>><<endevent>><<set $eventskip to 1>><</link>>
-		<br>
-	<<else>>
-		<br><br>
-		<<sydneyOptions>>
-	<</if>>
+<<elseif $sydneyClassWarn and $sydneyClassWarn gte 3 and !_sydneyStatus.includes("corrupt")>>
+	Sydney shoos you away. "If the <<nnpc_Title "Leighton">> catches you skipping class, we'll both be in big trouble!"
+	<br><br>
+	<<link [[Leave|School Library]]>><<endevent>><<set $eventskip to 1>><</link>>
+	<br>
 <<elseif _counterApproach is 1>>
 	<<if $sydneyChastityRemoveIntro is 1>>
 		Sydney looks eager to talk to you about something.
@@ -223,20 +206,47 @@
 <<if $bus is "schoollibrary" or $location is "school">>
 	<<switch _sydney_location>>
 		<<case "library">>
-			<<sydneyOptionsTalk>>
-			<br>
-			<<bookRentalOptions>>
-			<br>
-			You can purchase any school-sanctioned clothing here.
-			<br>
-			<<link [[Buy clothes|School Library Shop]]>><</link>>
-			<br>
-			<<link [[Leave|School Library]]>><<endevent>><<set $eventskip to 1>><</link>>
-			<br>
+			<<if ($sydneyScience isnot 1 and $schoolstate is "first") or ["fourth", "fifth"].includes($schoolstate)>>
+				<<if !$sydneyClassWarn>>
+					<<set $sydneyClassWarn to 0>>
+				<</if>>
+				<<set $sydneyClassWarn++>>
+			<</if>>
+			<<if $sydneyClassWarn and $sydneyClassWarn gte 3 and !_sydneyStatus.includes("corrupt")>>
+				<<He>> shoos you away from the rental counter. "If the <<nnpc_Title "Leighton">> catches you skipping class, we'll both be in big trouble!"
+				<br><br>
+				<<link [[Leave|School Library]]>><<endevent>><<set $eventskip to 1>><</link>>
+				<br>
+			<<else>>
+				<<if $sydneyClassWarn is 1>>
+					<<if $schoolstate is "first">>
+						<<He>> looks up at you. "Classes usually start around now. Aren't you going to be late?"
+					<<else>>
+						<<He>> checks the time. "You're going to be late for your next class."
+					<</if>>
+					<br><br>
+				<<elseif $sydneyClassWarn is 2>>
+					<<He>> looks up at you. "Are you... skipping class just to see me?"
+					<br><br>
+				<<elseif $sydneyClassWarn is 3 and _sydneyStatus.includes("corrupt")>>
+					<<He>> checks the time. "Screw it, you can stay. Just don't blame me if you get detention."
+					<br><br>
+				<</if>>
+				<<sydneyOptionsTalk>>
+				<br>
+				<<bookRentalOptions>>
+				<br>
+				You can purchase any school-sanctioned clothing here.
+				<br>
+				<<link [[Buy clothes|School Library Shop]]>><</link>>
+				<br>
+				<<link [[Leave|School Library]]>><<endevent>><<set $eventskip to 1>><</link>>
+				<br>
+			<</if>>
 		<<case "science">>
 			Sydney's eyes grow wide. "Sh<<if _sydneyStatus.includes("corrupt")>>i<<else>>oo<</if>>t! We're late for science class!" <<He>> begins to pack up <<his>> things. "<<sydneyMum>>'s gonna kill me..."
 			<br><br>
-			<<scienceicon>><<link [[Go with Sydney|Sydney Science Walk Late]]>><<set $eventskip to 1>><</link>>
+			<<scienceicon>><<link [[Go with Sydney|Science Classroom]]>><<endevent>><<set $sydneyScienceWalk to 1>><</link>>
 			<br>
 			<<link [[Leave|School Library]]>><<endevent>><<set $eventskip to 1>><</link>>
 			<br>
@@ -437,7 +447,7 @@
 	<br>
 <</if>>
 <<if $location is "school" and $sydneySeen.includes("science") and $hour is 8 and $minute gte 45>>
-	<<scienceicon>><<link [[Walk to science class (0:05)|Sydney Science Walk]]>><<pass 5>><<npcincr Sydney love 1>><</link>><<glove>>
+	<<scienceicon>><<link [[Walk to science class with Sydney (0:05)|Science Classroom]]>><<pass 5>><<npcincr Sydney love 1>><<endevent>><<set $sydneyScienceWalk to 1>><</link>><<glove>>
 	<br>
 <</if>>
 <<if $location is "adult_shop">> /*Placeholder. Unfinished.*/
-- 
GitLab


From 7cccd7bcd91c78b4c7de84398c082ace106f24ef Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Mon, 22 Aug 2022 20:56:06 +0000
Subject: [PATCH 09/50] Bugfixes

---
 game/overworld-town/loc-home/main.twee           | 2 +-
 game/overworld-town/special-robin/halloween.twee | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index e47a3d2ca9..952a07eb22 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -85,7 +85,7 @@ You are in your bedroom.
 <</if>>
 
 <br><br>
-<<if $robinbed is "yours" and !$possessed>>
+<<if $robinbed is "yours" and $hour gte 6 and !$possessed>>
 	<<unset $robinbed>>
 	<<npc Robin>><<person1>>Robin yawns and heads to <<his>> own room.<<endevent>>
 	<<if $hour is 6 and $minute lte 20>><<run setRobinLocationOverride("orphanage", 6)>><</if>>
diff --git a/game/overworld-town/special-robin/halloween.twee b/game/overworld-town/special-robin/halloween.twee
index c71678c00b..2b262cbb4b 100644
--- a/game/overworld-town/special-robin/halloween.twee
+++ b/game/overworld-town/special-robin/halloween.twee
@@ -537,7 +537,7 @@ Robin remains quiet as you move to the next house, but stays close to you. You h
 <br><br>
 <<actionsman>>
 
-<<if _combatend or (enemyanger gte 20 or $consensual isnot 1)>>
+<<if _combatend or ($enemyanger gte 20 or $consensual isnot 1)>>
 	<span id="next"><<link [[Next|Robin Trick Sex Finish]]>><</link>></span><<nexttext>>
 <<else>>
 	<span id="next"><<link [[Next|Robin Trick Sex]]>><</link>></span><<nexttext>>
@@ -703,4 +703,4 @@ You swap sweets with Robin, though <<he>> has trouble making up <<his>> mind, un
 <<stress -18>><<trauma -18>><<lltrauma>><<llstress>>
 <br><br>
 
-<<robinoptions>>
\ No newline at end of file
+<<robinoptions>>
-- 
GitLab


From 97dff6396782b464dd5b3d6474a29cda4a2e8f6a Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Mon, 22 Aug 2022 21:11:25 +0000
Subject: [PATCH 10/50] Style update for Furniture.js

---
 game/03-JavaScript/furniture.js | 212 +++++++++++++++++---------------
 1 file changed, 112 insertions(+), 100 deletions(-)

diff --git a/game/03-JavaScript/furniture.js b/game/03-JavaScript/furniture.js
index a383d5bcf4..2c28ab41b4 100644
--- a/game/03-JavaScript/furniture.js
+++ b/game/03-JavaScript/furniture.js
@@ -5,20 +5,20 @@ const Furniture = (() => {
 	const FORCE_UPDATE = false; /* IMPORTANT: Switch to false before the next update. */
 
 	const Categories = Object.freeze({
-		bed			: 'bed',
-		table		: 'table',
-		chair		: 'chair',
-		wardrobe	: 'wardrobe',
-		decoration	: 'decoration',
-		windowsill	: 'windowsill',
-		poster		: 'poster',
-		wallpaper	: 'wallpaper'
+		bed: "bed",
+		table: "table",
+		chair: "chair",
+		wardrobe: "wardrobe",
+		decoration: "decoration",
+		windowsill: "windowsill",
+		poster: "poster",
+		wallpaper: "wallpaper",
 	});
 
 	const Locations = Object.freeze({
 		bedroom: "bedroom",
 		cabin: "cabin",
-		cottage: "cottage"
+		cottage: "cottage",
 	});
 
 	let target = Locations.bedroom;
@@ -42,7 +42,7 @@ const Furniture = (() => {
 		*/
 
 		/* ------------- CHAIRS ------------- */
-		mapper.set('stool', {
+		mapper.set("stool", {
 			name: "stools",
 			nameCap: "Wooden stools",
 			category: ["chair"],
@@ -51,7 +51,7 @@ const Furniture = (() => {
 			description: "A set of stools. Uncomfortable, but better than nothing.",
 			iconFile: "stool.png",
 		});
-		mapper.set('chair', {
+		mapper.set("chair", {
 			name: "wooden chairs",
 			nameCap: "Wooden chairs",
 			category: ["chair"],
@@ -60,7 +60,7 @@ const Furniture = (() => {
 			description: "A set of regular wooden chairs.",
 			iconFile: "chair.png",
 		});
-		mapper.set('armchair', {
+		mapper.set("armchair", {
 			name: "armchairs",
 			nameCap: "Armchairs",
 			category: ["chair"],
@@ -69,18 +69,19 @@ const Furniture = (() => {
 			description: "A set of armchairs. Soft, relaxing and expensive.",
 			iconFile: "armchair.png",
 		});
-		mapper.set('egg', {
+		mapper.set("egg", {
 			name: "egg armchairs",
 			nameCap: "Egg armchairs",
 			category: ["chair"],
 			type: [],
 			cost: setPrice(2420, 50),
-			description: "A set of armchairs with a rounded back, in exotic colours. A chore to set up.",
+			description:
+				"A set of armchairs with a rounded back, in exotic colours. A chore to set up.",
 			iconFile: "armchairegg.png",
 		});
 
 		/* ------------- TABLES ------------- */
-		mapper.set('woodentable', {
+		mapper.set("woodentable", {
 			name: "wooden table",
 			nameCap: "Wooden table",
 			category: ["table"],
@@ -89,7 +90,7 @@ const Furniture = (() => {
 			description: "Can be used as a working or gathering spot. Just add chairs.",
 			iconFile: "table.png",
 		});
-		mapper.set('marbletable', {
+		mapper.set("marbletable", {
 			name: "marble-topped table",
 			nameCap: "Marble-topped table",
 			category: ["table"],
@@ -100,7 +101,7 @@ const Furniture = (() => {
 		});
 
 		/* ------------- BEDS ------------- */
-		mapper.set('bed', {
+		mapper.set("bed", {
 			name: "basic bed",
 			nameCap: "Basic bed",
 			category: ["bed"],
@@ -109,7 +110,7 @@ const Furniture = (() => {
 			description: "An old, poor bed. Uncomfortable.",
 			iconFile: "bed.png",
 		});
-		mapper.set('singlebed', {
+		mapper.set("singlebed", {
 			name: "single bed",
 			nameCap: "Single bed",
 			category: ["bed"],
@@ -118,7 +119,7 @@ const Furniture = (() => {
 			description: "A bed for one.",
 			iconFile: "singlebed.png",
 		});
-		mapper.set('singlebeddeluxe', {
+		mapper.set("singlebeddeluxe", {
 			name: "deluxe single bed",
 			nameCap: "Deluxe single bed",
 			category: ["bed"],
@@ -127,7 +128,7 @@ const Furniture = (() => {
 			description: "An ergonomically designed bed. Very comfortable.",
 			iconFile: "singlebeddeluxe.png",
 		});
-		mapper.set('doublebed', {
+		mapper.set("doublebed", {
 			name: "double bed",
 			nameCap: "Double bed",
 			category: ["bed"],
@@ -136,10 +137,10 @@ const Furniture = (() => {
 			description: "A simple bed. Fits two.",
 			iconFile: "doublebed.png",
 			showFn() {
-				return target !== 'bedroom';
-			}
+				return target !== "bedroom";
+			},
 		});
-		mapper.set('doublebeddeluxe', {
+		mapper.set("doublebeddeluxe", {
 			name: "deluxe double bed",
 			nameCap: "Deluxe double bed",
 			category: ["bed"],
@@ -148,22 +149,23 @@ const Furniture = (() => {
 			description: "A beautiful bed with a soft mattress. Very comfortable, fits two.",
 			iconFile: "doublebeddeluxe.png",
 			showFn() {
-				return target !== 'bedroom';
-			}
+				return target !== "bedroom";
+			},
 		});
-		mapper.set('doublebedexotic', {
+		mapper.set("doublebedexotic", {
 			name: "exotic double bed",
 			nameCap: "Exotic double bed",
 			category: ["bed"],
 			type: ["double", "comfy"],
 			cost: setPrice(4884),
-			description: "A bed made in a contemporary, minimalist style. Very comfortable, fits two.",
+			description:
+				"A bed made in a contemporary, minimalist style. Very comfortable, fits two.",
 			iconFile: "doublebedexotic.png",
 			showFn() {
-				return target !== 'bedroom';
-			}
+				return target !== "bedroom";
+			},
 		});
-		mapper.set('doublebedwicker', {
+		mapper.set("doublebedwicker", {
 			name: "wicker double bed",
 			nameCap: "Wicker double bed",
 			category: ["bed"],
@@ -172,21 +174,22 @@ const Furniture = (() => {
 			description: "An authentic bed on a rattan frame. Very comfortable, fits two.",
 			iconFile: "doublebedwicker.png",
 			showFn() {
-				return target !== 'bedroom';
-			}
+				return target !== "bedroom";
+			},
 		});
 
 		/* ------------- MISC ------------- */
-		mapper.set('plantpot', {
+		mapper.set("plantpot", {
 			name: "plant pot",
 			nameCap: "Plant pot",
 			category: ["windowsill"],
 			type: [],
 			cost: setPrice(680),
-			description: "A clay pot with good soil. Flowers come pre-planted. Can be put on your windowsill.",
+			description:
+				"A clay pot with good soil. Flowers come pre-planted. Can be put on your windowsill.",
 			iconFile: "flower.png",
-			});
-		mapper.set('jar', {
+		});
+		mapper.set("jar", {
 			name: "jar",
 			nameCap: "Jar",
 			category: ["windowsill"],
@@ -197,7 +200,7 @@ const Furniture = (() => {
 		});
 
 		/* ------------- DECORATIONS ------------- */
-		mapper.set('calendar', {
+		mapper.set("calendar", {
 			name: "calendar",
 			nameCap: "Calendar",
 			category: ["decoration"],
@@ -206,7 +209,7 @@ const Furniture = (() => {
 			description: "The days of this calendar are numbered.",
 			iconFile: "calendar.png",
 		});
-		mapper.set('painting', {
+		mapper.set("painting", {
 			name: "painting",
 			nameCap: "Painting",
 			category: ["decoration"],
@@ -215,7 +218,7 @@ const Furniture = (() => {
 			description: "It's not actually a painting. It's an illustration. ",
 			iconFile: "painting.png",
 		});
-		mapper.set('banner', {
+		mapper.set("banner", {
 			name: "banner",
 			nameCap: "Banner",
 			category: ["decoration"],
@@ -224,7 +227,7 @@ const Furniture = (() => {
 			description: "A figure from an old movie is poised in the centre.",
 			iconFile: "banner.png",
 		});
-		mapper.set('bannerlewd', {
+		mapper.set("bannerlewd", {
 			name: "lewd banner",
 			nameCap: "Lewd banner",
 			category: ["decoration"],
@@ -233,7 +236,7 @@ const Furniture = (() => {
 			description: "A banner with a tentacle.",
 			iconFile: "banner.png",
 		});
-		mapper.set('bannerfestive', {
+		mapper.set("bannerfestive", {
 			name: "festive banner",
 			nameCap: "Festive banner",
 			category: ["decoration"],
@@ -242,7 +245,7 @@ const Furniture = (() => {
 			description: "It may or may not be in season, but it still looks cool.",
 			iconFile: "bannerfestive.png",
 		});
-		mapper.set('bearplushie', {
+		mapper.set("bearplushie", {
 			name: "large bear plushie",
 			nameCap: "Large bear plushie",
 			category: ["decoration"],
@@ -251,7 +254,7 @@ const Furniture = (() => {
 			description: "Soft, cuddly and forever loyal.",
 			iconFile: "bearplushie.png",
 		});
-		mapper.set('owlplushie', {
+		mapper.set("owlplushie", {
 			name: "owl plushie",
 			nameCap: "Owl plushie",
 			category: ["decoration"],
@@ -259,13 +262,13 @@ const Furniture = (() => {
 			cost: setPrice(),
 			description: "Large eyes stare at the world.",
 			iconFile: "owlplushie.png",
-			showFn: () => false
+			showFn: () => false,
 		});
 		/* ------------- WARDROBES ------------- */
 		/*	starter - 20 clothing slots for every type
 			spacious - 30 clothing slots for every type
 			organised - 40 clothing slots for every type */
-		mapper.set('wardrobe', {
+		mapper.set("wardrobe", {
 			name: "creaky wardrobe",
 			nameCap: "Creaky wardrobe",
 			category: ["wardrobe"],
@@ -273,9 +276,9 @@ const Furniture = (() => {
 			cost: setPrice(0),
 			description: "An old, creaky wardrobe. Doesn't hold much.",
 			iconFile: "wardrobe.png",
-			showFn: () => false
+			showFn: () => false,
 		});
-		mapper.set('wardrobebasic', {
+		mapper.set("wardrobebasic", {
 			name: "wardrobe",
 			nameCap: "Wardrobe",
 			category: ["wardrobe"],
@@ -285,9 +288,9 @@ const Furniture = (() => {
 			iconFile: "wardrobebasic.png",
 			showFn() {
 				return isWardrobeHigherTier(this);
-			}
+			},
 		});
-		mapper.set('armoire', {
+		mapper.set("armoire", {
 			name: "armoire",
 			nameCap: "Armoire",
 			category: ["wardrobe"],
@@ -297,9 +300,9 @@ const Furniture = (() => {
 			iconFile: "armoire.png",
 			showFn() {
 				return isWardrobeHigherTier(this);
-			}
+			},
 		});
-		mapper.set('organiser', {
+		mapper.set("organiser", {
 			name: "organiser wardrobe",
 			nameCap: "Organiser wardrobe",
 			category: ["wardrobe"],
@@ -309,9 +312,9 @@ const Furniture = (() => {
 			iconFile: "wardrobeorganiser.png",
 			showFn() {
 				return isWardrobeHigherTier(this);
-			}
+			},
 		});
-		mapper.set('carved', {
+		mapper.set("carved", {
 			name: "carved armoire",
 			nameCap: "Carved armoire",
 			category: ["wardrobe"],
@@ -321,10 +324,10 @@ const Furniture = (() => {
 			iconFile: "armoirecarved.png",
 			showFn() {
 				return isWardrobeHigherTier(this);
-			}
+			},
 		});
 		/* --------------- POSTERS --------------- */
-		mapper.set('poster', {
+		mapper.set("poster", {
 			name: "blank poster",
 			nameCap: "Blank poster",
 			category: ["poster"],
@@ -334,7 +337,7 @@ const Furniture = (() => {
 			iconFile: "poster.png",
 		});
 		/* ------------- WALLPAPERS -------------- */
-		mapper.set('wallpaper', {
+		mapper.set("wallpaper", {
 			name: "blank wallpaper",
 			nameCap: "Blank wallpaper",
 			category: ["wallpaper"],
@@ -346,22 +349,26 @@ const Furniture = (() => {
 	}
 
 	function furnitureGet(type, onlySetup = false) {
-		if (typeof type !== 'string') {
-			console.debug('furnitureGet expected an argument of type: string.', type);
+		if (typeof type !== "string") {
+			console.debug("furnitureGet expected an argument of type: string.", type);
 			return null;
 		}
 		if (onlySetup) {
 			return setup.furniture.get(type);
 		}
 		if (!V) {
-			console.debug('furnitureGet called before SugarCube is ready, postpone execution next time.', type);
+			console.debug(
+				"furnitureGet called before SugarCube is ready, postpone execution next time.",
+				type
+			);
 			return null;
 		}
 		const area = V.furniture[target];
-		if (area.hasOwnProperty(type)) {
+		if (Object.hasOwn(area, type)) {
 			const current = area[type];
 			const defaults = setup.furniture.get(current.id);
-			return { ...defaults, ...current };
+			const composite = Object.assign({}, defaults, current);
+			return composite;
 		} else {
 			return null;
 		}
@@ -369,18 +376,18 @@ const Furniture = (() => {
 
 	function furnitureSet(id, category, propertyMap) {
 		if (!setup.furniture.has(id)) {
-			Errors.report(`Furniture.Set was incorrectly passed an id not listed in furniture: ${id}`);
+			Errors.report(
+				`Furniture.Set was incorrectly passed an id not listed in furniture: ${id}`
+			);
 			return false;
 		}
-		if (!Categories.hasOwnProperty(category)) {
+		if (!Object.hasOwn(Categories, category)) {
 			Errors.report(`Furniture.Set was incorrectly passed an invalid category : ${category}`);
 			return false;
 		}
 		const home = V.furniture[target];
 
-		home[category] = {
-			'id'	: id
-		};
+		home[category] = { id };
 		if (propertyMap) {
 			/* Object.defineProperties(home[category], propertyMap); */
 			Object.assign(home[category], propertyMap);
@@ -392,13 +399,17 @@ const Furniture = (() => {
 		if (Object.values(Locations).includes(location)) {
 			target = location;
 		} else {
-			Errors.report(`Location provided (${location}) does not exist in the furniture system.`);
+			Errors.report(
+				`Location provided (${location}) does not exist in the furniture system.`
+			);
 		}
 		return Furniture;
 	}
 
 	function furnitureUpdate(fromBackComp = false) {
 		const versions = V.objectVersion;
+		let wallpaper;
+		let poster;
 		if (versions.furniture === undefined || FORCE_UPDATE) {
 			versions.furniture = 0;
 		}
@@ -406,35 +417,36 @@ const Furniture = (() => {
 			case 0:
 				V.furniturePriceFactor = 1;
 				V.furniture = {
-					bedroom	: {
-						bed	: {
-							id: 'bed'
+					bedroom: {
+						bed: {
+							id: "bed",
 						},
-						wardrobe : {
-							id: fromBackComp ? 'organiser' : 'wardrobe'
-						}
-					}
-				}
+						wardrobe: {
+							id: fromBackComp ? "organiser" : "wardrobe",
+						},
+					},
+				};
 				wardrobeSpaceUpdater();
+			// eslint-disable-next-line no-fallthrough
 			case 1:
 				/* Set the target to the bedroom in the unlikely event it wasn't preset. */
 				furnitureIn(Locations.bedroom);
 				/* Search for the wallpaper object, returns null if not found. */
-				const wallpaper = furnitureGet(Categories.wallpaper);
-				if (wallpaper != null && wallpaper.name.includes('<<')) {
+				wallpaper = furnitureGet(Categories.wallpaper);
+				if (wallpaper != null && wallpaper.name.includes("<<")) {
 					const name = Util.escape(wallpaper.name);
-					furnitureSet('wallpaper', Categories.wallpaper, {
-						name: name,
-						nameCap: name.toUpperFirst()
+					furnitureSet("wallpaper", Categories.wallpaper, {
+						name,
+						nameCap: name.toUpperFirst(),
 					});
 				}
 				/* Search for the poster object, returns null if not found. */
-				const poster = furnitureGet(Categories.poster);
-				if (poster != null && poster.name.includes('<<')) {
+				poster = furnitureGet(Categories.poster);
+				if (poster != null && poster.name.includes("<<")) {
 					const name = Util.escape(poster.name);
-					furnitureSet('poster', Categories.poster, {
-						name: name,
-						nameCap: name.toUpperFirst()
+					furnitureSet("poster", Categories.poster, {
+						name,
+						nameCap: name.toUpperFirst(),
 					});
 				}
 				versions.furniture = 2;
@@ -443,13 +455,13 @@ const Furniture = (() => {
 	}
 
 	function getWardrobeTier(wardrobe) {
-		const type = wardrobe.type.find(e => ['spacious', 'organiser'].includes(e)) || 'starter';
-		const tier = { 'starter': 0, 'spacious': 1, 'organiser': 2 }[type];
+		const type = wardrobe.type.find(e => ["spacious", "organiser"].includes(e)) || "starter";
+		const tier = { starter: 0, spacious: 1, organiser: 2 }[type];
 		return tier;
 	}
 
 	function isWardrobeHigherTier(wardrobe) {
-		const current = Furniture.get('wardrobe');
+		const current = Furniture.get("wardrobe");
 		if (current) {
 			const targetTier = getWardrobeTier(wardrobe);
 			const currentTier = getWardrobeTier(current);
@@ -462,13 +474,13 @@ const Furniture = (() => {
 
 	function wardrobeSpaceUpdater() {
 		const wardrobe = V.wardrobe;
-		const furniture = furnitureGet('wardrobe');
-		if (typeof furniture !== 'object') return;
+		const furniture = furnitureGet("wardrobe");
+		if (typeof furniture !== "object") return;
 		if (!(furniture.type instanceof Array)) return;
 		/* Wardrobe object appears to be good: Is an object, type is an array. */
-		if (furniture.type.includes('organiser')) {
+		if (furniture.type.includes("organiser")) {
 			wardrobe.space = 40;
-		} else if (furniture.type.includes('spacious')) {
+		} else if (furniture.type.includes("spacious")) {
 			wardrobe.space = 30;
 		} else {
 			wardrobe.space = 20;
@@ -479,7 +491,7 @@ const Furniture = (() => {
 		return () => Math.floor((pounds * 100 + pence) * V.furniturePriceFactor);
 	}
 
-	$(document).on(':start2', function() {
+	$(document).on(":start2", function () {
 		furnitureUpdate();
 	});
 
@@ -487,15 +499,15 @@ const Furniture = (() => {
 	furnitureInit();
 
 	return Object.freeze({
-		init			: furnitureInit,
-		get				: furnitureGet,
-		set				: furnitureSet,
-		in				: furnitureIn,
-		update			: furnitureUpdate,
-		wardrobeUpdate	: wardrobeSpaceUpdater,
+		init: furnitureInit,
+		get: furnitureGet,
+		set: furnitureSet,
+		in: furnitureIn,
+		update: furnitureUpdate,
+		wardrobeUpdate: wardrobeSpaceUpdater,
 		get target() {
 			return target;
-		}
+		},
 	});
 })();
 window.Furniture = Furniture;
-- 
GitLab


From 3e898b4e64b0ed2911ee50212b2f82fdc7d3ece7 Mon Sep 17 00:00:00 2001
From: Xao <33462-xao@users.noreply.gitgud.io>
Date: Tue, 23 Aug 2022 09:41:40 +0200
Subject: [PATCH 11/50] Initial commit

---
 game/overworld-town/loc-shop/clothing-v2.twee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/game/overworld-town/loc-shop/clothing-v2.twee b/game/overworld-town/loc-shop/clothing-v2.twee
index 8db1ffc2b9..ebc324c930 100644
--- a/game/overworld-town/loc-shop/clothing-v2.twee
+++ b/game/overworld-town/loc-shop/clothing-v2.twee
@@ -1278,7 +1278,7 @@
 				<span class="bold gold">Traits</span>
 				<div class="traits-list">
 					<<set _traitsInThisShop = [...new Set(Object.keys(setup.clothes).flatMap(x => setup.clothes[x]).filter(x => x.shop.includes(_shopLocation)).flatMap(x => x.type))]>>
-					<<for _trait range _traitsInThisShop>>
+					<<for _trait range _traitsInThisShop.sort()>>
 						<<silently>><<shopTraitDescription _trait>><</silently>>
 						<div class="filters-trait-row">
 							<label>
-- 
GitLab


From 0a1aff8b9c990a4c78cd40de996ab206eb254629 Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Sat, 27 Aug 2022 12:50:51 -0400
Subject: [PATCH 12/50] NaN Check in passageFooter improved - Better function,
 much more performant - Can clear corrupted vars!!!!!!

---
 .../external/object-assign-deep.js            | 124 ++++++++++++++++++
 game/03-JavaScript/save.js                    |  42 +++++-
 .../04-Variables/variables-passageFooter.twee |  20 ++-
 3 files changed, 181 insertions(+), 5 deletions(-)
 create mode 100644 game/03-JavaScript/external/object-assign-deep.js

diff --git a/game/03-JavaScript/external/object-assign-deep.js b/game/03-JavaScript/external/object-assign-deep.js
new file mode 100644
index 0000000000..998458a71b
--- /dev/null
+++ b/game/03-JavaScript/external/object-assign-deep.js
@@ -0,0 +1,124 @@
+// https://raw.githubusercontent.com/saikojosh/Object-Assign-Deep/master/objectAssignDeep.js
+
+/*
+ * OBJECT ASSIGN DEEP
+ * Allows deep cloning of plain objects that contain primitives, nested plain objects, or nested plain arrays.
+ */
+
+/*
+ * A unified way of returning a string that describes the type of the given variable.
+ */
+function getTypeOf(input) {
+	if (input === null) {
+		return "null";
+	} else if (typeof input === "undefined") {
+		return "undefined";
+	} else if (typeof input === "object") {
+		return Array.isArray(input) ? "array" : "object";
+	}
+
+	return typeof input;
+}
+
+/*
+ * Branching logic which calls the correct function to clone the given value base on its type.
+ */
+function cloneValue(value) {
+	// The value is an object so lets clone it.
+	if (getTypeOf(value) === "object") {
+		return quickCloneObject(value);
+	}
+
+	// The value is an array so lets clone it.
+	else if (getTypeOf(value) === "array") {
+		return quickCloneArray(value);
+	}
+
+	// Any other value can just be copied.
+	return value;
+}
+
+/*
+ * Enumerates the given array and returns a new array, with each of its values cloned (i.e. references broken).
+ */
+function quickCloneArray(input) {
+	return input.map(cloneValue);
+}
+
+/*
+ * Enumerates the properties of the given object (ignoring the prototype chain) and returns a new object, with each of
+ * its values cloned (i.e. references broken).
+ */
+function quickCloneObject(input) {
+	const output = {};
+	for (const key in input) {
+		if (!Object.hasOwn(input, key)) {
+			continue;
+		}
+		output[key] = cloneValue(input[key]);
+	}
+	return output;
+}
+
+/*
+ * Does the actual deep merging.
+ */
+function executeDeepMerge(target, _objects = [], _options = {}) {
+	const options = {
+		arrayBehaviour: _options.arrayBehaviour || "replace", // Can be "merge" or "replace".
+	};
+
+	// Ensure we have actual objects for each.
+	const objects = _objects.map(object => object || {});
+	const output = target || {};
+
+	// Enumerate the objects and their keys.
+	for (let oindex = 0; oindex < objects.length; oindex++) {
+		const object = objects[oindex];
+		const keys = Object.keys(object);
+
+		for (let kindex = 0; kindex < keys.length; kindex++) {
+			const key = keys[kindex];
+			const value = object[key];
+			const type = getTypeOf(value);
+			const existingValueType = getTypeOf(output[key]);
+
+			if (type === "object") {
+				if (existingValueType !== "undefined") {
+					const existingValue = existingValueType === "object" ? output[key] : {};
+					output[key] = executeDeepMerge(
+						{},
+						[existingValue, quickCloneObject(value)],
+						options
+					);
+				} else {
+					output[key] = quickCloneObject(value);
+				}
+			} else if (type === "array") {
+				if (existingValueType === "array") {
+					const newValue = quickCloneArray(value);
+					output[key] =
+						options.arrayBehaviour === "merge"
+							? output[key].concat(newValue)
+							: newValue;
+				} else {
+					output[key] = quickCloneArray(value);
+				}
+			} else {
+				output[key] = value;
+			}
+		}
+	}
+
+	return output;
+}
+
+/*
+ * Merge all the supplied objects into the target object, breaking all references, including those of nested objects
+ * and arrays, and even objects nested inside arrays. Like Object.assign(), the first parameter is mutated.
+ * Properties in later objects will always overwrite.
+ */
+function objectAssignDeep(target, ...objects) {
+	return executeDeepMerge(target, objects);
+}
+window.objectAssignDeep = objectAssignDeep;
diff --git a/game/03-JavaScript/save.js b/game/03-JavaScript/save.js
index 0f8a80f248..ac074f2156 100644
--- a/game/03-JavaScript/save.js
+++ b/game/03-JavaScript/save.js
@@ -1152,9 +1152,10 @@ window.isJsonString = function (s) {
  * @param {object} result An object to store the results in. - leave blank.
  * @param {Set} hist A set used for Cycle history. - leave blank.
  */
+
 function recurseNaN(obj, path, result = null, hist = null) {
-	if (result === null) result = { nulls: [], nan: [], cycle: [] };
-	if (hist === null) hist = new Set([obj]);
+	result = Object.assign({ nulls: [], nan: [], cycle: [] }, result);
+	if (hist == null) hist = new Set([obj]);
 	/* let result = {"nulls" : [], "nan" : [], "cycle" : []}; */
 	for (const [key, val] of Object.entries(obj)) {
 		const newPath = `${path}.${key}`;
@@ -1180,3 +1181,40 @@ function recurseNaN(obj, path, result = null, hist = null) {
 	return result;
 }
 window.recurseNaN = recurseNaN;
+
+/**
+ * Recursively traverse target object, finding and returning an object containing all the NaN vars inside.
+ *
+ * Use with objectAssignDeep to re-assign 0 to all bad NaN'd vars.  Use with caution.
+ *
+ * @param {object} target The object to traverse.  Defaults to V ($).
+ * @returns {object} An object containing all the properties/sub-props that were NaN.
+ */
+function scanNaNs(target = V) {
+	// If this gets set to true during function, a NaN was hit within scope.
+	let isMutated = false;
+	const current = Object.create({});
+	// Loop through all properties of the target for NaNs and objects to scan.
+	for (const [key, value] of Object.entries(target)) {
+		// If value is an object, scan that property.
+		if (value && typeof value === "object") {
+			const resp = scanNaNs(value);
+			// If scanNaNs returns a non-null object, there was a NaN somewhere, so make sure to update current obj.
+			if (resp && typeof resp === "object") {
+				current[key] = resp;
+				isMutated = true;
+			}
+		} else if (typeof value === "number") {
+			// Does what it says on the tin, make sure you only test numbers.
+			if (isNaN(value)) {
+				// Set property to a default value, likely zero.
+				current[key] = 0;
+				isMutated = true;
+			}
+		}
+	}
+	// Return a fully realised object, indicating there were NaNs, or null, which can be ignored.
+	// isMutated controls whether we have encountered NaNs, remember to update where necessary.
+	return isMutated ? current : null;
+}
+window.scanNaNs = scanNaNs;
diff --git a/game/04-Variables/variables-passageFooter.twee b/game/04-Variables/variables-passageFooter.twee
index bb33b7a6a8..08b64d365b 100644
--- a/game/04-Variables/variables-passageFooter.twee
+++ b/game/04-Variables/variables-passageFooter.twee
@@ -71,13 +71,27 @@
 <</if>>
 
 <<if $debugdisable is "f">>
-	<<set _nancheck to recurseNaN(V, "V").nan.formatList()>>
-	<<if _nancheck isnot "">>
+	<<set _normalised to scanNaNs(V)>>
+	<<if _normalised neq null>>
 		<<error {
 			message: "Corrupted variables have been detected.",
-			source: "The following variables have invalid values:\n" + _nancheck +
+			source: "The following variables have invalid values:\n" + JSON.stringify(_normalised) +
 			"\n\nCurrent passage is: '" + $passage + "'\nPlease report this to the DoL Discord #bug-reports.",
 			exportable: false,
 		}>>
+		<br>
+		Please expand the above box (click the dropdown arrow on the left) before taking a screenshot.
+		<br><br>
+		<div id="nanClear">
+			If you are advised to do so by developers, you can click below to reset the corrupted variables.
+			<br>
+			<<link "Reset Corrupted Variables">>
+				<<silently>><<run objectAssignDeep(V, _normalised)>><</silently>>
+				<<replace "#nanClear" t8n>><span class="green">The variables have been cleared.</span><</replace>>
+			<</link>>
+			<br>
+			<span class="red">WARNING: This will set all corrupted variables to 0. This may have unintended consequences to your game state. Proeceed with caution!</span>
+		</div>
+		<br><br>
 	<</if>>
 <</if>>
-- 
GitLab


From b5e71f409b67af0c46d85ff91f9e2d1defb5b31e Mon Sep 17 00:00:00 2001
From: note leven <21133-noteleven@users.noreply.gitgud.io>
Date: Sat, 27 Aug 2022 18:01:33 +0000
Subject: [PATCH 13/50] fixes

---
 game/03-JavaScript/canvasmodel.js             |  2 +-
 game/03-JavaScript/save.js                    |  5 +-
 game/04-Variables/presets.twee                | 70 ++++++++++---------
 game/base-combat/widgets.twee                 |  9 +++
 game/base-system/clamp.twee                   | 29 ++------
 .../base-system/overlays/characteristics.twee |  2 +
 game/base-system/settings.twee                | 16 +++--
 game/overworld-town/special-avery/main.twee   |  2 +-
 8 files changed, 71 insertions(+), 64 deletions(-)

diff --git a/game/03-JavaScript/canvasmodel.js b/game/03-JavaScript/canvasmodel.js
index 8ed2155dc6..e3ad283fc7 100644
--- a/game/03-JavaScript/canvasmodel.js
+++ b/game/03-JavaScript/canvasmodel.js
@@ -178,7 +178,7 @@ window.CanvasModel = class CanvasModel {
 	 * @param [listener] Listener for Renderer events
 	 */
 	render(canvas,options,listener) {
-		if (typeof options === undefined) options = this.options;
+		if (typeof options === "undefined") options = this.options;
 		this.canvas = canvas;
 		this.options = options;
 		this.listener = listener;
diff --git a/game/03-JavaScript/save.js b/game/03-JavaScript/save.js
index 0f8a80f248..0f7ed0da1a 100644
--- a/game/03-JavaScript/save.js
+++ b/game/03-JavaScript/save.js
@@ -509,6 +509,9 @@ const importSettingsData = function (data) {
 			const listObject = settingsObjects("general");
 			const listKey = Object.keys(listObject);
 			const namedObjects = ["map", "skinColor", "shopDefaults"];
+			// correct swapped min/max values
+			if (S.general.breastsizemin > S.general.breastsizemax){let temp = S.general.breastsizemin; S.general.breastsizemin = S.general.breastsizemax, S.general.breastsizemax = temp};
+			if (S.general.penissizemin > S.general.penissizemax){let temp = S.general.penissizemin; S.general.penissizemin = S.general.penissizemax, S.general.penissizemax = temp};
 
 			for (let i = 0; i < listKey.length; i++) {
 				if (namedObjects.includes(listKey[i]) && S.general[listKey[i]] != null) {
@@ -868,7 +871,7 @@ function settingsObjects(type) {
 				asphyxiaLvl: { min: 0, max: 4, decimals: 0 },
 				NudeGenderDC: { min: 0, max: 2, decimals: 0 },
 				breastsizemin: { min: 0, max: 4, decimals: 0 },
-				breastsizemax: { min: 0, max: 13, decimals: 0 },
+				breastsizemax: { min: 0, max: 12, decimals: 0 },
 				bottomsizemax: { min: 0, max: 9, decimals: 0 },
 				penissizemax: { min: -2, max: 4, decimals: 0 },
 				penissizemin: { min: -2, max: 0, decimals: 0 },
diff --git a/game/04-Variables/presets.twee b/game/04-Variables/presets.twee
index 9a82d4c44b..71a9d689c6 100644
--- a/game/04-Variables/presets.twee
+++ b/game/04-Variables/presets.twee
@@ -131,47 +131,39 @@
 			<span class="gold">"starting":{</span>
 			<<set _validatorObject to settingsObjects("starting")>>
 			<<presetConfirm _args[0].starting>>
-		<</if>>
-		<<if _args[0].starting is undefined>>
-		<<elseif _args[0].starting.player isnot undefined>>
-			"player":
-			<<set _validatorObject to settingsObjects("starting")>>
-			{<<presetConfirm _args[0].starting.player>>}
-		<</if>>
-		<<if _args[0].starting is undefined>>
-		<<elseif _args[0].starting.skinColor isnot undefined>>
-			"skinColor":
-			<<set _validatorObject to settingsObjects("starting")>>
-			{<<presetConfirm _args[0].starting.skinColor>>}
-		<</if>>
-		<<if _args[0].starting isnot undefined>>
+			<<if _args[0].starting.player isnot undefined>>
+				"player":
+				<<set _validatorObject to settingsObjects("starting")>>
+				{<<presetConfirm _args[0].starting.player>>}
+			<</if>>
+			<<if _args[0].starting.skinColor isnot undefined>>
+				"skinColor":
+				<<set _validatorObject to settingsObjects("starting")>>
+				{<<presetConfirm _args[0].starting.skinColor>>}
+			<</if>>
 			<span class="gold">}</span>
 			<br>
 		<</if>>
+
 		<<if _args[0].general isnot undefined>>
 			<span class="gold">"general":{</span>
 			<<set _validatorObject to settingsObjects("general")>>
 			<<presetConfirm _args[0].general>>
-		<</if>>
-		<<if _args[0].general is undefined>>
-		<<elseif _args[0].general.skinColor isnot undefined>>
-			"skinColour":
-			<<set _validatorObject to settingsObjects("general")>>
-			{<<presetConfirm _args[0].general.skinColor>>}
-		<</if>>
-		<<if _args[0].general is undefined>>
-		<<elseif _args[0].general.map isnot undefined>>
-			"map":
-			<<set _validatorObject to settingsObjects("general")>>
-			{<<presetConfirm _args[0].general.map>>}
-		<</if>>
-		<<if _args[0].general is undefined>>
-		<<elseif _args[0].general.shopDefaults isnot undefined>>
-			"shopDefaults":
-			<<set _validatorObject to settingsObjects("general")>>
-			{<<presetConfirm _args[0].general.shopDefaults>>}
-		<</if>>
-		<<if _args[0].general isnot undefined>>
+			<<if _args[0].general.skinColor isnot undefined>>
+				"skinColour":
+				<<set _validatorObject to settingsObjects("general")>>
+				{<<presetConfirm _args[0].general.skinColor>>}
+			<</if>>
+			<<if _args[0].general.map isnot undefined>>
+				"map":
+				<<set _validatorObject to settingsObjects("general")>>
+				{<<presetConfirm _args[0].general.map>>}
+			<</if>>
+			<<if _args[0].general.shopDefaults isnot undefined>>
+				"shopDefaults":
+				<<set _validatorObject to settingsObjects("general")>>
+				{<<presetConfirm _args[0].general.shopDefaults>>}
+			<</if>>
 			<span class="gold">}</span>
 			<br>
 		<</if>>
@@ -192,6 +184,16 @@
 
 <<widget "presetConfirm">>
 <<if _args[0]>>
+	<<if _args[0].breastsizemin gt _args[0].breastsizemax>>
+		<<set _temp to _args[0].breastsizemin>>
+		<<set _args[0].breastsizemin to _args[0].breastsizemax>>
+		<<set _args[0].breastsizemax to _temp>>
+	<</if>>
+	<<if _args[0].penissizemin gt _args[0].penissizemax>>
+		<<set _temp to _args[0].penissizemin>>
+		<<set _args[0].penissizemin to _args[0].penissizemax>>
+		<<set _args[0].penissizemax to _temp>>
+	<</if>>
 	<ul>
 	<<for $_label, $_value range _args[0]>>
 		<<unset _altValue>>
diff --git a/game/base-combat/widgets.twee b/game/base-combat/widgets.twee
index 020a5591fc..a1ea781c20 100644
--- a/game/base-combat/widgets.twee
+++ b/game/base-combat/widgets.twee
@@ -46,6 +46,15 @@
 			<<else>>
 				<<set $player.virginity[_args[1]] to false>>
 			<</if>>
+			<!-- virgin purity loss -->
+			<<switch _args[1]>>
+				<<case "vaginal">><<purity -50>>
+				<<case "penile">><<purity -50>>
+				<<case "anal">><<purity -25>>
+				<<case "oral">><<purity -25>>
+				<<case "handholding">><<purity -100>>
+				<<case "kiss">><<purity -10>>
+			<</switch>>
 		<</if>>
 
 		<<if $player.virginity.temple is true and (_args[1] is "vaginal" or _args[1] is "penile") and $templePromised isnot _args[0]>>
diff --git a/game/base-system/clamp.twee b/game/base-system/clamp.twee
index 9b665af728..03ab701597 100644
--- a/game/base-system/clamp.twee
+++ b/game/base-system/clamp.twee
@@ -12,29 +12,12 @@
 <</widget>>
 
 <<widget "caption_clamp">>
-<<set $stress = Math.clamp($stress, 0, $stressmax)>>
-<<set $time = Math.clamp($time, 0, 1440)>>
-<<set $minute = Math.clamp($minute, 0, 1440)>>
-<<set $enemyanger to Math.clamp($enemyanger, 0, 200)>>
-<<set $audienceexcitement to Math.clamp($audienceexcitement, 0, 100)>>
-<<set $audiencearousal to Math.clamp($audiencearousal, 0, 100)>>
-
-<<set _tempmin = Math.min($breastsizemin, $breastsizemax)>>
-<<set _tempmax = Math.max($breastsizemin, $breastsizemax)>>
-<<set $breastsizemin = _tempmin>>
-<<set $breastsizemax = _tempmax>>
-<<set _tempmin = Math.min($bottomsizemin, $bottomsizemax)>>
-<<set _tempmax = Math.max($bottomsizemin, $bottomsizemax)>>
-<<set $bottomsizemin = _tempmin>>
-<<set $bottomsizemax = _tempmax>>
-<<set _tempmin = Math.min($penissizemin, $penissizemax)>>
-<<set _tempmax = Math.max($penissizemin, $penissizemax)>>
-<<set $penissizemin = _tempmin>>
-<<set $penissizemax = _tempmax>>
-<<set _tempmin = Math.min($ballssizemin, $ballssizemax)>>
-<<set _tempmax = Math.max($ballssizemin, $ballssizemax)>>
-<<set $ballssizemin = _tempmin>>
-<<set $ballssizemax = _tempmax>>
+	<<set $stress = Math.clamp($stress, 0, $stressmax)>>
+	<<set $time = Math.clamp($time, 0, 1440)>>
+	<<set $minute = Math.clamp($minute, 0, 1440)>>
+	<<set $enemyanger to Math.clamp($enemyanger, 0, 200)>>
+	<<set $audienceexcitement to Math.clamp($audienceexcitement, 0, 100)>>
+	<<set $audiencearousal to Math.clamp($audiencearousal, 0, 100)>>
 <</widget>>
 
 <<widget "clamp">>
diff --git a/game/base-system/overlays/characteristics.twee b/game/base-system/overlays/characteristics.twee
index 383da0ae1e..70bead3e6c 100644
--- a/game/base-system/overlays/characteristics.twee
+++ b/game/base-system/overlays/characteristics.twee
@@ -132,6 +132,7 @@ You have a <<bottom>>.
 	}>>
 	<<set _semenVolumeTextConfig = { currentValue : $semen_amount, states : [
 			{ requiredValue: 0,							color: 'red',		preText: "",				description: "but you\'ve been milked completely dry."},
+			{ requiredValue: 1,							color: 'pink',		preText: "but you\'re ", 	description: 'almost empty. '},
 			{ requiredValue: ($semen_volume / 7) * 2,	color: 'pink',		preText: "but you\'re ",	description: 'running out. '},
 			{ requiredValue: ($semen_volume / 7) * 3,	color: 'purple',	preText: "but you\'re ",	description: 'running low. '},
 			{ requiredValue: ($semen_volume / 7) * 4,	color: 'blue',		preText: "and you\'ve ",	description: 'about half left. '},
@@ -174,6 +175,7 @@ You have a <<bottom>>.
 		}>>
 	<<set _milkVolumeTextConfig = { currentValue : $milk_amount, states : [
 			{ requiredValue: 0,							color: 'red',		preText: "",				description: " but you\'ve been milked completely dry."},
+			{ requiredValue: 1,							color: 'pink',		preText: "but you\'re ", 	description: ' almost empty.'},
 			{ requiredValue: ($milk_volume / 7) * 2,	color: 'pink',		preText: "but you\'re ",	description: ' running out.'},
 			{ requiredValue: ($milk_volume / 7) * 3,	color: 'purple',	preText: "but you\'re ",	description: ' running low.'},
 			{ requiredValue: ($milk_volume / 7) * 4,	color: 'blue',		preText: "and you\'ve ",	description: ' about half left.'},
diff --git a/game/base-system/settings.twee b/game/base-system/settings.twee
index d1b34d6bb7..6610a5a9ed 100644
--- a/game/base-system/settings.twee
+++ b/game/base-system/settings.twee
@@ -1154,14 +1154,18 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<br>
 	<<set _name to ["Flat", "Budding", "Tiny", "Small", "Pert", "Modest", "Full", "Large", "Ample", "Massive", "Huge", "Gigantic", "Enormous"]>>
 	<<for _i to 0; _i lt _name.length; _i++>>
-		<label><<print _name[_i]>> <<radiobutton "$breastsizemax" `_i` autocheck>></label> |
+		<span data-target="breastsizemin" @data-disabledif="'V.breastsizemin > ' + _i">
+			<label><<print _name[_i]>> <<radiobutton "$breastsizemax" `_i` autocheck>></label>
+		</span> |
 	<</for>>
 	<br><br>
 
 	<span class="gold">Minimum player character breast size</span> <mouse class="tooltip linkBlue">(?)<span>Breasts already below this size won't automatically grow.</span></mouse>
 	<br>
 	<<for _i to 0; _i lt 5; _i++>>
-		<label><<print _name[_i]>> <<radiobutton "$breastsizemin" _i autocheck>></label> |
+		<span data-target="breastsizemax" @data-disabledif="_i + ' > V.breastsizemax'">
+			<label><<print _name[_i]>> <<radiobutton "$breastsizemin" _i autocheck>></label> |
+		</span>
 	<</for>>
 	<br><br>
 
@@ -1177,7 +1181,9 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<br>
 	<<set _name to ["Micro","Mini", "Tiny", "Small", "Normal", "Large", "Enormous"]>>
 	<<for _i to 0; _i lt _name.length; _i++>>
-		<label><<print _name[_i]>> <<radiobutton "$penissizemax" `(_i - 2)` autocheck>></label> |
+		<span data-target="penissizemin" @data-disabledif="_i - 2 + ' < V.penissizemin'">
+			<label><<print _name[_i]>> <<radiobutton "$penissizemax" `(_i - 2)` autocheck>></label> |
+		</span>
 	<</for>>
 	<br><br>
 
@@ -1185,7 +1191,9 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<br>
 	<<set _name to ["Micro","Mini", "Tiny"]>>
 	<<for _i to 0; _i lt _name.length; _i++>>
-		<label><<print _name[_i]>> <<radiobutton "$penissizemin" `(_i - 2)` autocheck>></label> |
+		<span data-target="penissizemax" @data-disabledif="_i - 2 + ' > V.penissizemax'">
+			<label><<print _name[_i]>> <<radiobutton "$penissizemin" `(_i - 2)` autocheck>></label> |
+		</span>
 	<</for>>
 	<br><br>
 
diff --git a/game/overworld-town/special-avery/main.twee b/game/overworld-town/special-avery/main.twee
index 8545809084..f94c6c668f 100644
--- a/game/overworld-town/special-avery/main.twee
+++ b/game/overworld-town/special-avery/main.twee
@@ -555,7 +555,7 @@ The hotel interior is extravagant. You're taken aback by the many chandeliers li
 <<else>>
 	A few of the well-dressed occupants look you over. They pay you little mind as you make your way to the elevator.
 <</if>>
-A sign details which rooms are on each floor. Yours seems seems to be at the very top. You step inside, and regard the set of gold buttons. You press the highest.
+A sign details which rooms are on each floor. Yours seems to be at the very top. You step inside, and regard the set of gold buttons. You press the highest.
 <br><br>
 
 The ride takes longer than expected. The doors open, and you make your way to the room. You hesitate before sliding the key into the lock. There's a click, and you turn the handle.
-- 
GitLab


From ec716c79c8225a8c30bc6785f31602d768ed19bb Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Sat, 27 Aug 2022 18:12:41 +0000
Subject: [PATCH 14/50] Crime/Stealth Rebalance

---
 game/04-Variables/variables-start.twee        |  1 -
 .../04-Variables/variables-versionUpdate.twee |  9 ++--
 game/base-system/overlays/cheats.twee         | 12 ++---
 game/base-system/widgets.twee                 | 50 +++++++++++++------
 game/overworld-town/loc-adultshop/shop.twee   |  2 +-
 game/overworld-town/loc-police/pillory.twee   |  5 +-
 game/overworld-town/loc-prison/beach.twee     |  8 +--
 game/overworld-town/loc-prison/main.twee      |  4 +-
 game/overworld-town/loc-prison/rut.twee       |  2 +-
 game/overworld-town/loc-prison/widgets.twee   |  4 ++
 game/overworld-town/loc-pub/main.twee         |  6 +--
 game/overworld-town/skul-shops/main.twee      | 34 ++++++-------
 .../special-whitney/street.twee               |  2 +-
 13 files changed, 79 insertions(+), 60 deletions(-)

diff --git a/game/04-Variables/variables-start.twee b/game/04-Variables/variables-start.twee
index 8bd7067d27..c9675e89b7 100644
--- a/game/04-Variables/variables-start.twee
+++ b/game/04-Variables/variables-start.twee
@@ -136,7 +136,6 @@
 <<set $speechcycle to 0>>
 <<set $npcspeechcycle to 0>>
 <<set $museuminterest to 0>>
-<<set $crimemax to 50000>>
 <<set $orphan_hope to 0>>
 <<set $orphan_reb to 0>>
 <<set $masochism to 0>>
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index 966c531c99..2f578c289b 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -578,10 +578,6 @@
 	<<npcset Robin state "active">>
 <</if>>
 
-<<if $crimemax is undefined>>
-	<<set $crimemax to 50000>>
-<</if>>
-
 <<if $catbuild is undefined>>
 	<<set $catbuild to 0>>
 	<<set $cat to 0>>
@@ -3641,4 +3637,9 @@
 		<<set $outfitTmp to {}>>
 	<</if>>
 
+	<!-- v0.3.11.4 - Remove $crimemax -->
+	<<if $crimemax isnot undefined>>
+		<<unset $crimemax>>
+	<</if>>
+
 <</widget>>
diff --git a/game/base-system/overlays/cheats.twee b/game/base-system/overlays/cheats.twee
index 007372e938..cfae7577a2 100644
--- a/game/base-system/overlays/cheats.twee
+++ b/game/base-system/overlays/cheats.twee
@@ -2068,13 +2068,13 @@ Delinquency: <span id="statsdelinquency"><<print Math.trunc($delinquency)>></spa
 	| <<link ">">><<set $schoolrep.crossdress += 1>><<set $schoolrep.crossdress = Math.clamp($schoolrep.crossdress, 0, 5)>><<replace "#statsschoolrepcrossdress">><<print Math.trunc($schoolrep.crossdress)>><</replace>><</link>>
 <</if>>
 <br><br>
-<<link "<<<">><<set $crime -= 1000>><<set $crime = Math.clamp($crime, 0, $crimemax)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>> |
-<<link "<<">><<set $crime -= 100>><<set $crime = Math.clamp($crime, 0, $crimemax)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>> |
-<<link "<">><<set $crime -= 10>><<set $crime = Math.clamp($crime, 0, $crimemax)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>> |
+<<link "<<<">><<set $crime -= 1000>><<set $crime = Math.clamp($crime, C.crime.min, C.crime.max)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>> |
+<<link "<<">><<set $crime -= 100>><<set $crime = Math.clamp($crime, C.crime.min, C.crime.max)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>> |
+<<link "<">><<set $crime -= 10>><<set $crime = Math.clamp($crime, C.crime.min, C.crime.max)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>> |
 Crime: <span id="statscrime"><<print Math.trunc($crime)>></span>
- | <<link ">">><<set $crime += 10>><<set $crime = Math.clamp($crime, 0, $crimemax)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>>
- | <<link ">>">><<set $crime += 100>><<set $crime = Math.clamp($crime, 0, $crimemax)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>>
- | <<link ">>>">><<set $crime += 1000>><<set $crime = Math.clamp($crime, 0, $crimemax)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>>
+ | <<link ">">><<set $crime += 10>><<set $crime = Math.clamp($crime, C.crime.min, C.crime.max)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>>
+ | <<link ">>">><<set $crime += 100>><<set $crime = Math.clamp($crime, C.crime.min, C.crime.max)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>>
+ | <<link ">>>">><<set $crime += 1000>><<set $crime = Math.clamp($crime, C.crime.min, C.crime.max)>><<replace "#statscrime">><<print Math.trunc($crime)>><</replace>><</link>>
 <br><br>
 
 <<if $location is "asylum">>
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 7176f8e284..da0220feb1 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -659,26 +659,48 @@
 	<</if>>
 <</widget>>
 
-<<widget "crimeup">>
-<<if $statFreeze isnot true>>
-	<<set _crime_up to 1>>
-	<<for _active_clothes range Object.keys($worn)>>
-		<<if $worn[_active_clothes].type.includes("stealthy")>>
-			<<set _crime_up -= 0.05>>
-		<</if>>
-	<</for>>
+<<widget "crimeup">><<silently>>
+	<<if $statFreeze isnot true>>
 		<<if _args[0]>>
-			<<set $crime += Math.trunc(_args[0] * _crime_up)>>
-			<<set $crimehistory += Math.trunc(_args[0] * _crime_up)>>
+			<<set $_crimemod to _args[0]>>
+			<<if _args[0] gte 1>>
+				<!-- Our crime value is positive, adjust by stealth factor -->
+				<<set $_crimefactor to 1>>
+				/* The following commented code contains experimental factors for calculating stealth */
+				/*
+					<<set $_crime1 to Math.clamp($crime, C.crime.min, C.crime.max / 10)>>
+					<<set $_crime2 to $crime - $_crime1>>
+					<<set $_crime2 to Math.clamp($crime - $_crime1, C.crime.min, C.crime.max / 10)>>
+					<!-- crime1 = first 5k of crime, crime2 = next 5k of crime -->
+					<<set $_normCrime1 to normalise($_crime1, C.crime.max / 10)>>
+					<<set $_normCrime2 to normalise($_crime2, C.crime.max / 10)>>
+					<!-- Both normalized to percentage of max/10 (currently 5k) -->
+					<<set $_stealthReduce1 to expCurve($_normcrime1, 3.0)>>
+					<!-- First 5k of crime at a curve to 5000 -->
+				*/
+				<<set $_stealthfactor to ( 0.15 * ( 1 - normalise($crime, C.crime.max / 5 ) ) )>>
+				<!-- Stealth gives 15%, but reduced by existing crime stat down to 0 at C.crime.max / 5 -->
+				<!-- At 10k crime, stealth equipment is effectively useless - too much evidence -->
+
+				<!-- Filter to all items with type "stealthy" and count them... -->
+				<<set $_stealthMult to Object.values($worn).filter(item => item.type.includes("stealthy")).length>>
+				<<set $_crimefactor -= $_stealthfactor * $_stealthMult>>
+
+				<<set $_crimemod to Math.ceil($_crimemod * $_crimefactor)>>
+				<!-- Add to crime history and Avery crimetracker-->
+				<<set $crimehistory += $_crimemod>>
+				<<if $averyCrimeTracker isnot undefined>>
+					<<set $averyCrimeTracker += $_crimemod>>
+				<</if>>
+			<</if>>
+			<<set $crime += $_crimemod>> <!-- This works for negative values as well! -->
+			<<set $crime to Math.clamp($crime, C.crime.min, C.crime.max)>> <!-- Auto-clamp crime -->
 		<</if>>
 		<<if $slimeEvent is "steal something">>
 			<<unset $slimeEvent>>
 		<</if>>
-	<<if $averyCrimeTracker isnot undefined>>
-	<<set $averyCrimeTracker+= (_args[0] * _crime_up)>>
 	<</if>>
-<</if>>
-<</widget>>
+<</silently>><</widget>>
 
 <<widget "seductionskilluse">>
 	<<set $enemyarousal += ($seductionskill / 100)>><<seductionskill 5>>
diff --git a/game/overworld-town/loc-adultshop/shop.twee b/game/overworld-town/loc-adultshop/shop.twee
index 499f605cb0..31be312ff7 100644
--- a/game/overworld-town/loc-adultshop/shop.twee
+++ b/game/overworld-town/loc-adultshop/shop.twee
@@ -370,7 +370,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Adult Shop]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Adult Shop]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Adult Shop]]>><</link>>
 	<br>
diff --git a/game/overworld-town/loc-police/pillory.twee b/game/overworld-town/loc-police/pillory.twee
index 645cd65920..077d7499e6 100644
--- a/game/overworld-town/loc-police/pillory.twee
+++ b/game/overworld-town/loc-police/pillory.twee
@@ -57,10 +57,7 @@ You have an opportunity to escape, but the <<person>> is aware of that, and keep
 <<else>>
 	<<set $pillorytime to 9>>
 <</if>>
-<<set $crime -= 5000>>
-<<if $crime lte 0>>
-	<<set $crime to 0>>
-<</if>>
+<<crimeup -5000>>
 
 <<bind>>
 The <<person>> moves your arms and head into position before lifting the top into place, restraining you. <<He>> locks it shut and attaches the key to a chain on <<his>> belt. "Someone will be over to release you in $pillorytime hours." <<He>> leaves without looking back.
diff --git a/game/overworld-town/loc-prison/beach.twee b/game/overworld-town/loc-prison/beach.twee
index 88634bd3f4..57969fac00 100644
--- a/game/overworld-town/loc-prison/beach.twee
+++ b/game/overworld-town/loc-prison/beach.twee
@@ -155,12 +155,12 @@ Wren addresses you with one leg resting on the side of the ship. "Any way I can
 	<</if>>
 
 	<<if $prison.kylar is "active">>
-		<<link [[Escape alone (0:30)|Prison Wren Escape]]>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>>
+		<<link [[Escape alone (0:30)|Prison Wren Escape]]>><<prison_end>><<prisoncrimeup>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>>
 		<br>
-		<<link [[Escape with Kylar (0:40)|Prison Kylar Escape]]>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 40>><<prison_guards -40>><<npcincr Kylar rage -60>><<npcincr Kylar love 20>><</link>><<crime>><<gggsuspicion>><<ggglove>><<lllksuspicion>>
+		<<link [[Escape with Kylar (0:40)|Prison Kylar Escape]]>><<prison_end>><<prisoncrimeup>><<pass 40>><<prison_guards -40>><<npcincr Kylar rage -60>><<npcincr Kylar love 20>><</link>><<crime>><<gggsuspicion>><<ggglove>><<lllksuspicion>>
 		<br>
 	<<else>>
-		<<link [[Escape (0:30)|Prison Wren Escape]]>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>>
+		<<link [[Escape (0:30)|Prison Wren Escape]]>><<prison_end>><<prisoncrimeup>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>>
 		<br>
 	<</if>>
 
@@ -558,7 +558,7 @@ You wade out, until a wave lifts your feet from the sand. The water is gentle at
 You keep swimming, until you reach the ring of mist that encircles the island. This is the point of no return.
 <br><br>
 
-<<link [[Escape (0:30)|Prison Escape]]>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>>
+<<link [[Escape (0:30)|Prison Escape]]>><<prison_end>><<prisoncrimeup>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>>
 <br>
 <<link [[Swim back to the prison (0:05)|Prison Beach]]>><<pass 5>><</link>>
 <br>
diff --git a/game/overworld-town/loc-prison/main.twee b/game/overworld-town/loc-prison/main.twee
index 6b259a7fad..7f4bbadafd 100644
--- a/game/overworld-town/loc-prison/main.twee
+++ b/game/overworld-town/loc-prison/main.twee
@@ -1705,7 +1705,7 @@ You run and jump, letting the wind catch your wings. You soar.
 	The <<beastsplural>> are too busy dealing with the revolt to stop, or even notice you. <span class="green">There's nothing stopping you from escaping.</span>
 	<br><br>
 
-	<<link [[Escape (0:30)|Prison Soar Escape]]>><<tiredness 12>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>><<ggtiredness>>
+	<<link [[Escape (0:30)|Prison Soar Escape]]>><<tiredness 12>><<prison_end>><<prisoncrimeup>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>><<ggtiredness>>
 	<br>
 	<<link [[Land|Prison Spire]]>><<endevent>><</link>>
 	<br>
@@ -1720,7 +1720,7 @@ You run and jump, letting the wind catch your wings. You soar.
 	<span class="green">There's nothing stopping you from escaping.</span>
 	<br><br>
 
-	<<link [[Escape (0:30)|Prison Soar Escape]]>><<tiredness 12>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>><<ggtiredness>>
+	<<link [[Escape (0:30)|Prison Soar Escape]]>><<tiredness 12>><<prison_end>><<prisoncrimeup>><<pass 30>><<prison_guards -40>><</link>><<crime>><<gggsuspicion>><<ggtiredness>>
 	<br>
 	<<link [[Land|Prison Spire]]>><<endevent>><</link>>
 	<br>
diff --git a/game/overworld-town/loc-prison/rut.twee b/game/overworld-town/loc-prison/rut.twee
index 46d9c53ef4..efcdd0b38a 100644
--- a/game/overworld-town/loc-prison/rut.twee
+++ b/game/overworld-town/loc-prison/rut.twee
@@ -511,5 +511,5 @@ You awaken in a dark place, far underground. A violent current carries you. You
 The next time you awaken, you're on your back, floating in the sea.<<crime>>
 <br><br>
 
-<<link [[Next|Sea]]>><<set $sea to 100>><<prison_end>><<set $crime += Math.trunc($prison.time * 250)>><<set $crimehistory += Math.trunc($prison.time * 250)>><<pass 30>><</link>>
+<<link [[Next|Sea]]>><<set $sea to 100>><<prison_end>><<prisoncrimeup>><<pass 30>><</link>>
 <br>
diff --git a/game/overworld-town/loc-prison/widgets.twee b/game/overworld-town/loc-prison/widgets.twee
index 6dabd3b257..ab1631cd52 100644
--- a/game/overworld-town/loc-prison/widgets.twee
+++ b/game/overworld-town/loc-prison/widgets.twee
@@ -1618,3 +1618,7 @@ You have the inmates' attention. A thought flashes through your mind. A desire f
 	</div>
 <</if>>
 <</widget>>
+
+<<widget "prisoncrimeup">>
+	<<crimeup ($prison.time * 250)>>
+<</widget>>
diff --git a/game/overworld-town/loc-pub/main.twee b/game/overworld-town/loc-pub/main.twee
index 38944ac438..2e778283c7 100644
--- a/game/overworld-town/loc-pub/main.twee
+++ b/game/overworld-town/loc-pub/main.twee
@@ -219,11 +219,7 @@ You make £<<print $blackmoney>>.
 <<unset $pubtask>>
 <<unset $pubtask2>>
 <<unset $pubtasksetting>>
-<<if $crime gte 10000>>
-	<<set $crime -= 10000>>
-<<else>>
-	<<set $crime to 0>>
-<</if>>
+<<crimeup -10000>>
 <<link [[Leave|Pub]]>><<endevent>><</link>>
 <br>
 
diff --git a/game/overworld-town/skul-shops/main.twee b/game/overworld-town/skul-shops/main.twee
index 15f62e8628..948e0fcac6 100644
--- a/game/overworld-town/skul-shops/main.twee
+++ b/game/overworld-town/skul-shops/main.twee
@@ -32,7 +32,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Dance Studio]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Dance Studio]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Dance Studio]]>><</link>>
 	<br>
@@ -72,7 +72,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Ocean Breeze]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Ocean Breeze]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Ocean Breeze]]>><</link>>
 	<br>
@@ -114,7 +114,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Strip Club]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Strip Club]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Strip Club]]>><</link>>
 	<br>
@@ -154,7 +154,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Clothing Shop]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Clothing Shop]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Clothing Shop]]>><</link>>
 	<br>
@@ -194,7 +194,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Furniture Shop]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Furniture Shop]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Furniture Shop]]>><</link>>
 <</if>>
@@ -234,7 +234,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Hairdressers]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Hairdressers]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Hairdressers]]>><</link>>
 	<br>
@@ -274,7 +274,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Tailor Shop]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Tailor Shop]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Tailor Shop]]>><</link>>
 	<br>
@@ -321,7 +321,7 @@ There's <<printmoney $tip>>.
 <<skulshopevents>>
 <<else>>
 
-<<link [[Take it|Pet Shop]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+<<link [[Take it|Pet Shop]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 <br>
 <<link [[Leave it|Pet Shop]]>><</link>>
 <br>
@@ -368,7 +368,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Toy Shop]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Toy Shop]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Toy Shop]]>><</link>>
 	<br>
@@ -408,7 +408,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Tattoo Parlour]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Tattoo Parlour]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Tattoo Parlour]]>><</link>>
 	<br>
@@ -430,7 +430,7 @@ want to see you around this place at night again, got that?" <<He>> leaves you i
 	You snatch the money from the register and run. <<He>> lunges for you, <span class="green">but you dodge <<his>> hand,</span> leaving <<him>> sprawled on the floor.
 	<br><br>
 	You run from the building, down the street and into an alley. You got away.
-	<<set $money += $tip>><<set $crime += ($tip / 100)>>
+	<<set $money += $tip>><<crimeup ($tip / 100)>>
 	<br><br>
 	<<endevent>>
 	<<destinationeventend>>
@@ -504,7 +504,7 @@ want to see you around this place at night again, got that?" <<He>> leaves you i
 	<<destinationeventend>>
 <<else>>
 	You kick <<him>> away from you. <<tearful>> you scramble to your feet and dash from the building.
-	<<set $money += $tip>><<set $crime += ($tip / 100)>>
+	<<set $money += $tip>><<crimeup ($tip / 100)>>
 	<br><br>
 	<<clotheson>>
 	<<endcombat>>
@@ -540,14 +540,14 @@ want to see you around this place at night again, got that?" <<He>> leaves you i
 	<<ejaculation>>
 	<<He>> avoids eye contact as <<he>> fixes <<his>> clothes. <<tearful>> you walk from the building, taking the money from the register as you do. You slap <<his>> ass on the way out, making <<him>> flinch.
 	<br><br>
-	<<set $money += $tip>><<set $crime += ($tip / 100)>>
+	<<set $money += $tip>><<crimeup ($tip / 100)>>
 	<<clotheson>>
 	<<endcombat>>
 	<<destinationeventend>>
 <<elseif $enemyhealth lte 0>>
 	You kick <<him>> away from you. <<tearful>> you scramble to your feet and dash from the building, snatching the money on the way out.
 	<br><br>
-	<<set $money += $tip>><<set $crime += ($tip / 100)>>
+	<<set $money += $tip>><<crimeup ($tip / 100)>>
 	<<clotheson>>
 	<<endcombat>>
 	<<destinationeventend>>
@@ -598,7 +598,7 @@ There's <<printmoney $tip>>.
 <</if>>
 <br><br>
 
-<<link [[Take it|Riding School]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+<<link [[Take it|Riding School]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 <br>
 <<link [[Leave it|Riding School]]>><</link>>
 <br>
@@ -637,7 +637,7 @@ There's <<printmoney $tip>>.
 <<if $rng gte 86>>
 	<<skulshopevents>>
 <<else>>
-	<<link [[Take it|Spa]]>><<set $money += $tip>><<set $crime += ($tip / 100)>><</link>><<crime>>
+	<<link [[Take it|Spa]]>><<set $money += $tip>><<crimeup ($tip / 100)>><</link>><<crime>>
 	<br>
 	<<link [[Leave it|Spa]]>><</link>>
 	<br>
@@ -687,7 +687,7 @@ There's <<printmoney $tip>>.
 	<span class="blue">There's nothing more you can learn from locks this simple.</span>
 <</if>>
 <br><br>
-<<link [[Take it|School Library]]>><<set $money += $tip>><<set $libraryMoneyStolen += ($tip / 100)>><<set $crime += ($tip / 100)>><</link>><<crime>>
+<<link [[Take it|School Library]]>><<set $money += $tip>><<set $libraryMoneyStolen += ($tip / 100)>><<crimeup ($tip / 100)>><</link>><<crime>>
 <br>
 <<link [[Leave it|School Library]]>><</link>>
 <br>
\ No newline at end of file
diff --git a/game/overworld-town/special-whitney/street.twee b/game/overworld-town/special-whitney/street.twee
index 6e9d417031..c59d027842 100644
--- a/game/overworld-town/special-whitney/street.twee
+++ b/game/overworld-town/special-whitney/street.twee
@@ -1988,7 +1988,7 @@ Soon after, a <<generate1>><<person1>><<person>> comes rushing into the alley. <
 Over <<his>> shoulder, you spy Whitney hiding under a parked car. <<nnpc_He "Whitney">> puts a finger to <<nnpc_his "Whitney">> lips.
 <br><br>
 
-<<link [[Fight|Street Bully Chased Fight]]>><<def 1>><<set $fightstart to 1>><<npcincr Whitney love 1>><<crime 300>><</link>><<glove>><<crime>>
+<<link [[Fight|Street Bully Chased Fight]]>><<def 1>><<set $fightstart to 1>><<npcincr Whitney love 1>><<crimeup 300>><</link>><<glove>><<crime>>
 <br>
 <<set $skulduggerydifficulty to 400>>
 <<link [[Lie|Street Bully Chased 2]]>><<set $phase to 1>><<npcincr Whitney love 1>><<npcincr Whitney dom 1>><</link>><<skulduggerydifficulty>><<glove>>
-- 
GitLab


From 5edd1fd3a65d38c71914657488f90258cdc3d27c Mon Sep 17 00:00:00 2001
From: Host <35009-Host@users.noreply.gitgud.io>
Date: Sun, 28 Aug 2022 02:02:08 +0300
Subject: [PATCH 15/50] Add missing CSS classes for hair dyes in Cheats menu

---
 game/04-Variables/colours.js | 46 +++++++++++------------
 modules/css/theme.css        | 72 ++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 23 deletions(-)

diff --git a/game/04-Variables/colours.js b/game/04-Variables/colours.js
index 6cc710ac08..b155b707b3 100644
--- a/game/04-Variables/colours.js
+++ b/game/04-Variables/colours.js
@@ -296,7 +296,7 @@ setup.colours.hair = [{
 	"variable": "bloodorange",
 	"name": "blood orange",
 	"name_cap": "Blood Orange",
-	"csstext": "",
+	"csstext": "bloodorange",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -306,7 +306,7 @@ setup.colours.hair = [{
 	"variable": "blue",
 	"name": "blue",
 	"name_cap": "Blue",
-	"csstext": "",
+	"csstext": "bluehair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -317,18 +317,18 @@ setup.colours.hair = [{
 	"variable": "deepblue",
 	"name": "deep blue",
 	"name_cap": "Deep Blue",
-	"csstext": "",
+	"csstext": "deepblue",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
-		"blend": "#0d2f73",
+		"blend": "#1349b5",
 		"brightness": -0.3
 	}
 }, {
 	"variable": "neonblue",
 	"name": "neon blue",
 	"name_cap": "Neon Blue",
-	"csstext": "",
+	"csstext": "neonblue",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -338,17 +338,17 @@ setup.colours.hair = [{
 	"variable": "green",
 	"name": "green",
 	"name_cap": "Green",
-	"csstext": "",
+	"csstext": "greenhair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
-		"blend": "#005c00"
+		"blend": "#007400"
 	}
 }, {
 	"variable": "darklime",
 	"name": "dark lime",
 	"name_cap": "Dark Lime",
-	"csstext": "",
+	"csstext": "darklime",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -358,7 +358,7 @@ setup.colours.hair = [{
 	"variable": "toxicgreen",
 	"name": "toxic green",
 	"name_cap": "Toxic Green",
-	"csstext": "",
+	"csstext": "toxicgreen",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -368,7 +368,7 @@ setup.colours.hair = [{
 	"variable": "teal",
 	"name": "teal",
 	"name_cap": "Teal",
-	"csstext": "",
+	"csstext": "tealhair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -378,7 +378,7 @@ setup.colours.hair = [{
 	"variable": "pink",
 	"name": "pink",
 	"name_cap": "Pink",
-	"csstext": "",
+	"csstext": "pinkhair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -388,7 +388,7 @@ setup.colours.hair = [{
 	"variable": "brightpink",
 	"name": "bright pink",
 	"name_cap": "Bright Pink",
-	"csstext": "",
+	"csstext": "brightpink",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -398,7 +398,7 @@ setup.colours.hair = [{
 	"variable": "hotpink",
 	"name": "hot pink",
 	"name_cap": "Hot Pink",
-	"csstext": "",
+	"csstext": "hotpink",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -408,7 +408,7 @@ setup.colours.hair = [{
 	"variable": "softpink",
 	"name": "soft pink",
 	"name_cap": "Soft Pink",
-	"csstext": "",
+	"csstext": "softpink",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -419,7 +419,7 @@ setup.colours.hair = [{
 	"variable": "crimson",
 	"name": "crimson",
 	"name_cap": "Crimson",
-	"csstext": "",
+	"csstext": "crimson",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -429,27 +429,27 @@ setup.colours.hair = [{
 	"variable": "purple",
 	"name": "purple",
 	"name_cap": "Purple",
-	"csstext": "",
+	"csstext": "purplehair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
-		"blend": "#48095d"
+		"blend": "#6a0d89"
 	}
 }, {
 	"variable": "mediumpurple",
 	"name": "medium purple",
 	"name_cap": "Medium Purple",
-	"csstext": "",
+	"csstext": "mediumpurple",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
-		"blend": "#3600b2"
+		"blend": "#5113df"
 	}
 }, {
 	"variable": "brightpurple",
 	"name": "bright purple",
 	"name_cap": "Bright Purple",
-	"csstext": "",
+	"csstext": "brightpurple",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
@@ -459,18 +459,18 @@ setup.colours.hair = [{
 	"variable": "white",
 	"name": "white",
 	"name_cap": "White",
-	"csstext": "",
+	"csstext": "whitehair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
-		"blend": "#808080",
+		"blend": "#BBBBBB",
 		"brightness": 0.3
 	}
 }, {
 	"variable": "snowwhite",
 	"name": "snow white",
 	"name_cap": "Snow White",
-	"csstext": "",
+	"csstext": "snowwhitehair",
 	"natural": false,
 	"dye": true,
 	"canvasfilter": {
diff --git a/modules/css/theme.css b/modules/css/theme.css
index 6096ed16eb..85f542c8e2 100644
--- a/modules/css/theme.css
+++ b/modules/css/theme.css
@@ -453,6 +453,78 @@
 	color: #d47730;
 }
 
+.bloodorange {
+	color: #ff4000;
+}
+
+.bluehair {
+	color: #3973ac;
+}
+
+.deepblue {
+	color: #0d2f73;
+}
+
+.neonblue {
+	color: #00d5ff;
+}
+
+.greenhair {
+	color: #005c00;
+}
+
+.darklime {
+	color: #4a8000;
+}
+
+.toxicgreen {
+	color: #99e600;
+}
+
+.tealhair {
+	color: #008040;
+}
+
+.pinkhair {
+	color: #e05281;
+}
+
+.brightpink {
+	color: #ff80aa;
+}
+
+.hotpink {
+	color: #ff4dc4;
+}
+
+.softpink {
+	color: #d6855c;
+}
+
+.crimson {
+	color: #b30000;
+}
+
+.purplehair {
+	color: #48095d;
+}
+
+.mediumpurple {
+	color: #3600b2;
+}
+
+.brightpurple {
+	color: #ab66ff;
+}
+
+.whitehair {
+	color: #808080;
+}
+
+.snowwhitehair {
+	color: #FFFFFF;
+}
+
 .softblond {
 	color: #e4cd87;
 }
-- 
GitLab


From 988d164360bd8774021eb27db979615ce39dde31 Mon Sep 17 00:00:00 2001
From: Host <35009-Host@users.noreply.gitgud.io>
Date: Sun, 28 Aug 2022 02:41:22 +0300
Subject: [PATCH 16/50] Add persistent mascara smears

- Mascara smears persist after tears dry out
- Add a black waterproof mascara colour
- Fix running mascara layer being rendered below freckles
- Replace hardcoded tears calculation from pain with a function
---
 game/03-JavaScript/ingame.js                   | 14 +++++++++++++-
 game/04-Variables/canvasmodel-00-data.js       |  1 +
 game/04-Variables/canvasmodel-main.js          |  8 +++++---
 game/04-Variables/colours.js                   |  8 ++++++++
 game/04-Variables/variables-start.twee         |  1 +
 game/04-Variables/variables-versionUpdate.twee |  6 ++++++
 game/base-clothing/canvasmodel-img.twee        |  5 ++++-
 game/base-clothing/images.twee                 |  4 ++--
 game/base-combat/doggy-images.twee             | 12 ++++++------
 game/base-combat/missionary-images.twee        | 12 ++++++------
 game/base-system/effects.twee                  |  3 +++
 game/base-system/mirror.twee                   | 11 +++++++++--
 game/base-system/widgets.twee                  |  7 +++++--
 modules/css/base.css                           |  9 ++++++---
 modules/css/theme.css                          |  3 ++-
 15 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index f20a3f7b0b..60e82b4283 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -1503,4 +1503,16 @@ window.combatCharacterShadow = function() {
 		.clone(true).removeClass((i, n) => (n.match(/(^|\s)(colour|layer)-\S+/g) || []).join(' '))
 		.addClass(targetClass).removeAttr('style').appendTo($(mainDiv).last());
 	});
-}
\ No newline at end of file
+}
+
+window.painToTearsLvl = function(pain) {
+	/**
+	 * For usage with tears calculation, converts pain stat [0..200] to 0..4 range (maxes out at pain = 80)
+	 */
+	pain ??= V.pain;
+	return Math.floor(Math.clamp(pain, 0, 99) / 20);
+}
+
+window.mascaraNameToCSS = function(name) {
+	return setup.colours.mascara.find(x => x.variable == name)?.csstext;
+}
diff --git a/game/04-Variables/canvasmodel-00-data.js b/game/04-Variables/canvasmodel-00-data.js
index 88c01a4a15..ee76df2428 100644
--- a/game/04-Variables/canvasmodel-00-data.js
+++ b/game/04-Variables/canvasmodel-00-data.js
@@ -25,6 +25,7 @@ var ZIndices = {
 	tanbreasts: 30,
 	blush: 50,
 	freckles: 51,
+	mascara_running: 51.5,
 	skin: 52,
 	tears: 55,
 	hair: 60,
diff --git a/game/04-Variables/canvasmodel-main.js b/game/04-Variables/canvasmodel-main.js
index 3ec76fb2a2..1e0001c9f6 100644
--- a/game/04-Variables/canvasmodel-main.js
+++ b/game/04-Variables/canvasmodel-main.js
@@ -90,6 +90,7 @@ replace (?<!["'\w])_(?=\w) with T.
  * "lipstick_colour": "" (none), key from setup.colours.lipstick_map, or "custom" ("lipstick" filter required)
  * "eyeshadow_colour": "" (none), key from setup.colours.eyeshadow_map, or "custom" ("eyeshadow" filter required)
  * "mascara_colour": "" (none), key from setup.colours.mascara_map, or "custom" ("mascara" filter required)
+ * "mascara_running": number - mascara smear level, 0..4, 0 is "no smears"
  *
  * TF OPTIONS: ("disabled" & "hidden" types hide the layer)
  * ----------
@@ -276,6 +277,7 @@ Renderer.CanvasModels["main"] = {
 			"lipstick_colour": "",
 			"eyeshadow_colour": "",
 			"mascara_colour": "",
+			"mascara_running": 0,
 			// tf
 			"angel_wings_type": "disabled",
 			"angel_wing_right": "idle",
@@ -961,13 +963,13 @@ Renderer.CanvasModels["main"] = {
 		},
 		"makeup_mascara_tears": {
 			srcfn(options) {
-				return 'img/face/' + options.facestyle + '/' + 'makeup/mascara' + options.tears + '.png'
+				return 'img/face/' + options.facestyle + '/' + 'makeup/mascara' + options.mascara_running + '.png'
 			},
 			showfn(options) {
-				return options.show_face && options.tears > 0 && !!options.mascara_colour
+				return options.show_face && options.mascara_running > 0 && !!options.mascara_colour
 			},
 			filters: ["mascara"],
-			z: ZIndices.lashes
+			z: ZIndices.mascara_running
 		},
 		/***
 		 *    ██   ██  █████  ██ ██████
diff --git a/game/04-Variables/colours.js b/game/04-Variables/colours.js
index 6cc710ac08..2ecadf6797 100644
--- a/game/04-Variables/colours.js
+++ b/game/04-Variables/colours.js
@@ -1094,6 +1094,14 @@ setup.colours.mascara = [
 		canvasfilter: {
 			blend: "#292929"
 		}
+	}, {
+		variable: "black waterproof",
+		name: "black (waterproof)",
+		name_cap: "Black (waterproof)",
+		csstext: "black",
+		canvasfilter: {
+			blend: "#292929"
+		}
 	}
 ];
 
diff --git a/game/04-Variables/variables-start.twee b/game/04-Variables/variables-start.twee
index c9675e89b7..3817df13dc 100644
--- a/game/04-Variables/variables-start.twee
+++ b/game/04-Variables/variables-start.twee
@@ -818,6 +818,7 @@
 	<<set $makeup.eyeshadow = 0>>
 	<<set $makeup.eyelenses = {"left":0, "right":0}>>
 	<<set $makeup.mascara = 0>>
+	<<set $makeup.mascara_running = 0>>
 	<<set $makeup.pbcolour = 0>>
 	<<set $makeup.browscolour = 0>>
 	<<set $makeup.concealer = 0>>
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index 2f578c289b..bfd81befc7 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -1657,6 +1657,7 @@
 	<<set $makeup.eyeshadow = 0>>
 	<<set $makeup.eyelenses = {"left":0, "right":0}>>
 	<<set $makeup.mascara = 0>>
+	<<set $makeup.mascara_running = 0>>
 	<<set $makeup.pbcolour = 0>>
 	<<set $makeup.browscolour = 0>>
 	<<set $makeup.concealer = 0>>
@@ -3642,4 +3643,9 @@
 		<<unset $crimemax>>
 	<</if>>
 
+	<!-- v0.3.11.4 - Add $makeup.mascara_running -->
+	<<if $makeup.mascara_running is undefined>>
+		<<set $makeup.mascara_running = 0>>
+	<</if>>
+
 <</widget>>
diff --git a/game/base-clothing/canvasmodel-img.twee b/game/base-clothing/canvasmodel-img.twee
index da1c139186..9e42868ff4 100644
--- a/game/base-clothing/canvasmodel-img.twee
+++ b/game/base-clothing/canvasmodel-img.twee
@@ -67,6 +67,9 @@ if ($skinColor.tanningEnabled is true){
 <<if $makeup.mascara != 0>>
 	<<set _modeloptions.mascara_colour to $makeup.mascara>>
 <</if>>
+<<if $makeup.mascara_running != 0>>
+	<<set _modeloptions.mascara_running to $makeup.mascara_running>>
+<</if>>
 <<if $makeup.lipstick != 0>>
 	<<set _modeloptions.lipstick_colour to $makeup.lipstick>>
 <</if>>
@@ -309,7 +312,7 @@ $worn.under_upper.type.includes("naked") and $worn.under_lower.type.includes("na
 <</if>>
 
 <!-- Tears -->
-<<set _modeloptions.tears = Math.floor(Math.clamp($pain, 0, 99) / 20)>>
+<<set _modeloptions.tears = painToTearsLvl($pain)>>
 
 <!--
  -    ████████ ███████ ███████
diff --git a/game/base-clothing/images.twee b/game/base-clothing/images.twee
index 26fabb8445..143835ed5f 100644
--- a/game/base-clothing/images.twee
+++ b/game/base-clothing/images.twee
@@ -750,9 +750,9 @@
 
 		<!-- Tears -->
 		<<if $pain gte 20>>
-			<img class="layer-tears anim-idle-2f" @src="'img/face/' + $facestyle + '/' + 'tear' + Math.floor(Math.clamp($pain, 0, 99) / 20) + '.png'">
+			<img class="layer-tears anim-idle-2f" @src="'img/face/' + $facestyle + '/' + 'tear' + painToTearsLvl($pain) + '.png'">
 			<<if $makeup.mascara != 0>>
-				<img @class="'layer-lashes ' + _blink + ' mascara-' + $makeup.mascara.replace(/ /g, '-')" @src="'img/face/' + $facestyle + '/' + 'makeup/mascara' + Math.floor(Math.clamp($pain, 0, 99) / 20) + '.png'">
+				<img @class="'layer-lashes ' + _blink + ' mascara-' + $makeup.mascara.replace(/ /g, '-')" @src="'img/face/' + $facestyle + '/' + 'makeup/mascara' + painToTearsLvl($pain) + '.png'">
 			<</if>>
 		<</if>>
 	<</if>>
diff --git a/game/base-combat/doggy-images.twee b/game/base-combat/doggy-images.twee
index c501d587e3..68ecb4b552 100644
--- a/game/base-combat/doggy-images.twee
+++ b/game/base-combat/doggy-images.twee
@@ -405,10 +405,10 @@ Mouth is closed in idle frames here. activeclosedmouth can be used in active, th
 <</if>>
 
 <<if $makeup.mascara>>
-	<<if $pain gte 20>>
-		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" @src="'img/sex/doggy/makeup/mascara_' + Math.floor(Math.clamp($pain, 0, 99) / 20) + '.png'">
+	<<if $makeup.mascara_running gte 1>>
+		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" @src="'img/sex/doggy/makeup/mascara_' + $makeup.mascara_running + '.png'">
 	<<else>>
-		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" src="img/sex/doggy/makeup/mascara.png">
+		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" src="img/sex/doggy/makeup/mascara.png">
 	<</if>>
 <</if>>
 
@@ -789,10 +789,10 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 <</if>>
 
 <<if $makeup.mascara>>
-	<<if $pain gte 20>>
-		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" @src="'img/sex/doggy/makeup/mascara_eyelids_' + Math.floor(Math.clamp($pain, 0, 99) / 20) + '.png'">
+	<<if $makeup.mascara_running gte 1>>
+		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" @src="'img/sex/doggy/makeup/mascara_eyelids_' + $makeup.mascara_running + '.png'">
 	<<else>>
-		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" src="img/sex/doggy/makeup/mascara_eyelids.png">
+		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" src="img/sex/doggy/makeup/mascara_eyelids.png">
 	<</if>>
 <</if>>
 
diff --git a/game/base-combat/missionary-images.twee b/game/base-combat/missionary-images.twee
index f6a1b2cc08..1e06c33fc8 100644
--- a/game/base-combat/missionary-images.twee
+++ b/game/base-combat/missionary-images.twee
@@ -245,10 +245,10 @@ Previous "Always Open" mouth. activemouth can be used in all active frames still
 <</if>>
 
 <<if $makeup.mascara>>
-	<<if $pain gte 20>>
-		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" @src="'img/sex/missionary/makeup/mascara_' + Math.floor(Math.clamp($pain, 0, 99) / 20) + '.png'">
+	<<if $makeup.mascara_running gte 1>>
+		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" @src="'img/sex/missionary/makeup/mascara_' + $makeup.mascara_running + '.png'">
 	<<else>>
-		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" src="img/sex/missionary/makeup/mascara.png">
+		<img @class="'layer-sexblush anim-doggy-2f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" src="img/sex/missionary/makeup/mascara.png">
 	<</if>>
 <</if>>
 
@@ -637,10 +637,10 @@ Same as above, but with eyelashes.
 <</if>>
 
 <<if $makeup.mascara>>
-	<<if $pain gte 20>>
-		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" @src="'img/sex/missionary/makeup/mascara_eyelids_' + Math.floor(Math.clamp($pain, 0, 99) / 20) + '.png'">
+	<<if $makeup.mascara_running gte 1>>
+		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" @src="'img/sex/missionary/makeup/mascara_eyelids_' + $makeup.mascara_running + '.png'">
 	<<else>>
-		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + $makeup.mascara.replace(/ /g, '-')" src="img/sex/missionary/makeup/mascara_eyelids.png">
+		<img @class="'layer-sexblush anim-doggy-4f-'+_animspeed+' mascara-' + mascaraNameToCSS($makeup.mascara)" src="img/sex/missionary/makeup/mascara_eyelids.png">
 	<</if>>
 <</if>>
 
diff --git a/game/base-system/effects.twee b/game/base-system/effects.twee
index ffcd88b4d8..c8b4c57c36 100644
--- a/game/base-system/effects.twee
+++ b/game/base-system/effects.twee
@@ -188,6 +188,9 @@
 	<<unset $makeupWashed>>
 	<span class="teal">Your makeup is washed away<<if $beauty gte ($beautymax / 7) * 4>> revealing your natural beauty<</if>>.</span><br>
 <</if>>
+<<if $makeup.mascara and $makeup.mascara_running < painToTearsLvl($pain) and !$makeup.mascara.contains('waterproof')>>
+	<<set $makeup.mascara_running = painToTearsLvl($pain)>>
+<</if>>
 <</widget>>
 
 <<widget "effects">>
diff --git a/game/base-system/mirror.twee b/game/base-system/mirror.twee
index 50f2fefd3f..cf972a08e8 100644
--- a/game/base-system/mirror.twee
+++ b/game/base-system/mirror.twee
@@ -1235,6 +1235,9 @@ Your fringe is in the "$fringetype" style.
 		<span class="no-numberify">
 		<<link "Remove">>
 		<<set $makeup[_itemType] = 0>>
+		<<if _itemType == 'mascara'>>
+			<<set $makeup.mascara_running = 0>>
+		<</if>>
 		<<run Engine.show()>>
 		<</link>></span>
 		<<print " | ">>
@@ -1244,11 +1247,14 @@ Your fringe is in the "$fringetype" style.
 		<<capture _item, _itemType>>
 			<span class="capitalize no-numberify">
 			<<if $makeup[_itemType] == _item.colour>>
-				_item.colour
+				<<print setup.colourName(_item.colour)>>
 			<<else>>
-				<<link _item.colour>>
+				<<link `setup.colourName(_item.colour)`>>
 					<<set $makeup[_itemType] = _item.colour>>
 					<<set _item.count -= 1>>
+					<<if _itemType == 'mascara'>>
+						<<set $makeup.mascara_running = 0>>
+					<</if>>
 					<<run Engine.show()>>
 				<</link>>
 			<</if>>
@@ -1286,6 +1292,7 @@ __Makeup__
 	<<set $makeup.lipstick to 0>>
 	<<set $makeup.eyeshadow to 0>>
 	<<set $makeup.mascara to 0>>
+	<<set $makeup.mascara_running to 0>>
 	<<set $makeup.eyelenses to { "left": 0, "right": 0 }>>
 <</link>> |
 <<link [[Randomise|$passage]]>>
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index da0220feb1..9dae3f9f01 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -3021,11 +3021,14 @@ It
 <</widget>>
 
 <<widget "washmakeup">>
-<<if $makeup.lipstick != 0 or $makeup.eyeshadow != 0 or $makeup.mascara != 0 or $makeup.concealer != 0>>
+<<if $makeup.lipstick != 0 or $makeup.eyeshadow != 0 or ($makeup.mascara != 0 and !$makeup.mascara.contains('waterproof')) or $makeup.concealer != 0>>
 	<<set $makeupWashed = 1>>
 	<<set $makeup.lipstick = 0>>
 	<<set $makeup.eyeshadow = 0>>
-	<<set $makeup.mascara = 0>>
+	<<if $makeup.mascara and !$makeup.mascara.contains('waterproof')>>
+		<<set $makeup.mascara = 0>>
+		<<set $makeup.mascara_running = 0>>
+	<</if>>
 	<<set $makeup.concealer = 0>>
 <</if>>
 <</widget>>
diff --git a/modules/css/base.css b/modules/css/base.css
index 5544be6bcb..e396d43048 100644
--- a/modules/css/base.css
+++ b/modules/css/base.css
@@ -4523,7 +4523,8 @@ label {
 	filter: hue-rotate(45deg) brightness(1) saturate(1) contrast(0.6);
 }
 
-.eyeshadow-light-brown {
+.eyeshadow-light-brown,
+.eyeshadow-lightbrown {
 	-webkit-filter: hue-rotate(40deg) brightness(4) saturate(0.7) contrast(0.5);
 	filter: hue-rotate(40deg) brightness(4) saturate(0.7) contrast(0.5);
 }
@@ -4534,12 +4535,14 @@ label {
 }
 
 .eyeshadow-black,
-.mascara-black {
+.mascara-black,
+.mascara-black-waterproof {
 	-webkit-filter: hue-rotate(0deg) brightness(0.1) saturate(0) contrast(0.7);
 	filter: hue-rotate(0deg) brightness(0.1) saturate(0) contrast(0.7);
 }
 
-.eyeshadow-white {
+.eyeshadow-white,
+.mascara-white {
 	-webkit-filter: hue-rotate(250deg) brightness(8) saturate(0) contrast(1);
 	filter: hue-rotate(250deg) brightness(8) saturate(0) contrast(1);
 }
diff --git a/modules/css/theme.css b/modules/css/theme.css
index 6096ed16eb..55b3f10f6c 100644
--- a/modules/css/theme.css
+++ b/modules/css/theme.css
@@ -445,7 +445,8 @@
 	color: #a45e16;
 }
 
-.lightbrown {
+.lightbrown,
+.light-brown {
 	color: #c5793a;
 }
 
-- 
GitLab


From 702edd2a77440b85b87613d16e11c00abb1e73f3 Mon Sep 17 00:00:00 2001
From: Crimson Tide <literallyjustrandomletters@gmail.com>
Date: Tue, 30 Aug 2022 09:06:51 +0000
Subject: [PATCH 17/50] Anal parasite tooltips

---
 game/04-Variables/pregnancyVar.twee           |  30 ++
 .../04-Variables/variables-versionUpdate.twee |   4 +-
 game/base-system/feats.twee                   |  13 +
 game/base-system/pregnancy/containers.twee    | 378 +++++++++++++-----
 game/base-system/pregnancy/events.twee        | 102 +++--
 game/base-system/pregnancy/pregnancy.twee     |  52 ++-
 game/overworld-forest/loc-lake/main.twee      |   8 +-
 game/overworld-plains/loc-farm/upgrades.twee  |   4 +-
 game/overworld-plains/loc-farm/work.twee      |   4 +-
 game/overworld-town/loc-home/main.twee        |  10 +-
 game/overworld-town/loc-hospital/main.twee    |   2 +-
 game/overworld-town/loc-shop/petShop.twee     |  30 +-
 12 files changed, 481 insertions(+), 156 deletions(-)

diff --git a/game/04-Variables/pregnancyVar.twee b/game/04-Variables/pregnancyVar.twee
index 3984bda500..bc25612aaf 100644
--- a/game/04-Variables/pregnancyVar.twee
+++ b/game/04-Variables/pregnancyVar.twee
@@ -95,6 +95,36 @@
 	}>>
 	<<set $container.list.pushUnique("farm")>>
 <</if>>
+
+<<if $sexStats.anus.pregnancy.typesSeen is undefined or $sexStats.anus.pregnancy.variantsSeen is undefined>>
+	<<set $sexStats.anus.pregnancy.typesSeen to []>><<set $sexStats.anus.pregnancy.variantsSeen to []>>
+	<<for _i range $container.list>>
+		<<for _o to 0; _o lt $container[_i].maxCount; _o++>>
+			<<if $container[_i].creatures[_o] isnot undefined and $container[_i].creatures[_o] isnot null>>
+				<<if $container[_i].creatures[_o].creature.includes("Tentacle")>>
+					<<set $sexStats.anus.pregnancy.typesSeen.pushUnique("Tentacle")>>
+				<<elseif $container[_i].creatures[_o].creature.includes("Vine")>>
+					<<set $sexStats.anus.pregnancy.typesSeen.pushUnique("Vine")>>
+				<<elseif $container[_i].creatures[_o].creature.includes("Slime")>>
+					<<set $sexStats.anus.pregnancy.typesSeen.pushUnique("Slime")>>
+				<<else>>
+					<<set $sexStats.anus.pregnancy.typesSeen.pushUnique($container[_i].creatures[_o].creature)>>
+				<</if>>
+				<<if $container[_i].creatures[_o].creature.includes("Pale")>>
+					<<set $sexStats.anus.pregnancy.variantsSeen.pushUnique("Pale")>>
+				<<elseif $container[_i].creatures[_o].creature.includes("Metal")>>
+					<<set $sexStats.anus.pregnancy.variantsSeen.pushUnique("Metal")>>
+				<</if>>
+			<<else>>
+				<<break>>
+			<</if>>
+		<</for>>
+	<</for>>
+<</if>>
+
+<<if $containerVine or $containerMetal or $containerPale>>
+	<<unset $containerVine, $containerMetal, $containerPale>>
+<</if>>
 <</widget>>
 
 <<widget "prenancyObjectRepair">>
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index 2f578c289b..ba8853e193 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -2624,7 +2624,7 @@
 	<</if>>
 <</for>>
 
-<<pregnancyVar>>
+<!-- pregnancyVar was moved to <<backComp>>-->
 <</widget>>
 
 <<widget "backComp">>
@@ -2667,6 +2667,8 @@
 		<<set $nectar_timer to 0>>
 	<</if>>
 
+	<<pregnancyVar>>
+
 	<<if $hypnotised is undefined>>
 		<<set $hypnotised to 0>>
 		<<set $famemodel to 0>>
diff --git a/game/base-system/feats.twee b/game/base-system/feats.twee
index c3442d3ede..b06aa4b1c1 100644
--- a/game/base-system/feats.twee
+++ b/game/base-system/feats.twee
@@ -500,6 +500,11 @@
 		<<if $sexStats.anus.pregnancy.motherStatus is 2>>
 			<<earnFeat "Broodmother Host">>
 		<</if>>
+		<<if $sexStats.anus.pregnancy.typesSeen.length gte 14 and $sexStats.anus.pregnancy.variantsSeen.length gte 2 and $sexStats.anus.pregnancy.book is 3>>
+			<!-- typesSeen: fish, snake, slime, spider, maggot, worm, eel, wasp, bee, lurker, squid, slug, tentacle, vine -->
+			<!-- variantsSeen: pale, metal -->
+			<<earnFeat "Broodmother Zoologist">>
+		<</if>>
 		<<if $spraymax gte 7>>
 			<<earnFeat "Max Those Shots">>
 		<</if>>
@@ -1258,6 +1263,14 @@
 			filter: ["All", "Special"],
 			hint: "Hint: Something amazing left behind."
 		},
+		"Broodmother Zoologist":{
+			title: "Broodmother Zoologist",
+			desc: "Filled out the parasite notebook.",
+			difficulty: 3,
+			series: "",
+			filter: ["All", "Special"],
+			hint: "Hint: Everything left behind, carefully detailed."
+		},
 		"Producer of Lewd Fluids":{
 			title: "Producer of Lewd Fluids",
 			desc: "Those tentacles know who's boss.",
diff --git a/game/base-system/pregnancy/containers.twee b/game/base-system/pregnancy/containers.twee
index ecbb1d9a4a..83dce9c0d2 100644
--- a/game/base-system/pregnancy/containers.twee
+++ b/game/base-system/pregnancy/containers.twee
@@ -1,5 +1,6 @@
 :: Widgets containers [widget]
 <<widget "creatureActivity">>
+<!-- Activity is determined by parasite's speed stat -->
 <<if _args[0]>>
 	<<if _args[0] lt 60>>
 		<span class="gold">Perfect activity</span>
@@ -23,6 +24,7 @@
 <</widget>>
 
 <<widget "creatureContainersProgressDay">>
+<!-- Runs once per day -->
 <<set _list to $container.list>>
 <<for _i to 0; _i lt _list.length; _i++>>
 	<<set _container to $container[_list[_i]]>>
@@ -31,6 +33,7 @@
 		<<continue>>
 	<</if>>
 	<<if _list[_i] is "home">>
+		<!-- Kylar will help feed your home parasites at high love. This is told to the player with a note signed "K" -->
 		<<if $NPCName[$NPCNameList.indexOf("Kylar")].love gte 75 and $NPCName[$NPCNameList.indexOf("Kylar")].state is "active">>
 			<<set _container.kylarHelp to true>>
 		<<else>>
@@ -47,9 +50,11 @@
 	<</if>>
 	<<set _container.daysSinceFed += 1>>
 	<<if _container.daysSinceFed gt _container.maxDaysWithoutFood>>
+		<!-- Parasites die if they don't get fed enough. The max time you can leave them is determined by tank size/parasite barn quality -->
 		<<set _container.deadCreatures to _container.count>>
 		<<for _i to 0; _i lt _container.count; _i++>>
 			<<if _container.creatures[_i].creature.includes("Pale") and $wraith and $wraith.state isnot "">>
+				<!-- If a pale parasite dies, the Ivory Wraith becomes angry, and encounters become more dangerous -->
 				<<set $wraith.offspring to "dead">>
 				<<set $wraithAnger to 30>>
 				<<set $wraithShow to true>>
@@ -63,110 +68,295 @@
 <</widget>>
 
 <<widget "creatureVisit">>
-<<set _container to $container[$location]>>
+<!-- You can visit each location to get stat reductions once per day -->
 <<set _container.visited to true>>
 <<set _container.daysSinceFed to 0>>
+<<if _args[0] is false>>
+	<<set $_notVisited to false>>
+<<else>>
+	<<set $_notVisited to true>>
+<</if>>
+<<set $_creature to []>><<set _creatureTip to []>><<set _luxuryTip to []>>
 
-/*stress, trauma, fatigue, purity, impurity, hallucinogens*/
-<<set _boosts to [false,false,false,false,false,false]>>
-<<set _purityGain to 0>><<set _tenticles to 0>><<set _paleChance to 0>>
+/*stress, trauma, fatigue, purity, hallucinogens*/
+<<set _boosts to {stress: 0, trauma: 0, tiredness: 0, purity: 0, hallucinogen: 0}>>
+<<set _tenticles to 0>><<set _paleChance to 0>>
 <<for _i to 0; _i lt _container.maxCount; _i++>>
-	<<if _container.creatures[_i] is undefined>>
+	<<if _container.creatures[_i] is undefined or _container.creatures[_i] is null>>
 		<<continue>>
 	<</if>>
-	<<if _container.creatures[_i] isnot null>>
-		<<set _tendingMulti to 1 + (currentSkillValue('tending') / 1000)>>
-		<<set _value = Math.floor(5000 / _container.creatures[_i].stats.speed)>>
-		<<if _container.upgrades.luxury gt 0>>
-			<<set _value to Math.floor(_value * (1 + (0.25 * _container.upgrades.luxury)))>>
-		<</if>>
-		<<if _value gt 0>>
-			<<set $stress -= Math.floor(_value * _tendingMulti)>>
-			<<set _boosts[0] to true>>
-		<</if>>
-		<<if Math.floor(_value / 8) gt 0>>
-			<<set $trauma -= Math.floor(_value / 8)>>
-			<<set _boosts[1] to true>>
-			<<traumaclamp>>
-		<</if>>
-		<<if _container.creatures[_i].creature is "Slime">>
-			<<set _purityGain += 0.5>>
-		<</if>>
-		<<if _container.creatures[_i].creature is "Pale Slime">>
-			<<set _purityGain += 1.5>>
-			<<hallucinogen 20>>
-			<<set _boosts[5] to true>>
-			<<set _paleChance ++>>
-		<</if>>
-		<<if _container.creatures[_i].creature is "Worm">>
-			<<set _purityGain -= 0.5>>
-		<</if>>
-		<<if _container.creatures[_i].creature is "Tentacle">>
-			<<if Math.floor(_value / 4) gt 0>>
-				<<set $tiredness -= Math.floor((_value / 4) * _tendingMulti)>>
-				<<set _boosts[2] to true>>
-			<</if>>
-			<<set _tenticles += 0.5>>
-		<</if>>
-		<<if _container.creatures[_i].creature is "Pale Tentacle">>
-			<<if Math.floor(_value / 3) gt 0>>
-				<<set $tiredness -= Math.floor((_value / 3) * _tendingMulti)>>
-				<<set _boosts[2] to true>>
-				<<hallucinogen 30>>
-				<<set _boosts[5] to true>>
-				<<set _paleChance ++>>
-			<</if>>
-			<<set _tenticles += 1.5>>
+	<<set $_creature[_i] to {tiredness: 0, purity: 0, hallucinogen: 0, tenticles: 0}>>
+	<<set _creatureTip[_i] to []>>
+	<!-- Higher tending increases stress and fatigue losses -->
+	<<set _tendingMulti to 1 + (currentSkillValue('tending') / 1000)>>
+	<<set _pregValue = Math.floor(5000 / _container.creatures[_i].stats.speed)>>
+	<<if _container.upgrades.luxury gt 0>>
+		<!-- Decorations/barn quality increase value -->
+		<<set _pregValue to Math.floor(_pregValue * (1 + (0.25 * _container.upgrades.luxury)))>>
+	<</if>>
+	<<if _pregValue gt 0>>
+		<!-- The decorations get a tooltip noting that stress is reduced -->
+		<<set _boosts.stress += Math.floor(_pregValue * _tendingMulti)>>
+		<<set _luxuryTip.pushUnique("- Stress")>>
+	<</if>>
+	<<if Math.floor(_pregValue / 8) gt 0>>
+		<!-- With high enough value, trauma is also reduced -->
+		<<set _boosts.trauma += Math.floor(_pregValue / 8)>>
+		<<set _luxuryTip.pushUnique("- Trauma")>>
+	<</if>>
+	<<if _container.creatures[_i].creature is "Slime">>
+		<!-- Slimes innately raise purity -->
+		<<set _boosts.purity += 0.5>>
+		<<set $_creature[_i].purity += 0.5>>
+	<</if>>
+	<<if _container.creatures[_i].creature is "Pale Slime">>
+		<!-- Pale slimes raise purity more, and also raise hallucinogens -->
+		<<set _boosts.purity += 1.5>>
+		<<set _boosts.hallucinogen += 20>>
+		<<set $_creature[_i].purity += 1.5>>
+		<<set $_creature[_i].hallucinogen to 1>>
+		<<set _paleChance++>>
+	<</if>>
+	<<if _container.creatures[_i].creature is "Worm">>
+		<!-- Worms innately lower purity -->
+		<<set _boosts.purity -= 0.5>>
+		<<set $_creature[_i].purity -= 0.5>>
+	<</if>>
+	<<if _container.creatures[_i].creature is "Pale Tentacle">>
+		<!-- Pale tentacles lower fatigue, and impact purity based on other parasites -->
+		<<if Math.floor(_pregValue / 3) gt 0>>
+			<<set _boosts.tiredness += Math.floor((_pregValue / 3) * _tendingMulti)>>
+			<<set _boosts.hallucinogen += 30>>
+			<<set $_creature[_i].tiredness to 1>>
+			<<set $_creature[_i].hallucinogen to 1>>
+			<<set _paleChance++>>
+		<</if>>
+		<<set _tenticles += 1.5>><<set $_creature[_i].tenticles += 1.5>>
+	<<elseif _container.creatures[_i].creature.includes("Tentacle") or _container.creatures[_i].creature.includes("Vine")>>
+		<!-- Other tentacles and vines also impact fatigue and purity, but less than pale tentacles -->
+		<<if Math.floor(_pregValue / 4) gt 0>>
+			<<set _boosts.tiredness += Math.floor((_pregValue / 4) * _tendingMulti)>>
+			<<set $_creature[_i].tiredness to 1>>
 		<</if>>
-		<<if _container.creatures[_i].creature is "Vine">>
-			<<set _tenticles += 0.5>>
+		<<set _tenticles += 0.5>><<set $_creature[_i].tenticles += 0.5>>
+	<</if>>
+	<<if Object.keys($_creature[_i]).length gte 1>>
+		<!-- Adding the tooltips -->
+		<<if $_creature[_i].tiredness is 1>>
+			<<set _creatureTip[_i].pushUnique("- Fatigue")>>
+		<</if>>
+		<<if $_creature[_i].purity gt 0>>
+			<<set _creatureTip[_i].pushUnique("+ Purity (natural)")>>
+		<<elseif $_creature[_i].purity lt 0>>
+			<<set _creatureTip[_i].pushUnique("- Purity (natural)")>>
+		<</if>>
+		<<if $_creature[_i].hallucinogen is 1>>
+			<<set _creatureTip[_i].pushUnique("+ Hallucinations")>>
 		<</if>>
 	<</if>>
 <</for>>
 
-<<if _purityGain gt 0>>
-	<<set _purityGain += _tenticles>>
-<<elseif _purityGain lt 0>>
-	<<set _purityGain -= _tenticles>>
+<!-- Tentacle purity calculation and tooltips -->
+<<if _boosts.purity gt 0>>
+	<<set _boosts.purity += _tenticles>>
+<<elseif _boosts.purity lt 0>>
+	<<set _boosts.purity -= _tenticles>>
 <</if>>
-<<if Math.floor(_purityGain) gt 0>>
-	<<set _purityGain to Math.floor(_purityGain)>>
-	<<set _boosts[3] to true>>
-<<elseif Math.ceil(_purityGain) lt 0>>
-	<<set _purityGain to Math.ceil(_purityGain)>>
-	<<set _boosts[4] to true>>
-<</if>>
-<<purity _purityGain>>
+<<set _boosts.purity to Math.ceil(_boosts.purity)>>
+<<for _i to 0; _i lt _creatureTip.length; _i++>>
+	<<if _container.creatures[_i] is undefined or _container.creatures[_i] is null>>
+		<<continue>>
+	<</if>>
+	<<if $_creature[_i].tenticles isnot 0>>
+		<<if _boosts.purity gte 1>>
+			<<set _creatureTip[_i].pushUnique("+ Purity (inherited)")>>
+		<<elseif _boosts.purity lte -1>>
+			<<set _creatureTip[_i].pushUnique("- Purity (inherited)")>>
+		<</if>>
+	<</if>>
+<</for>>
 
-<<if _boosts[0]>> <<lstress>><</if>>
-<<if _boosts[1]>> <<ltrauma>><</if>>
-<<if _boosts[2]>> <<ltiredness>><</if>>
-<<if _boosts[3]>> <<gpurity>><</if>>
-<<if _boosts[4]>> <<lpurity>><</if>>
-<<if _boosts[5]>> <<ghallucinogens>><</if>>
+<<if $_notVisited>>
+	<!-- Stat changes only happen once per day -->
+	<<if _boosts.stress isnot 0>>
+		<<set $stress -= _boosts.stress>><<lstress>>
+	<</if>>
+	<<if _boosts.trauma isnot 0>>
+		<<set $trauma -= _boosts.trauma>><<traumaclamp>><<ltrauma>>
+	<</if>>
+	<<if _boosts.tiredness isnot 0>>
+		<<set $tiredness -= _boosts.tiredness>><<ltiredness>>
+	<</if>>
+	<<if _boosts.purity isnot 0>>
+		<<purity _boosts.purity>>
+		<<if _boosts.purity gt 0>><<gpurity>><<else>><<lpurity>><</if>>
+	<</if>>
+	<<if _boosts.hallucinogen isnot 0>>
+		<<hallucinogen _boosts.hallucinogen>><<ghallucinogens>>
+	<</if>>
 
-<<if $wraith and $wraith.state isnot "" and _paleChance gte random(1, 10) and !$possessed>>
-	<br><br>
-	You catch a glimpse of a pale figure standing right next to you. You jump back in shock. It slowly turns to you.
-	<br><br>
-	"<span class="wraith">Beautiful. Keep <<if _container.count isnot 1>>them<<else>>it<</if>> safe.</span>" It disappears with a bright flash. <<stress 6>><<gstress>>
-	<<set $wraith.offspring to "alive">>
+	<<if $wraith and $wraith.state isnot "" and (_paleChance gte random(1, 10) or _paleChance gte 1 and !$wraith.offspringWarning) and !$possessed>>
+		<!-- When you have pale parasites, the Ivory Wraith has a chance of appearing and warning you to keep them alive -->
+		<!-- It's guaranteed to appear if you're viewing pale parasites for the first time -->
+		<br><br>
+		You catch a glimpse of a pale figure standing right next to you. You jump back in shock. It slowly turns to you.
+		<br><br>
+		"<span class="wraith">Beautiful. Keep <<if _container.count isnot 1>>them<<else>>it<</if>> safe.</span>" It disappears with a bright flash. <<stress 6>><<gstress>>
+		<<set $wraith.offspring to "alive">>
+		<<if !$wraith.offspringWarning>>
+			<br>
+			You try to imagine what would happen if you let the pale creature die. <span class="purple">A spike of dread shoots through you.</span>
+			<<set $wraith.offspringWarning to true>>
+		<</if>>
+	<</if>>
 <</if>>
 
 <</widget>>
 
+<<widget "creatureTooltip">>
+	<<if _creatureTip[_i].length gte 1 and _pregnancy.book is 3 and $statdisable is "f">>
+		<mouse class="tooltip"><<print _container.creatures[_i].creature>><span class="gold"><<print _creatureTip[_i].join("<br>")>></span></mouse>
+	<<else>>
+		<<print _container.creatures[_i].creature>>
+	<</if>>
+<</widget>>
+
+<<widget "luxuryTooltip">>
+	<span class="gold">
+	<<if $phase is "farm" and $farm.parasitebarn gte 2>>
+		<<if _luxuryTip.length gte 1 and _pregnancy.book is 3 and $statdisable is "f">>
+			<mouse class="tooltip">as advanced as can be<span><<print _luxuryTip.join("<br>")>></span></mouse>
+		<<else>>
+			as advanced as can be
+		<</if>>
+	<<else>>
+		<<if _luxuryTip.length gte 1 and _pregnancy.book is 3 and $statdisable is "f">>
+			<mouse class="tooltip"><<print _container.decorations.toLowerCase()>><span><<print _luxuryTip.join("<br>")>></span></mouse>
+		<<else>>
+			<<print _container.decorations.toLowerCase()>>
+		<</if>>
+	<</if>>
+	</span>
+<</widget>>
+
+<<widget "containersLink">>
+	<!-- Printing the initial link to the containers -->
+	<<if $location is "alex_farm">>
+		<<set $phase to "farm">>
+	<<else>>
+		<<set $phase to $location>>
+	<</if>>
+	<<if _args[0] is "ind">>
+		<<ind>>
+	<</if>>
+	<<set $container.lastLocation to $location>>
+
+	<<if $nextPassageCheck is "Containers">>
+		<span class="nextLink"><<link [["Check the " + $container[$phase].name.toLowerCase() + " (0:05)"|Containers]]>><<pass 5>><</link>></span>
+	<<elseif $container[$phase].kylarFed is true>>
+		<<link [["Check the " + $container[$phase].name.toLowerCase() + " (0:05)"|Kylar Parasites Feed]]>><<pass 5>><</link>>
+	<<else>>
+		<<link [["Check the " + $container[$phase].name.toLowerCase() + " (0:05)"|Containers]]>><<pass 5>><</link>>
+	<</if>>
+	<br>
+<</widget>>
+
+<<widget "containerInfo">>
+	<<link "Close notebook">><<replace "#info">><<link "Open notebook">><<replace "#info">><<containerInfo>><</replace>><</link>><</replace>><</link>>
+	<br>
+	<<set _locCount to 0>>
+	<<for _locs range $container.list>>
+		<<if $container[_locs].count gte 1>>
+			<<set _locCount++>>
+		<</if>>
+	<</for>>
+	<<if _locCount gte 2>>
+		Checking on your parasites will impact your stats once per day, per location.
+	<<else>>
+		Checking on your parasites will impact your stats once per day.
+	<</if>>
+	<<if $location is "alex_farm">>
+		The quality of the parasite barn, as well as the activity of the parasites present,
+	<<elseif $location is "home">>
+		The quality of the decorations you have, as well as the activity of the parasites present,
+	<<else>>
+		The activity of the parasites present
+	<</if>>
+	determines how much stress and trauma is reduced when checking on your parasites. Activity goes from <span class="red">very rare</span> to <span class="gold">perfect</span>.
+	<br><br>
+	<<if _pregnancy.typesSeen.includes("Slime")>>
+		<li><b>Slimes</b> of any kind raise purity by a small amount when checking on them.</li>
+	<</if>>
+	<<if _pregnancy.typesSeen.includes("Worm")>>
+		<li><b>Worms</b> lower purity by a small amount when checking on them.</li>
+	<</if>>
+	<<if _pregnancy.typesSeen.includes("Tentacle")>>
+		<li><b>Tentacles</b> of any kind lower fatigue when checking on them. They can also raise or lower purity, depending on what other parasites are present.
+		<<if _boosts and _boosts.purity gt 0>>
+			Currently, they're raising purity.
+		<<elseif _boosts and _boosts.purity lt 0>>
+			Currently, they're lowering purity.
+		<<else>>
+			Currently, they're doing neither.
+		<</if>>
+		They are more likely to have better activity than other parasites.</li>
+		<<if _pregnancy.typesSeen.includes("Vine")>>
+			<li><b>Vines</b> have the same effect as tentacles.</li>
+		<</if>>
+	<<elseif _pregnancy.typesSeen.includes("Vine")>>
+		<li><b>Vines</b> lower fatigue when checking on them. They can also raise or lower purity, depending on what other parasites are present.
+		<<if _boosts and _boosts.purity gt 0>>
+			Currently, they're raising purity.
+		<<elseif _boosts and _boosts.purity lt 0>>
+			Currently, they're lowering purity.
+		<<else>>
+			Currently, they're doing neither.
+		<</if>>
+		They are more likely to have better activity than other parasites.</li>
+	<</if>>
+	<<if _pregnancy.typesSeen.includes("Lurker")>>
+		<li><b>Lurkers</b> are more likely to have better activity, but take longer to birth and sell for less. They do not have any other notable traits.</li>
+	<</if>>
+	<!-- Printing info for all remaining types seen, that don't have any special traits -->
+	<<set $_typesRemainder to clone(_pregnancy.typesSeen).filter(types => !["Lurker","Vine","Tentacle","Slime","Worm"].includes(types))>>
+	<<if $_typesRemainder.length gte 1>>
+		<<for _r to 0; _r lt $_typesRemainder.length; _r++>>
+			<<set $_typesRemainder[_r] to "<b>" + $_typesRemainder[_r]>>
+			<<if $_typesRemainder[_r].endsWith("s") or $_typesRemainder[_r].endsWith("sh")>>
+				<!-- Avoiding "Fishs". Most parasites have the s stripped off the end anyway, but best to be sure -->
+				<<set $_typesRemainder[_r] += "</b>">>
+			<<else>>
+				<<set $_typesRemainder[_r] += "s</b>">>
+			<</if>>
+		<</for>>
+		<li><<print formatList($_typesRemainder)>> do not have any notable traits.</li>
+	<</if>>
+	<!-- Pale parasites are down here because they're variants. It looks kinda awkward because there are very few parasite variants -->
+	<<if _pregnancy.variantsSeen.includes("Pale")>>
+		<li><b><span class="wraith">Pale</span></b> parasites have larger bonuses than other parasites, and also afflict you with hallucinogens.</li>
+	<</if>>
+	<!-- Printing info for all remaining variants seen, that don't have any special traits -->
+	<<set $_variantsRemainder to clone(_pregnancy.variantsSeen).filter(types => !["Pale"].includes(types))>>
+	<<if $_variantsRemainder.length gte 1>>
+		<<for _r to 0; _r lt $_variantsRemainder.length; _r++>>
+			<<set $_variantsRemainder[_r] to "<b>" + $_variantsRemainder[_r] + "</b>">>
+		<</for>>
+		<li><<print formatList($_variantsRemainder)>> parasites do not have any notable differences compared to ordinary parasites.</li>
+	<</if>>
+<</widget>>
+
 :: Containers
 <<set $outside to 0>><<set $location to $container.lastLocation>><<effects>>
-<<set _container to $container[$location]>>
+<<set _container to $container[$phase]>>
 <<set _pregnancy to $sexStats.anus.pregnancy>>
 <<set $checkboxResult to {}>>
 
 <<if _container.count is 0>>
 	<<if _container.deadCreatures is 0>>
-		You currently have no <<if _pregnancy.namesChildren is true>>children<<else>>parasites<</if>> inside the <<print _container.name>>.
+		You currently have no <<if _pregnancy.namesChildren is true>>children<<else>>parasites<</if>> inside the <span class="gold"><<print _container.name.toLowerCase()>></span>.
 		<br>
 	<<else>>
-		After not checking and feeding <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, it looks like some have died. You take your time in burying them.
+		After not checking and feeding <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, it looks like <span class="red">some have died</span>. You take your time in burying them.
 		<<ggtrauma>>
 		<br><br>
 		<<if _pregnancy.namesChildren is true>>
@@ -189,14 +379,28 @@
 	<</if>>
 <<else>>
 	<<if _container.visited is false>>
-		You check on <<if _pregnancy.namesChildren is true>>your child<<if _container.count isnot 1>>ren<</if>><<else>>the parasite<<if _container.count isnot 1>>s<</if>><</if>>, and make sure <<if _container.count isnot 1>>they have<<else>>it has<</if>> everything <<if _container.count isnot 1>>they need<<else>>it needs<</if>> inside your <<print _container.name>>.
+		You check on <<if _pregnancy.namesChildren is true>>your child<<if _container.count isnot 1>>ren<</if>><<else>>the parasite<<if _container.count isnot 1>>s<</if>><</if>>, and make sure <<if _container.count isnot 1>>they have<<else>>it has<</if>> everything <<if _container.count isnot 1>>they need<<else>>it needs<</if>> inside the <span class="gold"><<print _container.name.toLowerCase()>></span>.
 		<br>
 		<<creatureVisit>>
 	<<else>>
-		You watch your <<if _pregnancy.namesChildren is true>>child<<if _container.count isnot 1>>ren<</if>><<else>>parasite<<if _container.count isnot 1>>s<</if>><</if>> inside your <<print _container.name>>.
+		<<creatureVisit false>>
+		You watch your <<if _pregnancy.namesChildren is true>>child<<if _container.count isnot 1>>ren<</if>><<else>>parasite<<if _container.count isnot 1>>s<</if>><</if>> inside the <span class="gold"><<print _container.name.toLowerCase()>></span>.
 	<</if>>
 	<br><br>
-	It has a max capacity of <<number _container.maxCount>> and <<if _pregnancy.namesChildren is true>>your child<<if _container.count isnot 1>>ren<</if>><<else>>the parasite<<if _container.count isnot 1>>s<</if>><</if>> can survive <<number _container.maxDaysWithoutFood>> days without your attention<<if _container.feederName>>, thanks to your <<print _container.feederName>><</if>>. <<if _container.decorations>>You have <<print _container.decorations>> setup within the tank.<</if>>
+	It has a max capacity of <<number _container.maxCount>> and <<if _pregnancy.namesChildren is true>>your child<<if _container.count isnot 1>>ren<</if>><<else>>the parasite<<if _container.count isnot 1>>s<</if>><</if>> can survive <<number _container.maxDaysWithoutFood>> days without your attention<<if _container.feederName>>, thanks to your <span class="gold"><<print _container.feederName.toLowerCase()>></span><</if>>.
+	<<if _container.decorations>>You have <<luxuryTooltip>> set up within the tank.<</if>>
+	<<if $phase is "farm" and $farm.parasitebarn gte 2>>The equipment set up is <<luxuryTooltip>> in the barn.<</if>>
+	<!-- For players who had multiple parasite children before the tooltip update -->
+	<<if _pregnancy.typesSeen.length gte 4 and _pregnancy.book is undefined or _pregnancy.book is 1>>
+		<<set _pregnancy.book to 1>>
+		<br><br>
+		You find yourself wondering at the sheer number of different types of creatures you have, and wonder if there's any way to know more. <span class="gold">Doctor Harper might be able to help you.</span>
+	<</if>>
+<</if>>
+<br><br>
+
+<<if _pregnancy.book is 3>>
+	<div id="info" class="no-numberify"><<link "Open notebook">></span><<replace "#info">><<containerInfo>><</replace>><</link>></div>
 <</if>>
 
 <<if _container.count gt 0>>
@@ -206,7 +410,7 @@
 				<<continue>>
 			<</if>>
 			<<if _container.creatures[_i] isnot null>>
-				<li><label><<print '<<checkbox "$checkboxResult[' + clone(_i) + ']" false true>>'>> - <<print _container.creatures[_i].creature>> - <<print _container.creatures[_i].stats.gender>> - <<creatureActivity _container.creatures[_i].stats.speed>></label></li>
+				<li><label><<print '<<checkbox "$checkboxResult[' + clone(_i) + ']" false true>>'>> - <<creatureTooltip>> - <<print _container.creatures[_i].stats.gender>> - <<creatureActivity _container.creatures[_i].stats.speed>></label></li>
 			<</if>>
 		<</for>>
 	</ul>
@@ -216,23 +420,19 @@
 	<<if _pregnancy.feltMovement is true>>
 		<<if $worn.genitals.anal_shield is 1>>
 			You're unable to deliver <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>> while you have an anal shield.
-			<br><br>
 		<<else>>
 			<<if _pregnancy.namesChildren is true>>
 				<<link [[Attempt to deliver your baby (1:00)|GiveBirth]]>><<pass 60>><</link>>
-				<br>
 			<<else>>
 				<<link [[Attempt to deliver the parasite (1:00)|GiveBirth]]>><<pass 60>><</link>>
-				<br>
 			<</if>>
 		<</if>>
 	<<elseif _pregnancy.count - (_pregnancy.motherStatus is 2 ? 1 : 0) gt 0>>
 		You don't think <<print (_pregnancy.namesChildren is true ? "your children" : "the parasites")>> are ready for delivery.
-		<br><br>
 	<</if>>
-	<br>
+	<br><br>
 	<<if _container.count gt 0>>
-		<<link [[Transfer for selling|$passage]]>>
+		<<link [[Transfer selected for selling|$passage]]>>
 			<<for _i to 0; _i lt _container.maxCount;_i++>>
 				<<if _container.creatures[_i] is undefined>>
 					<<continue>>
@@ -240,12 +440,12 @@
 				<<if _container[_i] isnot null>>
 					<<if $checkboxResult[_i] is true>>
 						<<set $number to clone(_i)>>
-						<<moveCreature $location "portable" _i>>
+						<<moveCreature $phase "portable" _i>>
 					<</if>>
 				<</if>>
 			<</for>>
 		<</link>>
 		<br>
 	<</if>>
-	<<link [[Leave|$container[$location].leaveLink]]>><</link>>
+	<<link [[Leave|_container.leaveLink]]>><</link>>
 <</if>>
diff --git a/game/base-system/pregnancy/events.twee b/game/base-system/pregnancy/events.twee
index 7a7d68f1be..0ae98bb7cb 100644
--- a/game/base-system/pregnancy/events.twee
+++ b/game/base-system/pregnancy/events.twee
@@ -49,6 +49,10 @@ You shake your head. <<He>> holds open the door for you, and you leave the offic
 	<<link [[Inquire about anal futa removal (0:30)|Remove Futa Pregnancy]]>><<pass 30>><<set $futaCheck to true>><<set $firstOption to false>><</link>>
 	<br>
 <</if>>
+<<if $sexStats.anus.pregnancy.typesSeen.length gte 4 and $sexStats.anus.pregnancy.book is 1>>
+	<<link [[Inquire about information on parasites (0:05)|Harper Parasite Book]]>><<pass 5>><<set $firstOption to false>><</link>>
+	<br>
+<</if>>
 
 <<link [[Return to foyer|Hospital Foyer]]>><<endevent>><<unset $firstOption>><</link>>
 
@@ -140,7 +144,7 @@ Harper stares unblinking at your <<bottom>> as the pulsing increases in intensit
 <br><br>
 
 "All done," <<he>> says as <<he>> unties the straps. <<He>> turns away as you dress.
-<br><br><br><br>
+<br><br>
 <<link [[Next|Pregnancy Discussion]]>><<unset $futaCheck>><</link>>
 
 :: GiveBirth
@@ -148,13 +152,14 @@ Harper stares unblinking at your <<bottom>> as the pulsing increases in intensit
 <<set $outside to 0>><<set $location to $container.lastLocation>><<effects>>
 <<set _pregnancy to $sexStats.anus.pregnancy>>
 <<set _pregnancy.feltMovement to false>>
-<<set _container to $container[$location]>>
+<<set _container to $container[$phase]>>
 <<set $pregResult to "notReady">>
 <<set _stressMulti to 2 - _pregnancy.motherStatus>>
 <<set $checkboxResult to {}>>
 <<set $checkboxReplace to {}>>
 <<set $parasiteSelectionCount to 0>>
-<<set _vine to 0>><<set _metal to 0>><<set _pale to 0>>
+<<set _newlyBirthed to {}>>
+<<set _allSeen to _pregnancy.typesSeen.length + _pregnancy.variantsSeen.length>>
 
 Following the directions from Doctor Harper, you get into position and attempt to deliver <<if _pregnancy.namesChildren is true>>your baby<<else>>the parasites<</if>>. <<if _stressMulti gt 0>><<gstress>><</if>><<set $stress += 250 * _stressMulti>>
 <br><br>
@@ -165,7 +170,7 @@ Following the directions from Doctor Harper, you get into position and attempt t
 	<</if>>
 	<<if _pregnancy[_i].stats.gender isnot "Futa">>
 		<<set _rand to random(0,100)>>
-		<<if (_rand lte 80 and _pregnancy[_i].daysLeft is 0) or (_rand lte 50 and _pregnancy[_i].daysLeft lte 1) or (_rand lte 30 and _pregnancy[_i].daysLeft lte 2) or (_rand lte 10 and _pregnancy[_i].daysLeft lte 3)>>
+		<<if (_rand lte 80 and _pregnancy[_i].daysLeft is 0) or (_rand lte 50 and _pregnancy[_i].daysLeft lte 1) or (_rand lte 30 and _pregnancy[_i].daysLeft lte 2) or (_rand lte 10 and _pregnancy[_i].daysLeft lte 3) or $parasiteBirthDebug>>
 			<<if $pregResult is "notReady">>
 				<<set $pregResult to [clone(_i)]>>
 			<<else>>
@@ -185,32 +190,56 @@ Following the directions from Doctor Harper, you get into position and attempt t
 
 	<ul>
 		<<for _i to 0; _i lt $pregResult.length; _i++>>
-			<li><label><<print '<<checkbox "$checkboxResult[' + clone($pregResult[_i]) + ']" false true checked>>'>> - <<print _pregnancy[$pregResult[_i]].creature>> - <<creatureActivity _pregnancy[$pregResult[_i]].stats.speed>></label></li>
-			<<if _pregnancy[$pregResult[_i]].creature is "Vine">>
-				<<set _vine++>>
-			<</if>>
-			<<if _pregnancy[$pregResult[_i]].creature.includes("Metal")>>
-				<<set _metal++>>
-			<</if>>
-			<<if _pregnancy[$pregResult[_i]].creature.includes("Pale")>>
-				<<set _pale++>>
+			<<set _result to _pregnancy[$pregResult[_i]]>>
+			<!-- Printing the checkbox -->
+			<li><label><<print '<<checkbox "$checkboxResult[' + clone($pregResult[_i]) + ']" false true checked>>'>> - <<print _result.creature>> - <<creatureActivity _result.stats.speed>></label></li>
+			<<if _result.creature.includes(" ")>>
+				<!-- If the creature has a variant, like Pale. Currently does not account for creatures with more than one variant, because those don't yet exist -->
+				<!-- Possible task for the future: turn parasite variants into variables, so there can be multiple -->
+				<<set _split to _result.creature.split(" ")>>
+				<<if !_pregnancy.variantsSeen.includes(_split[0]) and _split[0] isnot _split[1]>>
+					<<set _pregnancy.variantsSeen.pushUnique(_split[0])>>
+					<!-- For Pale Tentacle, this will set _newlyBirthed.Pale to "tentacle" -->
+					<<set _newlyBirthed[_split[0]] to _split[1].toLowerCase()>>
+				<</if>>
+				<<if !_pregnancy.typesSeen.includes(_split[1])>>
+					<<set _pregnancy.typesSeen.pushUnique(_split[1])>>
+					<<set _newlyBirthed[_split[1]] to true>>
+				<</if>>
+			<<else>>
+				<!-- Creatures without variants -->
+				<<if !_pregnancy.typesSeen.includes(_result.creature)>>
+					<<set _pregnancy.typesSeen.pushUnique(_result.creature)>>
+					<<set _newlyBirthed[_result.creature] to true>>
+				<</if>>
 			<</if>>
 		<</for>>
 	</ul>
-	<<if _vine gte 1 and !$containerVine and $location is "home">>
-		<<set $containerVine to true>>
-		You worry that the vine<<if _vine gte 2>>s<</if>> won't be able to survive without being planted in a better environment, but <<if _vine is 1>>it seems<<else>>they seem<</if>> to be fine in your <<print $container[$location].name>>, writhing around. You suspect <<if _vine is 1>>it's<<else>>they're<</if>> not strictly plant life.
+	<<for _n to 0; _n lt Object.values(_newlyBirthed).length; _n++>>
+		<<switch Object.keys(_newlyBirthed)[_n]>>
+			<<case "Tentacle">>
+				You watch the tentacle in fascination. It writhes around blindly and coils around itself, almost like a snake. It's so energetic, just looking at it makes you feel less tired.
+			<<case "Slime">>
+				The slime doesn't move for a while. You poke at it, a little worried, and it jiggles. It has an indescribable consistency. It looks almost without flaw, and you feel <<if _pregnancy.namesChildren is true>>proud to have birthed<<else>>almost proud to have hosted<</if>> such a creature.
+			<<case "Worm">>
+				Almost immediately, the worm tries to find somewhere to dig. It has little success, and squirms in agitation until you place it in the <<print _container.name.toLowerCase()>>. You feel odd, having <<if _pregnancy.namesChildren is true>>birthed<<else>>hosted<</if>> such a creature.
+			<<case "Lurker">>
+				The lurker moves mainly by crawling, but sometimes hops surprising distances. You quickly place it in the <<print _container.name.toLowerCase()>> before you can lose it.
+			<<case "Vine">>
+				You worry that the vine won't be able to survive without being planted in a better environment, but it seems to be fine in the <<print _container.name.toLowerCase()>>, writhing around. You suspect it's not strictly plant life.
+			<<case "Metal">>
+				Upon closer inspection, the metal <<print _newlyBirthed.Metal>> isn't truly metal. It has a metallic colour and pattern, but it bends and writhes in ways that steel wouldn't be able to. You hope it doesn't need anything in particular to eat.
+			<<case "Pale">>
+				Your hands seem to move on their own, and you find yourself holding the pale <<print _newlyBirthed.Pale>>. It's so pale that it's almost translucent. You feel a twinge of dread, but it's quickly replaced by an odd contentment.
+				<span class="blue">You should be careful deciding whether to keep it.</span>
+			<<default>>
+				<!-- This way, species like Wasp that don't have a unique line don't print <br>s for no reason -->
+				<<continue>>
+		<</switch>>
 		<br><br>
-	<</if>>
-	<<if _metal gte 1 and !$containerMetal and $location is "home">>
-		<<set $containerMetal to true>>
-		Upon closer inspection, the metal tentacle isn't truly metal. It has a metallic colour and pattern, but it bends and writhes in ways that steel wouldn't be able to. You hope it doesn't need anything in particular to eat.
-		<br><br>
-	<</if>>
-	<<if _pale gte 1 and !$containerPale and $location is "home">>
-		<<set $containerPale to true>>
-		Your hands seem to move on their own, and you find yourself holding the pale creature<<if _pale gte 2>>s<</if>>. <<if _pale gte 2>>They're<<else>>It's<</if>> so pale that <<if _pale gte 2>>they're<<else>>it's<</if>> almost translucent. You feel a twinge of dread, but it's quickly replaced by an odd contentment.
-		<span class="blue">You should be careful deciding whether to keep <<if _pale gte 2>>them<<else>>it<</if>>.</span>
+	<</for>>
+	<<if _pregnancy.book is 3 and _pregnancy.typesSeen.length + _pregnancy.variantsSeen.length gt _allSeen>>
+		You write about <<if _pregnancy.namesChildren is true>>your new children<<else>>the new parasites<</if>> in your notebook.
 		<br><br>
 	<</if>>
 	<<if $pregResult.length gt (_container.maxCount - _container.count)>>
@@ -235,7 +264,7 @@ Following the directions from Doctor Harper, you get into position and attempt t
 <<widget "PregEventsResult">>
 <<set $outside to 0>><<set $location to $container.lastLocation>><<effects>>
 <<set _pregnancy to $sexStats.anus.pregnancy>>
-<<set _container to $container[$location]>>
+<<set _container to $container[$phase]>>
 <<set $parasiteSelectionCount to 0>>
 <<set $parasiteReplaceArray to []>>
 <<set _availableStorage to (_container.maxCount - _container.count)>>
@@ -280,7 +309,7 @@ Following the directions from Doctor Harper, you get into position and attempt t
 <<elseif $parasiteSelectionCount gt 0>>
 	Not enough storage for selected amount. Please replace <<number $parasiteSelectionCount-_availableStorage>> <<if _pregnancy.namesChildren is true>><<print $parasiteSelectionCount - _availableStorage gt 1 ? 'babies' : 'baby'>><<else>><<print $parasiteSelectionCount - _availableStorage gt 1 ? 'parasites' : 'parasite'>><</if>>.
 	<br>
-	<<if ($parasiteSelectionCount - $parasiteReplaceArray.length) is _availableStorage>>
+	<<if ($parasiteSelectionCount - $parasiteReplaceArray.length) lte _availableStorage>>
 		<<if _pregnancy.namesChildren is true>>
 			<<link [[Replace selected babies|PregEventsResult2]]>>
 				<<set $pregChoice to "ReplaceSelected">>
@@ -342,7 +371,7 @@ Following the directions from Doctor Harper, you get into position and attempt t
 			<<moveCreature $pregResult[_i] "portable">>
 		<</if>>
 	<</for>>
-	You decide to keep <<number $parasiteSelectionCount>> of <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>> and so place <<if $parasiteSelectionCount isnot 1>>them<<else>>it<</if>> in your <<print $container[$location].name>> in place of <<number $parasiteReplaceArray.length>> <<if $parasiteReplaceArray.length gt 1>>others<<else>>other<</if>>, while preparing the rest for Doctor Harper.
+	You decide to keep <<number $parasiteSelectionCount>> of <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, and place <<if $parasiteSelectionCount isnot 1>>them<<else>>it<</if>> in your <<print $container[$phase].name.toLowerCase()>> in place of <<number $parasiteReplaceArray.length>> <<if $parasiteReplaceArray.length gt 1>>others<<else>>other<</if>>, while preparing the rest for Doctor Harper.
 	<br><br>
 <<case "KeepSelected">>
 	<<for _i to 0; _i lt $pregResult.length;_i++>>
@@ -352,13 +381,13 @@ Following the directions from Doctor Harper, you get into position and attempt t
 			<<moveCreature $pregResult[_i] "portable">>
 		<</if>>
 	<</for>>
-	You decide to keep <<number $parasiteSelectionCount>> of <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, and place <<if $parasiteSelectionCount isnot 1>>them<<else>>it<</if>> in your <<print $container[$location].name>> while preparing the rest for Doctor Harper.
+	You decide to keep <<number $parasiteSelectionCount>> of <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, and place <<if $parasiteSelectionCount isnot 1>>them<<else>>it<</if>> in your <<print $container[$phase].name.toLowerCase()>> while preparing the rest for Doctor Harper.
 	<br><br>
 <<case "keepAll">>
 	<<for _i to 0; _i lt $pregResult.length;_i++>>
 		<<moveCreature $pregResult[_i] "container">>
 	<</for>>
-	You decide to keep all of <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, and place them in your <<print $container[$location].name>>.
+	You decide to keep all of <<if _pregnancy.namesChildren is true>>your children<<else>>the parasites<</if>>, and place them in your <<print $container[$phase].name.toLowerCase()>>.
 	<br><br>
 <<case "sellAll">>
 	<<for _i to 0; _i lt $pregResult.length;_i++>>
@@ -374,6 +403,17 @@ Following the directions from Doctor Harper, you get into position and attempt t
 	<<unset $parasiteSelectionCount>><<unset $parasiteReplaceArray>>
 <</link>>
 
+:: Harper Parasite Book
+<<effects>>
+<<set $sexStats.anus.pregnancy.book to 2>>
+Harper nods approvingly. "It's good that you want to know more." <<He>> brings out a rather thick book and shows it to you. "This is a popular reference guide among scientists. It has a lot of information on this subject, but it's property of the hospital. I'm not authorized to lend it out."
+<br><br>
+
+<<He>> thinks for a few seconds. "<span class="gold">The pet shop on High Street may have something.</span> If nothing else, you could pick up a notebook and fill out info you gather yourself."
+<br><br>
+
+<<link [[Next|Pregnancy Discussion]]>><</link>>
+
 
 :: Pregnancy Birth Hospital Passout
 <<set $outside to 0>><<effects>>
diff --git a/game/base-system/pregnancy/pregnancy.twee b/game/base-system/pregnancy/pregnancy.twee
index 5e9d075b5d..c3881bf629 100644
--- a/game/base-system/pregnancy/pregnancy.twee
+++ b/game/base-system/pregnancy/pregnancy.twee
@@ -5,8 +5,10 @@
 	<<if _pregnancy.count lt _pregnancy.maxCount>>
 		<<set $calc to [random(0,100), (1 + _args[1]) / (_pregnancy.count + 1)]>>
 		<<if $calc[0] lte $calc[1] or _args[2]>>
+			<!-- chances of impregnation. Guaranteed with parasites based on futa -->
 			<<for _i to 0; _i lt _pregnancy.maxCount; _i++>>
 				<<if _pregnancy[_i] is null>>
+					<!-- Encorce non-plural names -->
 					<<switch _args[0]>>
 						<<case "slimes" "eels" "worms" "snakes" "spiders" "slugs" "maggots">>
 							<<set _creatureType to toTitleCase(_args[0])>>
@@ -14,7 +16,14 @@
 						<<default>>
 							<<set _creatureType to toTitleCase(_args[0])>>
 					<</switch>>
+					<!-- creature: the type of creature it is. "Lurker", "Slime", "Pale Tentacle", etc -->
+					<!-- fertilised: whether it's fertilised or not. Parasites need to be fertilised before they can be birthed -->
+					<!-- daysLeft: how long until it can be birthed. Birthing is possible when it's 3 or less, but significantly more likely at 0 -->
+					<!-- timeLeft: how long until it prompts a daily event. Speed impacts how fast it goes down -->
+					<!-- stats.growth: how long it takes to birth, and how much the parasite is worth when selling-->
+					<!-- stats.speed: how often it prompts a daily event. Also determines the parasite's activity -->
 					<<if _args[2]>>
+						<!-- Futa-birthed parasites -->
 						<<set _egg to {
 							"creature": _args[0],
 							"fertilised": true,
@@ -26,6 +35,7 @@
 							}
 						}>>
 					<<else>>
+						<!-- Non-futa parasites -->
 						<<set _egg to {
 							"creature": _creatureType,
 							"fertilised": false,
@@ -36,17 +46,20 @@
 								"speed": random(60,360)
 							}
 						}>>
-						<<if _creatureType is "Tentacle" or _creatureType is "Vine">>
+						<<if _creatureType.includes("Pale")>>
+							<!-- Pale parasites have significantly better activity -->
+							<<set _egg.stats.speed to clone(_egg.stats.speed * 0.6)>>
+						<<elseif _creatureType.includes("Tentacle") or _creatureType is "Vine">>
+							<!-- Tentacles and vines have better activity. Done in an elseif so pale tentacles don't get the calculation twice -->
 							<<set _egg.stats.speed to clone(_egg.stats.speed * 0.9)>>
 						<</if>>
 						<<if _creatureType is "Vine" and random(0,100) gt 99>>
+							<!-- Vine Vine easter egg lol -->
 							<<set _egg.creature += " Vine">>
 							<<set _egg.stats.growth-->>
 						<</if>>
-						<<if _creatureType is "Pale Tentacle" or _creatureType is "Pale Slime">>
-							<<set _egg.stats.speed to clone(_egg.stats.speed * 0.6)>>
-						<</if>>
 						<<if _creatureType is "Lurker">>
+							<!-- Lurkers have better activity, but sell for less and take longer to birth -->
 							<<run _egg.stats.growth += 14>>
 							<<for _l to 0; _l lt 3; _l++>>
 								<<if _egg.stats.speed gte 100>>
@@ -58,19 +71,22 @@
 
 					<<set _genderCheck to Math.random()>>
 					<<if _genderCheck lt 0.7>>
+						<!-- Female parasites are most likely -->
 						<<set _egg.stats.gender to "Female">>
 					<<elseif _genderCheck lt 0.8 or _pregnancy.motherStatus is 0 or _pregnancy.motherStatus is 2>>
+						<!-- You can only get a futa if motherStatus is 1, aka if you're ready for a futa and don't currently have one -->
 						<<set _egg.stats.gender to "Male">>
 					<<else>>
 						<<set _egg.stats.gender to "Futa">>
 						<<set _egg.stats.lastEgg to Math.floor(_egg.stats.growth / 3)>>
-
 					<</if>>
 
+					<!-- adding the new parasite to $sexStats.anus.pregnancy -->
 					<<set _pregnancy[_i] to clone(_egg)>>
 					<<set _pregnancy.count++>>
 
 					<<if _args[2] is undefined>>
+						<!-- Parasites require fertilisation, aka an anal creampie, before they can be birthed. Tentacles, lurkers and futa-born parasites are automatically fertilised -->
 						<<set _pregnancy.fertile to true>>
 						<<set _impreg to true>>
 					<</if>>
@@ -83,6 +99,7 @@
 <</widget>>
 
 <<widget "fertilise">>
+<!-- Runs whenever someone ejaculates in your anus -->
 <<if $sexStats.anus.pregnancy.fertile is true and $analpregdisable is "f">>
 	<<set _pregnancy to $sexStats.anus.pregnancy>>
 	<<for _i to 0; _i lt _pregnancy.maxCount; _i++>>
@@ -117,6 +134,7 @@
 	<<for _i to 0; _i lt _pregnancy.maxCount; _i++>>
 		<<if _pregnancy[_i] isnot null>>
 			<<if _pregnancy[_i].daysLeft is 0 and _pregnancy[_i].fertilised is false>>
+				<!-- Unfertilised parasites get removed -->
 				<<set _remove to true>>
 			<<else>>
 				<<if _pregnancy[_i].daysLeft gt 0>>
@@ -127,6 +145,7 @@
 				<</if>>
 			<</if>>
 			<<if _pregnancy[_i].stats.gender is "Futa" and _pregnancy[_i].daysLeft lte 3>>
+				<!-- Futas only "activate" a few days after initial impregnation -->
 				<<if _pregnancy[_i].stats.lastEgg gt 0>>
 					<<set _pregnancy[_i].stats.lastEgg -= 1>>
 				<<elseif _pregnancy.count lt _pregnancy.maxCount>>
@@ -135,6 +154,7 @@
 				<</if>>
 			<</if>>
 			<<if _remove is true>>
+				<!-- Remmeber when I said unfertilised parasites get removed? This is where it happens -->
 				<<set _pregnancy[_i] to null>>
 				<<set _pregnancy.count -= 1>>
 			<</if>>
@@ -150,16 +170,22 @@
 	<<for _i to 0; _i lt _pregnancy.maxCount; _i++>>
 		<<if _pregnancy[_i] isnot null>>
 			<<if _pregnancy[_i].fertilised is true>>
+				<!-- Setting up the daily messages to pop at the top of the screen -->
 				<<if _pregnancy[_i].timeLeft is null>>
 					<<set _pregnancy[_i].timeLeft to _pregnancy[_i].stats.speed>>
 				<<else>>
 					<<set _pregnancy[_i].timeLeft -= _args[0]>>
 				<</if>>
 				<<if _pregnancy[_i].timeLeft lte 0>>
+					<!-- The lower the parasite's speed, the more often it will affect daily events -->
 					<<set _pregnancy[_i].timeLeft to _pregnancy[_i].stats.speed>>
 					<<if $dailyEvent is undefined>>
 						<<set $dailyEvent to []>>
 					<</if>>
+					<!-- dailyEvent0: You feel something large/your grown parasite move in your stomach. -->
+					<!-- dailyEvent1: You feel something/one of your parasites move in your stomach. -->
+					<!-- dailyEvent2: Your stomach rumbles a little. You hope the noise hasn't attracted any attention. -->
+					<!-- dailyEvent3: You feel a little lightheaded for a moment. -->
 					<<if $dailyEvent.length lt _pregnancy.count>>
 						<<if _pregnancy[_i].stats.gender is "Futa" and _pregnancy[_i].daysLeft lte 3>>
 							<<if (_pregnancy[_i].daysLeft lt 3 and $rng lt 20) or (_pregnancy[_i].daysLeft is 0 and $rng lt 50)>>
@@ -193,14 +219,17 @@
 /*2 -> locationId*/
 <<if _args[0] isnot null and _args[1]>>
 	<<set _portable to $container.portable>>
-	<<set _container to $container[$location]>>
+	<<set _container to $container[$phase]>>
 	<<set _pregnancy to $sexStats.anus.pregnancy>>
 
 	<<set _result to _args[1]>>
 	<<switch _args[0]>>
 		<<case 0 1 2 3>>
+			<!-- With a number as argument 0, it takes the parasite of that argument in your current pregnancy item -->
 			<<set _creature to clone(_pregnancy[_args[0]])>>
 		<<default>>
+			<!-- With a string as argument 0, it takes a parasite from the container matching the argument. Which parasite it takes corresponds to argument 2 -->
+			<!-- Currently only used when transferring parasites for selling in :: Containers, inside a for loop -->
 			<<if _args[2] isnot null>>
 				<<set _creature to clone($container[_args[0]].creatures[_args[2]])>>
 			<</if>>
@@ -208,14 +237,18 @@
 
 	<<if _creature>>
 		<<if _result is "destroy">>
+			<!-- Simply gets rid of the parasite -->
 			<<set _creature to null>>
 			<<removeCreature _args[0] _args[2]>>
 		<<elseif _result is "portable">>
+			<!-- Transfers the parasites for selling. The value of the parasite depends on its growth stat -->
 			<<set _portable.creatures.push(clone(_creature))>>
 			<<set _value to Math.floor(1000 / _creature.stats.growth)>>
 			<<set _portable.value += _value>>
 			<<removeCreature _args[0] _args[2]>>
 		<<elseif _result is "replace" and _args[2] isnot null and _args[0] gte 0 and _args[0] lte 3>>
+			<!-- Replaces an existing parasite, for when you birth more than you can currently store -->
+			<!-- The replaced parasite gets transferred for selling -->
 			<<if _container.creatures[_i] isnot undefined>>
 				<<if _container.creatures[_i] isnot null>>
 					<<set _portable.creatures.push(clone(_container.creatures[_args[2]]))>>
@@ -231,6 +264,7 @@
 			<</if>>
 			<<removeCreature _args[0]>>
 		<<elseif _result is "container">>
+			<!-- Keeps the parasite and moves it to the current container -->
 			<<set _moveTo to false>>
 			<<for _containerSlot to 0; _containerSlot lt _container.maxCount; _containerSlot++>>
 				<<if _container.creatures[_containerSlot] is undefined>>
@@ -239,8 +273,8 @@
 					<<set _moveTo to true>>
 				<</if>>
 				<<if _moveTo is true>>
-					<<set $container[$location].creatures[_containerSlot] to clone(_creature)>>
-					<<set $container[$location].count += 1>>
+					<<set $container[$phase].creatures[_containerSlot] to clone(_creature)>>
+					<<set $container[$phase].count += 1>>
 					<<removeCreature _args[0] _args[2]>>
 					<<break>>
 				<</if>>
@@ -255,6 +289,7 @@
 		<<set _pregnancy to $sexStats.anus.pregnancy>>
 		<<switch _args[0]>>
 			<<case 0 1 2 3>>
+				<!-- With a number as argument 0, it removes the parasite of that argument in your current pregnancy item -->
 				<<set _pregnancy[_args[0]] to null>>
 				<<set _pregnancy.count -= 1>>
 				<<set _pregnancy.givenBirth += 1>>
@@ -263,6 +298,7 @@
 					<<set _pregnancy.maxCount to 2>>
 				<</if>>
 			<<default>>
+				<!-- With a string as argument 0, it removes a parasite from the container matching the argument. Which parasite it takes corresponds to argument 1 -->
 				<<if _args[1] isnot null>>
 					<<set $container[_args[0]].creatures[_args[1]] to null>>
 					<<set $container[_args[0]].count -= 1>>
diff --git a/game/overworld-forest/loc-lake/main.twee b/game/overworld-forest/loc-lake/main.twee
index e142cfaebe..3ec6944989 100644
--- a/game/overworld-forest/loc-lake/main.twee
+++ b/game/overworld-forest/loc-lake/main.twee
@@ -187,13 +187,7 @@ There's a rocky alcove where you could store your clothes.
 	<<eventlakesafe>>
 	<<lakereturnjourney>>
 	<<if $sexStats.anus.pregnancy.seenDoctor gte 2>>
-		<<set $container.lastLocation to $location>>
-		<<if $nextPassageCheck is "Containers">>
-			<<print '<span class="nextLink"><<link [[Check ' + $container[$location].name + ' (0:05)|Containers]]>><<pass 5>><</link>></span>'>>
-		<<else>>
-			<<print '<<link [[Check ' + $container[$location].name + ' (0:05)|Containers]]>><<pass 5>><</link>>'>>
-		<</if>>
-		<br>
+		<<containersLink>>
 	<</if>>
 	<<if $mason_count gte 2 and $season isnot "winter">>
 		<<link [[Mason's pond (0:05)|Mason Pond]]>><<pass 5>><</link>>
diff --git a/game/overworld-plains/loc-farm/upgrades.twee b/game/overworld-plains/loc-farm/upgrades.twee
index ea63879c80..5ddd1021b6 100644
--- a/game/overworld-plains/loc-farm/upgrades.twee
+++ b/game/overworld-plains/loc-farm/upgrades.twee
@@ -569,7 +569,7 @@ An even bigger coop means even more chickens.
 A new barn to store your parasites.
 <br><br>
 
-<span class="green">Parasite Storage.</span>
+<span class="green">Parasite storage.</span>
 <br>
 <span class="gold">Costs £5000.</span>
 <br>
@@ -593,7 +593,7 @@ A new barn to store your parasites.
 A new barn to store your parasites.
 <br><br>
 
-<span class="green">Upgrades the Parasite barn, providing a little extra space and allowing them to survive on their own for longer.</span>
+<span class="green">Upgrades the parasite barn, providing a little extra space and allowing them to survive on their own for longer.</span>
 <br>
 <span class="gold">Costs £20000.</span>
 <br>
diff --git a/game/overworld-plains/loc-farm/work.twee b/game/overworld-plains/loc-farm/work.twee
index 6bea274a53..5d00ab7c09 100644
--- a/game/overworld-plains/loc-farm/work.twee
+++ b/game/overworld-plains/loc-farm/work.twee
@@ -648,9 +648,7 @@ You are on Alex's farm. A rustic farmhouse overlooks a yard and chicken coop. Ot
 			<br>
 		<</if>>
 		<<if $farm.parasitebarn gte 1>>
-			<<set $container.lastLocation to "farm">>
-			<<print '<<link [[Check ' + $container["farm"].name + ' (0:05)|Containers]]>><<pass 5>><</link>>'>>
-			<br>
+			<<containersLink>>
 		<</if>>
 		<br>
 
diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index 952a07eb22..7923707e82 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -252,15 +252,7 @@ You are in your bedroom.
 	<</if>>
 
 	<<if $sexStats.anus.pregnancy.seenDoctor gte 2>>
-		<<set $container.lastLocation to $location>>
-		<<if $nextPassageCheck is "Containers">>
-			<span class="nextLink"><<ind>><<print '<<link [[Check ' + $container[$location].name + ' (0:05)|Containers]]>><<pass 5>><</link>>'>></span>
-		<<elseif $container[$location].kylarFed is true>>
-			<<ind>><<print '<<link [[Check ' + $container[$location].name + ' (0:05)|Kylar Parasites Feed]]>><<pass 5>><</link>>'>>
-		<<else>>
-			<<ind>><<print '<<link [[Check ' + $container[$location].name + ' (0:05)|Containers]]>><<pass 5>><</link>>'>>
-		<</if>>
-		<br>
+		<<containersLink "ind">>
 	<</if>>
 	<br>
 	The hallway outside connects to the rest of the orphanage.
diff --git a/game/overworld-town/loc-hospital/main.twee b/game/overworld-town/loc-hospital/main.twee
index 1b7d9771ef..eeb69c5584 100644
--- a/game/overworld-town/loc-hospital/main.twee
+++ b/game/overworld-town/loc-hospital/main.twee
@@ -116,7 +116,7 @@ You are inside the hospital foyer. <<if $psych is 1>>You see a sign directing to
 			<<link [[Inquire about movement in your stomach (0:10)|Pregnancy Introduction]]>><<pass 10>><</link>>
 			<br>
 		<</if>>
-		<<if _pregnancy.seenDoctor is 3 or (_pregnancy.motherStatus is 2 and _pregnancy.seenDoctor gt 3) or $container.portable.value gt 0>>
+		<<if _pregnancy.seenDoctor is 3 or (_pregnancy.motherStatus is 2 and _pregnancy.seenDoctor gt 3) or (_pregnancy.book is 1 and _pregnancy.seenDoctor gt 3) or $container.portable.value gt 0>>
 			<<if $deviancy gte 75>><<set _pregnancy.namesChildren to true>><<else>><<set _pregnancy.namesChildren to false>><</if>>
 			<<if _pregnancy.namesChildren is true>>
 				<<link [[Inquire about your pregnancy and children (0:10)|Pregnancy Discussion]]>><<pass 10>><</link>>
diff --git a/game/overworld-town/loc-shop/petShop.twee b/game/overworld-town/loc-shop/petShop.twee
index 97b3299073..d6302ee6b9 100644
--- a/game/overworld-town/loc-shop/petShop.twee
+++ b/game/overworld-town/loc-shop/petShop.twee
@@ -36,7 +36,6 @@ You are in the pet shop. <<if $daystate is "night">>Most of the animals are slee
 	<<endevent>>
 <<elseif $seenPets isnot true and $daystate isnot "night">>
 	<<set $seenPets to true>><<stress -10>>
-	<br>
 	You have a look around the shop, and pet some of the cats and dogs.
 	<<lstress>>
 	<br><br>
@@ -59,7 +58,7 @@ You are in the pet shop. <<if $daystate is "night">>Most of the animals are slee
 		<<PetShopBoughtItem>>
 	<</if>>
 	<br>
-	Capacity Upgrades:
+	__Capacity upgrades:__
 	<br>
 	<<if (_pregnancy.motherStatus is 0 and _container.upgrades.capacity lt 1) or (_pregnancy.motherStatus gt 0 and _container.upgrades.capacity lt 4)>>
 		<ul>
@@ -94,7 +93,7 @@ You are in the pet shop. <<if $daystate is "night">>Most of the animals are slee
 	<</if>>
 	<<if _pregnancy.motherStatus gte 1 and _container.upgrades.capacity gt 1>>
 		<br>
-		Food Upgrades:
+		__Food upgrades:__
 		<br>
 		<<if _container.upgrades.foodStorage lt 3>>
 			<ul>
@@ -121,7 +120,7 @@ You are in the pet shop. <<if $daystate is "night">>Most of the animals are slee
 	<</if>>
 	<<if _container.upgrades.capacity gt 2>>
 		<br>
-		Decoration Upgrades:
+		__Decoration upgrades:__
 		<br>
 		<<if _container.upgrades.luxury lt 1 or (_container.upgrades.capacity gt 3 and _container.upgrades.luxury lt 2)>>
 			<ul>
@@ -141,6 +140,15 @@ You are in the pet shop. <<if $daystate is "night">>Most of the animals are slee
 			<br>
 		<</if>>
 	<</if>>
+	<<if $sexStats.anus.pregnancy.book is 2>>
+		<br>
+		<<if $money gte 2000>>
+			<<link [[Buy notebook (£20)|Pet Shop Book]]>><<set $money -= 2000>><</link>>
+		<<else>>
+			You see a notebook available that you could use to collect info on your parasites. It costs £20. You can't afford it.
+		<</if>>
+		<br>
+	<</if>>
 <</if>>
 <br>
 <<if $farm_stage gte 7 and $daystate isnot "night">>
@@ -162,7 +170,7 @@ You examine the range of dog treats on display.
 <</if>>
 
 <<if $money gte 100>>
-	<<link [[Buy 1|Pet Shop Treats Buy]]>><<set $money -= 100>><<set $kennel_treats += 1>><</link>>
+	<<link [[Buy 1 (£1)|Pet Shop Treats Buy]]>><<set $money -= 100>><<set $kennel_treats += 1>><</link>>
 	<br>
 <<else>>
 	<span class="blue">You can't afford any.</span>
@@ -205,6 +213,18 @@ You buy the treats, and have them sent to the farm. You have <span class="gold">
 <<link [[Next|Pet Shop]]>><</link>>
 <br>
 
+:: Pet Shop Book
+<<effects>>
+<<set $sexStats.anus.pregnancy.book to 3>>
+You find a high-quality notebook available that you could use to collect info on your parasites. It has individual pages to fill out for scientific study on animal species in the wild, but it would work just fine for parasites, you think. You purchase it.
+<br><br>
+
+<i>You can now view info about the parasites you've birthed, at any location where you look after them.</i>
+<br><br>
+
+<<link [[Next|Pet Shop]]>><</link>>
+<br>
+
 :: Widgets PetShopBoughtItem [widget]
 
 <<widget "PetShopBoughtItem">>
-- 
GitLab


From 8009dfa3ee519b421e5168abe5681ad341e8b6cb Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Thu, 1 Sep 2022 21:41:04 +0000
Subject: [PATCH 18/50] Bugfix/sextoys fixup

---
 game/03-JavaScript/sextoys.js | 142 +++++++++++-----------------------
 1 file changed, 46 insertions(+), 96 deletions(-)

diff --git a/game/03-JavaScript/sextoys.js b/game/03-JavaScript/sextoys.js
index b3616b3f54..e4028e8102 100644
--- a/game/03-JavaScript/sextoys.js
+++ b/game/03-JavaScript/sextoys.js
@@ -1,126 +1,76 @@
 function playerHasStrapon() {
-	return (V.worn.under_lower.type.includes("strap-on") && V.worn.under_lower.state == "waist")
+	return V.worn.under_lower.type.includes("strap-on") && V.worn.under_lower.state === "waist";
 }
 window.playerHasStrapon = playerHasStrapon;
 
 function npcHasStrapon(index) {
-	if (typeof index !== 'number') {
-		if (V.debugdisable === 'f' || V.debug === 1)
-			Errors.report(`[npcHasStrapon]: index must be a number, was ${typeof index}.`, { index });
+	if (typeof index !== "number") {
+		if (V.debugdisable === "f" || V.debug === 1)
+			Errors.report(`[npcHasStrapon]: index must be a number, was ${typeof index}.`, {
+				index,
+			});
 		return false;
 	} else if (index < 0 || index > 5) {
-		if (V.debugdisable === 'f' || V.debug === 1)
-			Errors.report(`[npcHasStrapon]: index must be between 0 and 5 inclusive, was ${index}.`, { index });
+		if (V.debugdisable === "f" || V.debug === 1)
+			Errors.report(
+				`[npcHasStrapon]: index must be between 0 and 5 inclusive, was ${index}.`,
+				{ index }
+			);
 		return false;
 	}
 	// index is 0 to 5
 	const npc = V.NPCList[index];
-	return (npc && npc.strapon && npc.strapon.state === "worn");
+	return npc && npc.strapon && npc.strapon.state === "worn";
 }
 window.npcHasStrapon = npcHasStrapon;
 
 function getSexToysofType(toyType) {
-	var sexToys = ["dildo","whip","stroker","vibrator","all"];
-	sexToys["dildo"] = ["dildo","length of anal beads"];
-	sexToys["whip"] = ["riding crop","flog"];
-	sexToys["stroker"] = ["stroker"];
-	sexToys["vibrator"] = ["vibrator","bullet vibe"];
-	sexToys["all"] = sexToys["dildo"].concat(sexToys["whip"],sexToys["stroker"],sexToys["vibrator"]);
+	const sexToys = {
+		dildos: ["dildo", "length of anal beads"],
+		whip: ["riding crop", "flog"],
+		stroker: ["stroker"],
+		vibrator: ["vibrator", "bullet vibe"],
+		get all() {
+			return [...this.dildos, ...this.whip, ...this.stroker, ...this.vibrator];
+		},
+	};
 
-	if (toyType != undefined){
-		if (toyType == "dildo"){
-			var dildos = sexToys["dildo"].concat(sexToys["vibrator"]);
-			return dildos;
-		}
-		else if (toyType == "stroker"){
-			return sexToys["stroker"];
-		}
-		else if (toyType == "whip"){
-			return sexToys["whip"];
-		}
-		else if (toyType == "vibrator"){
-			return sexToys["vibrator"];
-		}
-		else if (toyType == "dildos and strokers"){
-			var dildos = sexToys["dildo"].concat(sexToys["vibrator"],sexToys["stroker"]);
-			return dildos;
-		}
-		else if (toyType == "dildos and whips"){
-			var dildos = sexToys["dildo"].concat(sexToys["vibrator"],sexToys["whip"]);
-			return dildos;
-		}
-		else {
-			return sexToys["all"];
-		}
-	}
-	else {
-		//console.log("All sex toys. Length = "+sexToys["all"].length+ " and I contain: " +sexToys["all"]);
-		return sexToys["all"];
+	/* sexToys.all = sexToys.dildos.concat(sexToys.whip, sexToys.stroker, sexToys.vibrator); */
+
+	const dandv = sexToys.dildos.concat(sexToys.vibrator);
+	const dandvs = dandv.concat(sexToys.stroker);
+	const dandvw = dandv.concat(sexToys.whip);
+
+	if (toyType) {
+		if (Object.keys(sexToys).includes(toyType)) return sexToys[toyType];
+		else if (toyType === "dildo") return dandv;
+		else if (toyType === "dildos and strokers") return dandvs;
+		else if (toyType === "dildos and whips") return dandvw;
+		else return sexToys.all;
+	} else {
+		// console.log("All sex toys. Length = "+sexToys["all"].length+ " and I contain: " +sexToys["all"]);
+		return sexToys.all;
 	}
 }
 window.getSexToysofType = getSexToysofType;
 
-function npcHasSexToyOfType(npcIndex,toyType) {
-	var npc = V.NPCList[npcIndex];
-	if (npc.righttool != undefined || npc.lefttool != undefined){
-		var sexToys = ["dildo","whip","stroker","all"];
-		sexToys.dildo = getSexToysofType("dildo");
-		sexToys.whip = getSexToysofType("whip");
-		sexToys.stroker = getSexToysofType("stroker");
-		sexToys.vibrator = getSexToysofType("vibrator");
-		sexToys.all = getSexToysofType("all");
+function npcHasSexToyOfType(npcIndex, toyType) {
+	const npc = V.NPCList[npcIndex];
+	const sexToyList = getSexToysofType(toyType);
 
-		/* Only output to console if in debug mode. */
-		if (V.debug) console.log("sex toys: "+sexToys.all);
+	/* Only output to console if in debug mode. */
+	if (V.debug) console.log("sex toys: " + getSexToysofType("all"));
 
-		return sexToys[toyType].includes(V.NPCList[npcIndex].righttool) || sexToys[toyType].includes(V.NPCList[npcIndex].lefttool)
-	}
-	else {
-		return false;
-	}
+	return sexToyList.includes(npc.righttool) || sexToyList.includes(npc.lefttool);
 }
 window.npcHasSexToyOfType = npcHasSexToyOfType;
 
-function randomSexToy(toyType) {
-	if (toyType != undefined){
-		if (toyType == "dildo"){
-			var dildos = getSexToysofType("dildo");
-			return dildos[random(0,dildos.length-1)];
-		}
-		else if (toyType == "stroker"){
-			var strokers = getSexToysofType("stroker");
-			return strokers[random(0,strokers.length-1)];
-		}
-		else if (toyType == "whip"){
-			var whips = getSexToysofType("whip");
-			return whips[random(0,whips.length-1)];
-		}
-		else if (toyType == "vibrator"){
-			var vibrators = getSexToysofType("vibrator");
-			return vibrators[random(0,vibrators.length-1)];
-		}
-		else if (toyType == "dildos and strokers"){
-			var dildos = getSexToysofType("dildos and strokers");
-			return dildos[random(0,dildos.length-1)];
-		}
-		else if (toyType == "dildos and whips"){
-			var dildos = getSexToysofType("dildos and whips");
-			return dildos[random(0,dildos.length-1)];
-		}
-		else {
-			var sexToys = getSexToysofType("all")
-			return sexToys[random(0,sexToys.length-1)];
-		}
-	}
-	else {
-		//console.log("All sex toys. Length = "+sexToys["all"].length+ " and I contain: " +sexToys["all"]);
-		var sexToys = getSexToysofType("all")
-		return sexToys[random(0,sexToys.length-1)];
-	}
-}
+const randomSexToy = toyType => getSexToysofType(toyType).random();
 window.randomSexToy = randomSexToy;
 
 function playerHasButtPlug() {
-	return (V.worn.butt_plug != undefined && V.worn.butt_plug.state == "worn" && V.worn.butt_plug.worn == 1) // V.worn.butt_plug.worn == 1 is just as a safeguard for now
+	return (
+		V.worn.butt_plug != null && V.worn.butt_plug.state === "worn" && V.worn.butt_plug.worn === 1
+	); // V.worn.butt_plug.worn === 1 is just as a safeguard for now
 }
 window.playerHasButtPlug = playerHasButtPlug;
-- 
GitLab


From 4ce0a52a7c281eb0973cc244f958121ee207b602 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=B6st?= <35009-Host@users.noreply.gitgud.io>
Date: Thu, 1 Sep 2022 22:08:15 +0000
Subject: [PATCH 19/50] Chance to wake up with ruffled up hair

---
 game/03-JavaScript/base.js     |  7 +++++
 game/04-Variables/hair-defs.js | 47 ++++++++++++++++++++++++++++++++++
 game/base-system/sleep.twee    | 24 +++++++++++++++++
 game/base-system/tips.twee     |  2 ++
 4 files changed, 80 insertions(+)
 create mode 100644 game/04-Variables/hair-defs.js

diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index c7fc3db945..6c6ab94335 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -659,3 +659,10 @@ Macro.add("icon", {
 		if (!this.args.includes("nowhitespace")) this.output.append(" ");
 	}
 });
+
+window.pickRandom = function (list) {
+	if (!list)
+		return undefined;
+
+	return list[Math.floor(Math.random() * list.length)];
+}
diff --git a/game/04-Variables/hair-defs.js b/game/04-Variables/hair-defs.js
new file mode 100644
index 0000000000..38fb0ae8cd
--- /dev/null
+++ b/game/04-Variables/hair-defs.js
@@ -0,0 +1,47 @@
+setup.hair = {
+    hairtype: [
+        {
+            name: "default",
+            list: ["default", "loose", "straight", "swept left", "curl", "defined curl", "neat", "curly side up", "heart braid", "ruffled"],
+            devolve_into: ["ruffled"]
+        },
+        {
+            name: "single tail",
+            list: ["flat ponytail", "ponytail", "side tail left", "side tail right"],
+            devolve_into: ["ponytail"]
+        },
+        {
+            name: "double tail",
+            list: ["pigtails", "twintails", "curly pigtails", "sailor buns", "loop braid"],
+            devolve_into: ["twintails"]
+        },
+        {
+            name: "single braid",
+            list: ["braid left", "braid right"],
+            devolve_into: ["braid left"]
+        },
+        {
+            name: "double braid",
+            list: ["twin braids"],
+            devolve_into: ["twin braids"]
+        },
+        {
+            name: "short",
+            list: ["messy", "short", "short spiky"],
+            devolve_into: ["messy", "short spiky"]
+        },
+        {
+            // immune to being ruined (because devolve list is empty)
+            name: "special",
+            list: ["dreads", "bubble tails"],
+            devolve_into: []
+        }
+    ],
+    fringetype: [
+        {
+            name: "default",
+            list: ["default", "thin flaps", "wide flaps", "hime", "loose", "messy", "overgrown", "ringlets", "split", "straight", "swept left", "back", "parted", "flat", "quiff", "straight curl", "ringlet curl", "curtain", "trident"],
+            devolve_into: ["messy", "trident", "thin flaps"]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/game/base-system/sleep.twee b/game/base-system/sleep.twee
index 945cf7effc..f62cb033ae 100644
--- a/game/base-system/sleep.twee
+++ b/game/base-system/sleep.twee
@@ -2,6 +2,7 @@
 
 <<widget "sleep">>
 	<<sleephour>>
+	<<ruffleHairFromSleep>>
 <</widget>>
 
 <<widget "sleephour">>
@@ -334,6 +335,29 @@
 	<<set $foresthunt to 0>>
 <</widget>>
 
+<<widget "ruffleHairFromSleep">>
+	<!-- Roll a chance to wake up with ruffled hair the longer you sleep -->
+	<!-- Chance is negligible at under 5 hours of sleep and reaches 40% at 10 hours, 100% at 13 hours -->
+	<!-- Graph: https://www.desmos.com/calculator/gslcapsydv -->
+	<<set _chance = Math.pow($sleepHoursTotal, 4) * 10 / 250000>>
+	<<set _roll = Math.random()>>
+	<<if $debug>>
+		<<print $sleepHoursTotal + " hours: Rolled " + _roll + " vs " + _chance + " chance">>
+	<</if>>
+	<<if _chance > _roll>>
+		<span class="yellow">Your hair is tousled.</span>
+		<<ruffleHair>>
+	<</if>>
+<</widget>>
+
+<<widget "ruffleHair">>
+	<!-- Find a style group of current hair (loose, braid, etc.) and pick a random one from a list of corresponding 'ruffled' styles. If none found then keep current hair -->
+	<<set $hairtype = pickRandom(setup.hair.hairtype.find(x => x.list.contains($hairtype))?.devolve_into) ?? $hairtype>>
+	<<set $fringetype = pickRandom(setup.hair.fringetype.find(x => x.list.contains($fringetype))?.devolve_into) ?? $fringetype>>
+	<<set $tempSavedHairStyles.hairtype = $hairtype>>
+	<<set $tempSavedHairStyles.fringetype = $fringetype>>
+<</widget>>
+
 :: SleepSlimeEventObey
 	You obey the slime's demand.
 	<<slimeEventResult>>
diff --git a/game/base-system/tips.twee b/game/base-system/tips.twee
index 130ab0e950..7d4eb8aefc 100644
--- a/game/base-system/tips.twee
+++ b/game/base-system/tips.twee
@@ -136,6 +136,8 @@
 			"Blood moons are said to cause strange behaviour and hallucinations. They happen on the last day of every month.",
 			"Sleeping through a blood moon can be dangerous.",
 			"A slippery stage is a dangerous stage.",
+			"You may wake up with bad hair after a prolonged sleep. Aim to have 7-8 hours of sleep to minimise the chance and get enough rest.",
+			"You can assign a hair style along with a clothing set to quickly dress up and do your hair in one go.",
 		]>>
 
 		<!-- Tentacle tips -->
-- 
GitLab


From 4f5675dff1487f7bf1dc6b394ce5f222c9851461 Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Thu, 1 Sep 2022 22:44:17 +0000
Subject: [PATCH 20/50] Bugfix/11.4 fixes

---
 game/01-config/constants.js                   |   4 +
 game/03-JavaScript/base.js                    |  45 ---
 game/03-JavaScript/bedroomPills.js            |  52 +--
 game/03-JavaScript/canvasmodel.js             | 185 +++++-----
 game/03-JavaScript/eyesRelated.js             | 320 ++++++++++--------
 game/03-JavaScript/save.js                    |  12 +-
 game/04-Variables/variables-start.twee        |   1 -
 .../04-Variables/variables-versionUpdate.twee |  11 +
 game/base-clothing/canvasmodel-img.twee       |   4 +-
 game/base-combat/audience.twee                |  25 +-
 game/base-combat/ejaculation.twee             |   2 +-
 game/base-combat/machine/machine.twee         |   3 +-
 game/base-combat/struggle.twee                |   1 +
 game/base-system/mirror.twee                  | 118 ++++---
 game/base-system/mobileStats.twee             |   6 +-
 game/base-system/orgasm.twee                  |  12 +-
 game/base-system/overlays/cheats.twee         |   2 +-
 game/base-system/physicalAdjustments.twee     |  13 +-
 game/base-system/settings.twee                |   2 +-
 game/base-system/text.twee                    |  25 +-
 game/base-system/widgets.twee                 |  21 +-
 game/overworld-forest/loc-asylum/events.twee  |  12 +-
 game/overworld-forest/loc-asylum/widgets.twee |   2 +-
 game/overworld-forest/loc-cabin/events.twee   |   2 +-
 game/overworld-forest/loc-cabin/main.twee     |   2 +-
 game/overworld-forest/loc-lake/widgets.twee   |   2 +-
 game/overworld-forest/loc-wolfpack/wolf.twee  |  12 +-
 .../loc-estate/cards_widgets.twee             |   2 +-
 game/overworld-plains/loc-estate/main.twee    |   3 +-
 .../overworld-plains/loc-estate/sabotage.twee |   2 +-
 game/overworld-plains/loc-farm/events.twee    |   2 +-
 game/overworld-plains/loc-livestock/main.twee |   2 +-
 game/overworld-town/loc-adultshop/events.twee |   2 +-
 game/overworld-town/loc-adultshop/intro.twee  |   2 +-
 game/overworld-town/loc-adultshop/shop.twee   |   2 +-
 .../overworld-town/loc-adultshop/widgets.twee |   4 +-
 game/overworld-town/loc-brothel/main.twee     |   2 +-
 game/overworld-town/loc-cafe/main.twee        |   4 +-
 game/overworld-town/loc-compound/main.twee    |   4 +-
 .../loc-dance-studio/widgets.twee             |   4 +-
 .../overworld-town/loc-danube-homes/work.twee |   6 +-
 game/overworld-town/loc-docks/main.twee       |   2 +-
 game/overworld-town/loc-domus-homes/nude.twee |   6 +-
 game/overworld-town/loc-home/widgets.twee     |   4 +-
 game/overworld-town/loc-hospital/main.twee    |   2 +-
 game/overworld-town/loc-park/run.twee         |   2 +-
 .../overworld-town/loc-photography/model.twee |  10 +-
 game/overworld-town/loc-police/pillory.twee   |   2 +-
 game/overworld-town/loc-pound/abduction.twee  |   8 +-
 game/overworld-town/loc-pub/seduction.twee    |   2 +-
 game/overworld-town/loc-school/fame.twee      |   2 +-
 game/overworld-town/loc-school/infirmary.twee |   6 +-
 .../loc-school/maths-project.twee             |   2 +-
 .../loc-school/science-project.twee           |   2 +-
 .../loc-school/special-olive.twee             |   2 +-
 .../loc-school/widgets-events.twee            |  12 +-
 game/overworld-town/loc-school/widgets.twee   |   4 +-
 game/overworld-town/loc-street/events.twee    |  10 +-
 game/overworld-town/special-avery/main.twee   |   2 +-
 .../special-kylar/abduction_events.twee       |  82 ++---
 game/overworld-town/special-kylar/main.twee   |   2 +-
 .../special-robin/crossdressing.twee          |   6 +-
 game/overworld-town/special-robin/main.twee   |   6 +-
 .../overworld-town/special-robin/widgets.twee |   4 +-
 .../overworld-town/special-sydney/temple.twee |   6 +-
 game/overworld-town/special-whitney/park.twee |   2 +-
 .../special-whitney/street.twee               |   2 +-
 .../loc-sewers/morgan.twee                    |   4 +-
 .../loc-sewers/old-sewers.twee                |   4 +-
 .../loc-underground/events.twee               |   2 +-
 game/special-exhibition/main.twee             |   2 +-
 71 files changed, 583 insertions(+), 556 deletions(-)

diff --git a/game/01-config/constants.js b/game/01-config/constants.js
index 5daa6a6134..8f350bcc93 100644
--- a/game/01-config/constants.js
+++ b/game/01-config/constants.js
@@ -7,6 +7,10 @@ const constants = {
 		max: 5,
 		min: -2,
 	},
+	tiredness: {
+		max: 2000,
+		min: 0,
+	},
 };
 
 /* Hoist Constants to the top (For statevars.js) */
diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index 6c6ab94335..fb2e0737c6 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -427,51 +427,6 @@ DefineMacroS("svg", processedSvg, null, false, true);
 
 /*! <<numberpool>> macro set for SugarCube v2 */
 
-window.AvsAn = (function () {
-	var dict = "p3ezz;4wrlg;2h;#2rg;22;2;a;7;;if;z;;&4h;1c;1;N;6;;*yp;6a;4;a2;q;;e1;q;;i1;h;;o;7;;/op;5n;9;a3;i;;e5;h;;h;;1;o5;;;i;r;;l;;1;/;6;;n;;1;o6;;;o1;a;;r;;1;e7;;;s;;1;/2;j;;09pa;y3;1;8e;10;;17qoq;qmm;2;12hp;7nw;a;0o4;45;1;0n;2w;;15r;1n;2;8;7;;9;5;;28s;x;;34q;z;1;7;5;;45n;n;;598;w;;65k;u;;74j;y;;850;y;;93x;g;;81ux;hgk;a;0zb;el;a;0p;4h;;11;16;;21;10;;32;15;;4;18;;54;v;;6;12;;7;s;;8;v;;9;17;;11k;bq;1; v;2;;229;f3;2; 1a;3;;–5;;;31x;jc;1; 12;2;;41w;kq;2; z;4;;–5;;;559;sp;5; 2k;1;;,h;;;h7;;;kd;;;m6;;;62p;rm;2; 1b;5;;k5;;;72n;y6;2; 14;;;–5;;;82r;192;2; 19;4;;,5;;;93i;1ig;2; 10;4;;–5;;;8ys;nsu;;<e9;1x;2;m;;1;d;6;;o;6;;=kq;1x;1;=3m;g;1;E;6;;@16;2a;;A3wn;bu7d;6;Abr;y1;1;A8b;5o;1;S3;e;;i2g;4rh;1;r26;4dg;1;ob;2;;mg9;5490;1;a1k;140;1;rv;1e;1; t;1;;n6n;gfl;1;d25;1ae;1;a1c;5b;1;l1b;4c;1;u1b;3r;1;c18;c;1;i;;1;a;;1;n;6;;s3f;feu;1;tn;sc;1;uh;1t;1;rh;1s;1;ih;1q;1;ah;1q;1;sg;1;;t71;41h;1;h53;112;1;l4x;7i;1;e4w;6m;1;t4w;6m;1;e4w;2j;1;s;f;;B7cel;sz;2;hlb;42;2;aaw;28;1;ij;1y;1;rf;1s;1;ae;;;á;11;;olhj;28;1;r1cy;j;1;des;f;1; 3;f;;C8l05;10j;3;a29ng;5t;1;i9c;b;1;s;;1;s5;;;h1ska;9p;4;aa1a;1x;2;i115;o;1;s5;g;1;e5;;;o5p;7;1;i;6;;l17;l;1;á;f;;rkxk;19;1;o9t;a;1;í;5;;u2re;y;2;i1;a;;r2fq;e;1;re;5;1;a;5;;o1vrk;88;1;njpy;1m;1;g380;f;1;j;5;;D40dx;hh;7;aj56;1y;1;o35;6;1;q;5;;ijhc;2t;2;nbw;j;1;a17;f;1;s4;f;;ogz;g;1;t1;9;;uivv;1r;1;ad2;7;1;lci;7;1;c;7;;á30;7;1; ;5;;ò;5;;ù1;e;;ư;7;;Efoe;42zy;7;U3t;zk;1;R1r;4;;be;42;1;oc;1t;1;lb;p;1;ib;;;m2k;73m;1;pw;13w;1;eh;91;1;zd;;;n7x;27zz;1;af;14;1;md;3;;syp;35x;1;pws;9c;5;awn;p;1;c;7;;e4;7d;;h;5;;o;b;;r;h;;udjl;hc;1;lj;6o;1;o6;;;wr;1e;1;id;2;;F4eta;hhx;11; cf;1rz;;,;17;;.2j;6h;;/i;29;;05;2y;;128;e1;;216;9g;;311;7d;;418;8i;;5i;5u;;69;z;;7;;1;0a;;;86;j;;97;l;;A404;5ij;e;Be;3;;Ct9;my;;Dx;9;;Fc;;;I;;2;L8;;;Rq;;;K11;;;Ll;4;;M1x;1;;Ny;2;;P13;2;;Q9h;5j;;Rad;3p;;S1n;9;;T2t;2;;B57;1ji;;C4s;jp;1;Mb;1;;D2g;ak;;E7r;39;2;C6;k;;I5;f;;F33;64;1;r5;;;Hz;1u;;I1vx;bk;3;A24;45;1;Tm;1;;R;;1; w;30;;U2;a;;J5;f;;Lkk;g1;3;C2p;3v;;N4;e;;P1;f;;M6w;1ds;;Og3;2e;1; 5;i;;Ps4;w7;1;.7i;53;;R8v;3z;2;A1e;g;1; 3;e;;Se;y;;S3g;91;;T8a;1ah;1;S1x;6;;Uel;3m;2;,2;b;;.;k;;Xm;1o;;Yz;5w;1;V6;;;c3;l;;f;;1;o7;;;h1;31;;σ1;i;;G55z0;ig;7;e1sct;3h;1;r1fvh;1n;1;n;;1;e;a;;h1sd;31;1;a17k;2e;3;e;q;;i;n;;o;6;;i4b9;s;1;alt;c;1;nl0;b;1;g1;a;;ovi2;2d;2;f;;1; ;b;;t238;f;1;t2z;7;1; ;6;;r17jv;32;1;iql;e;1;a;9;;w43;6;1;a1p;5;1;rd;5;1;r;5;;ú;5;;H24sn;cwd;s; 5i;mk;;&b;17;;,1;f;;.37;42;2;Ai;;;Ie;4;;1i;1j;;2r;22;;39;n;;5a;19;;72;a;;B2z;cx;1;P7;;;C1q;35;;Dd1;tb;;F1l;2x;;Gl;14;;Hy;30;1;I5;;;I80;i9;6;Cc;1;;G10;2;;Nb;1;;Pq;2;;S;;1;D1;j;;Tf;1;;K4k;1w;1;9;7;;L1e;35;;M36;6u;1;.c;;;Ny;2v;;O95;3g;2; 7;t;;Vc;16;;P4b;bf;;R2v;4v;1;Tn;7;;S;;1;F5;;;T9c;115;;V1k;3u;;eaox;7p;2;im1;11;1;r4;o;;r29t;2m;1;r1d;7;1;n;5;;ohh1;6d0;2;n3jr;65v;6;d121;v;;e4c;1m;1;s7;1m;;g21f;e;;kp;;;oad;61b;2;l26;1;;r7c;5jz;1;i;;1;f;5;;v6;;;u2q4;32;1;r2;2x;;I266;4mgb;3;I4o;8f;2;*6;;;I1v;j;;nij;1hm4;1;d9p;wtp;1;e1c;3wy;1;p12;3r6;1;e12;3r6;1;n12;3r4;1;d12;3r4;2;et;3qw;1;nt;3qw;1;c7;41;1;i6;;;ê8;;;s4h;cif;1;l2i;42z;1;a2h;3yr;1;ne;gy;1;de;gy;1;sd;3;;J24b6;7h;1;iw9;t;1;a;;1;o2;o;;L2u98;abe;y; 5s;17t;;,2;s;;.25;9q;;1l;1t;;2j;2h;;3a;10;;48;l;;8;c;;Anc;ce;3; 1e;6q;;Po;2t;;X1;a;;B1j;2r;;C59;r4;;D42;lc;;Ejg;hg;2; 2;i;;D4x;e9;;F20;3s;1;Ti;2;;G8s;ko;;H;;1;Dk;6;;Idy;1m;1;Rd;u;;Lc0;25k;;M3k;94;;N26;51;;P63;1g0;;R23;6z;;S2z;f6;1;m7;;;T36;86;;U1s;n;1; 5;h;;V14;35;1;C7;;;W;;1;T;5;;Z9;t;;^;5;;am5d;3g;1;o91;e;1;i;;1;g;e;;oln2;3r;1;c2ik;19;1;h1s;11;1;a7;z;1;b6;;;p1;h;;u51i;1q;1;s4p;x;1;hg;w;1;ob;;;ộ;5;;M5bhu;skd;15; 6n;n2;;&b;1h;;,;g;;.1kr;5er;1;Alm;2kf;1;.kf;2ht;1;Sa;2;;/4;1f;;14f;f4;;22a;6k;;3y;31;;41j;5h;;5n;1a;;6r;3q;;7t;1f;;87;11;;A1fx;2mt;i;B5;;;C9q;1;;D2d;3;;F12;4;;G17;4;;J38;;;L11;2;;Mv;1;;N2i;a;;P2f;6;;R2o;;;S2t;6;;T2l;f;;Vc;2;;W7;;;X1h;;;Ya;;;Z7;;;Bbv;39s;1;Sb;r;1;T9;;;C5e;ni;;D5e;na;;Efj;d4;3;P1j;9f;1;S7;;;W;7;;n6;i;;F64;14y;;G31;az;;H2i;7d;;Izq;ij;4; f;w;;5;2o;;6f;35;;T25;7y;1;Mi;1;;K1o;3c;;Lcl;17r;;Mcc;rp;;N1i;40;;Osl;av;1;U17;2c;;Pel;3xz;;Qa;1g;;R4l;nw;;Sku;1ld;;Tai;yj;1;R1y;w;;Uas;1t;2; 2;i;;V3;d;;V3s;a5;;Xq;2p;;b1a;i;1;ur;d;1;m1;a;;f2q;ek;;hf;1g;;om4z;7h;2;D;;1;e7;;;U2b;34;1;.5;;;p;;1;31;b;;s23;h;1;c3;c;;N3qyx;ipi;y; 7p;qe;;+;9;;.;;1;Eg;5;;46;k;;7;7;;8;7;;:;5;;A4ga;in;3;A3g;6j;1;Fo;2;;I1m;52;;S2l3;1x;1;Lb;1b;;B8k;2gd;;Ckh;2ib;;D2t;aq;;Ejp;9r;3;A10;2r;;H5;16;;S;;1; 1y;2v;;Fas;2sm;1;Uc;2;;G5x;zb;;H8o;1oq;;I;;7;C1w;j;;D;;1; ;9;;Ka;;;Ld;2;;Nj;;;O8;;;S20;n;;K1c;4g;;L2t;94;;M1s;9a;1;M5;;;Ndl;36;2;R1;d;;T4;h;;P;;1;O25k;1j4;1;V24y;1i8;1;/;;1;B;5;;R9n;f6;2;Je;3;;T3y;e;;Sby;lt;1;W5m;g;;T3m;9h;1;L;;1;D5;;;U60;1a;1;S4;i;;V1a;4h;;W64;4n;2;Au;30;;O;;1;H;8;;Xp;4p;;Ys5;af;3;C64;1i;1;L;6;;P1k;3t;;Uj;1p;;a10pz;8f;1;sq1;d;1;a;;1;n1;8;;t;;1;h1;a;;vk;1c;;²;7;;×;5;;O1n9;1g7f;5;N17;3l;1;E12;2;;l29;8yb;1;vl;2;;nuh;1ti;2;c;;1;ec;2;;etc;21;1;i2;1k;;oi;3e;1;pf;1;;u3x;1ey;1;i3c;b;;P5dsg;kg;1;hmb6;3r;2;i39j;v;1;a;9;;o128;1s;2;bh;19;2;i8;;;o9;;;i1;j;;Qb3c;1l;1;i8c;t;1;n61;l;1;g4x;l;1;x1;f;;R3te6;u0n;z; 6h;119;;&8t;ze;;,;k;;.2r;4t;1;Jj;3;;/a;q;;11s;3k;;4a;r;;67;j;;A12c;ym;3; d;1o;;.1;a;;F7v;ra;1;Tf;;;B4b;v4;1;Rk;3;;C52;l7;;D34;9b;;Enp;3a;3; b;q;;S3z;q;1;Pa;p;;U;5;;Fxl;5cg;;G11;5w;;H1x;1a;1;S4;f;;If2;6o;2;A17;3s;;C;;1; a;1c;;Jn;2e;;Kz;5g;;L1h;2k;1;P6;;;M5u;cg;5;1e;4;;26;;;36;;;59;;;65;;;N4y;q3;;Ogs;86;2;Hk;16;;T1n;3b;2;Av;;;O7;;;P4u;q7;;Q8;q;;R21;37;1;F6;;;S1pl;1up;4;,85;6b;;.ba;7l;;?2l;y;;Tv;6;;T5t;iz;;U23;4u;4;B5;;;M5;;;Nb;;;S9;1;;V1h;8u;;Xa;o;;c;8;;f3qh;db8;1;M;;1;.h;4;;h1xk;1a;2;A;5;;B;5;;ò;5;;S7ldf;ea7;11; 9n;18a;;&1o;3s;;,2;f;;.e8;91;4;E7;m;;Mc;10;;Oa;18;;T;;1;.;;3;B2;b;;D3;c;;M2;c;;1m;29;;35;o;;4b;s;;55;i;;68;s;;84;i;;92;b;;A1b1;l3;3; 2a;7d;;8;5;;S2v;3t;2;Ep;4;;I6;;;B30;74;;Clf;a7;3;A2z;15;1; 3;y;;R;;2;Ap;;;U5;;;T6;s;;D66;ns;;Eri;jq;6; s;1g;;5;7;;C3g;ba;3;Ac;;;Oh;;;Rh;3;;I;;1;F9;;;O1a;28;;U;5;;F58;7w;3;&5;;;H6;;;O;;1;S8;;;G24;5v;1;Df;5;;H6m;3t;3;25;h;;32;g;;L;7;;It0;83;2; f;50;;S;;1;O6;;;K;;2;I9;1;;Yh;;;L6z;8m;3;A2k;o;2; 1;g;;.;5;;Iu;e;1; 3;c;;Om;5;;M9j;lh;3;A28;o;1; 4;m;;Ii;5;;U;;1;R6;;;N;;5;A1e;b;;C;;3;A8;;;B5;;;C8;1;;E18;o;;Fa;;;O4g;1;;Oi7;dc;5; c;u;;A4c;1h;1;I5;g;;Eg;1m;;Sv;5m;1;U5;;;V9;p;;P1r8;320;7;A102;1dn;7;Aa;;;Ch;;;D22;;;Mr;;;Ne;;;R2f;;;S8;1;;E3k;j;1; 4;g;;Ib9;155;4;Co;;;D6;;;N5;;;R5;;;L13;26;1;O6;;;O18;e;;U1x;5;;Y5;;;Q;;1; 1;e;;R3i;9z;;Sf7;1kv;1;We;;;Tjg;e7;9;A46;w;1; 8;s;;C7;r;;Dn;2z;;F4;n;;Iq;1c;;L6;k;;Mm;15;;Sb;12;;V5;12;;U;;7;Bn;1;;L42;28;;Mj;;;N18;;;P15;2;;Rf;;;Sf;;;V6j;y7;;Whe;2v;1;R5;m;;X;;1;M2;c;;ha9m;14;1;i2m7;i;1;g;;1;a;;1;o;7;;pxbl;3u;1;i1lg;s;1;o6;j;1;n6;;;tpmv;33;2;B;5;;ikz;b;1;c5b;a;1;i;8;;T3dav;if;4;aczy;4f;2;i1wj;15;2;g;;1;a6;;;s;;1;c;8;;v1q;q;1;e17;h;1;s;h;;ega6;29;1;a1o2;o;1;mg2;6;1;p;6;;uc4t;22;1;i;;2;l1;8;;r;8;;à1;n;;U2oh8;a1j;m;.jqk;80;1;N78;h;1;.70;h;1;C;f;;/2r;f;1;1;9;;1;;1; c;;;24b;x;1;17;k;;L3q;j;1;T;6;;M7h;1d;1;N8;q;;N4bp;am;4;C2u;k;1;L;5;;D;;2; 6;;;P14;2;;K;5;;R;;1; 5;;;a3;40;;b2r;43;2;am;4;;is;9;;de;16;;glp;3a;1;l;1n;;i;;1;gq;a;;l2u;14r;2;ig;4;;yc;;;my;8n;;ntrc;2uh;o; 5;k;;a;;1;n1e;b;;b3;1q;;ce;9w;;d1u;x2;;e19;1t;1;s16;2;;f3;2d;;g;l;;h6;l;;itj3;kb;2;d3;e;;n2;65;;j;7;;k3;55;;l3;2c;;m5;1e;;n2;t;;o4;13;;p2;1p;;q;5;;r6;71;;s5;2u;;t11;4a;;u6;v;;v1;a;;w1;10;;p12;ze;;r1ap;1rs;3;a4h;k;;ea;;;uz5;e2;1;k1;d;;s1at;41;3; ;7;;h9;t;;tw;1r;1;rp;1;;tla;49;4;h2;a;;n1;n;;ra;u;;t7;j;;x2;j;;z2d;dy;;í2;e;;W3fzh;1xp;2;Pgh8;1kw;1;:dtp;1jr;4;A;;1;Fp;1b;;I;;2;B1;9;;N;;1;H8;1;;Oe2;7b;1;V;a;;R1n7;cv;1;F;;1;C;;2;N5;;;U1b;e;;i150z;6l;1;kucb;5n;1;iu0s;5l;1;El;8;1;l;;1;i1;8;;X18k;5ru;7;a2o;6;;e7o;5;;h22;;;i8v;c;;om;4;;ux;4;;yt;4;;Ydr1;5s;3;e1xq;v;1;t35;a;1;h2;a;;p3;d;;s1;8;;[1f3;b3;5;A6;m;;E;b;;I1;a;;ai;13;;ed;30;;_1pde;5f3;2;_1pa2;5em;1;i;6;;e;5;;`4j;19;3;a1;g;;e;5;;i;7;;aa4e;1k1cr;7; 2e6;1r4;;m6h;1bmc;1;a2k;gdk;1;r;;1; 9;;;n1yq;4tcz;1;dsz;136;2; sm;69;;ě5;;;p8x;2tn1;1;rj;e8;1;t6;;;r1ql;dm6d;1;t1bb;7rrp;1;í6;;;uat;271y;1;sc;wm;1;s6;l;1;i;;1; 5;;;v31;2qsv;1;u5;21;1;t5;;;d14132;4sp;3;a4bh7;3i;1;s1q3;1j;1; ;1h;;edez2;3tl;2;mosa;1n;1; 2;10;;r9oc;3b1;1; 1;3an;;idsd0;ky;2;cfg1;k;1;hdj;d;1; ;c;;e57k;6w;1;s1rl;l;1;e1pp;k;2;m;5;;r;5;;e7wn;zlrz;8;c2u;mo2;1;o1z;egy;1;n1g;bbv;1;o1e;bbg;1;m1e;bbc;1;i1b;9c8;1;a6;;;ee;15d;1;w8;;;lbr;2yiq;1;it;5bi;1;tj;3qh;1;eg;3hs;1;i5;;;m8g;1t5c;1;p2z;oie;1;ed;v6;1;zd;;;nyp;6b4j;1;t7j;1g2s;1;e16;5d4;1;n5;r;1;d5;;;s96;1ypr;2;a;;1; 5;;;t45;1716;4;a2g;c3l;1; d;;;e8;i0;1; 6;;;il;tl8;1;ml;tl5;1;al;tl4;1;r5;;;rd;bo;1;u;;1;t6;;;u2qo;74;1;p11a;2j;1; ;i;;w2e;o;;f1n9ht;1ct;3; 1b;44;;M7;2j;;y1l;7;1;i;7;;hpp6o;1t04;9; 37;kq;;,1;9;;.;5;;C2;1d;;a4tpe;la;1;u1je;1r;1;tn;1j;1;b5;;;e3q3g;3wn;2;iajd;24b;1;r1z;232;1;a15;1;;rjaj;1ep;1;m1uj;14;1;a83;e;1;n;5;;o63t5;1eb3;4;mymg;1rd;2;a16t;1mn;1; 6;;;mm;1g;;n1aw;owo;8; a;1;;b8;;;df;;;ez3;32r;3; 6;;;de;;;yvn;1;;ga;;;if;1;;k4e;;;vd;;;ro27;7b;1;sc8c;1v;1; 8;15;;u1lyy;mvr;1;r26;mus;;ry;7;1; ;5;;t2t;51;1;t1e;24;1;p1e;24;1;:u;f;;i550;t5c8;6;bc;3a;1;n7;;;e9;l;1;r7;;;n2x3;jmka;2;fbo;1jnw;2;l1s;fl3;1;u17;cuh;1;ê9;;;o6p;gaj;1;ad;1;;s84;1pv1;1;t3y;whk;1;a17;9gq;1;ld;21c;1;a5;;;r2j;ekg;1; 8;1;;sqz;1agk;1; jd;4q;;u16;8;;k3v63;5f;1;urs;n;1; 3;n;;l1ewzo;zp;3;cj;7;1;d;6;;sl;5;1; ;5;;vm;8;1;a;8;;m1ql98;243;a; 1b;93;;,;7;;Rs;3e;;b;;1;a5;;;egur2;9r;1;i2c;d;1;n3;d;;f5;g;;pz;6b;;t;;1;aa;;;u5ql8;5t;1;l193t;2t;1;t17us;2t;1;i17ty;2t;1;c1d4;8;1;a4z;6;1;mo;6;1;p;;1;i;6;;×;a;;n14seq;3b7;6; 9r;1ei;;V7;w;;W4;q;;dx;1n;1; e;;;te;u;;×1;b;;o1po1;gmse;8;c2l;ewy;2;hb;4w;1;oa;1;;u7;6u;1;p7;;;d21;6ii;1;d1o;59e;1;ya;;;fkz;2cg9;1; br;51;;gp;fd;1;ge;11;1;ia;;;n1muy;151v;o; 4a;6y6;;';5;;,;8;;/1;3t;;a1;e;;b;db;;c1qc;se;1;o3;rn;;d1;n;;e1kqx;bu;2;i;b;;r6;3a;;f;9;;g1t;adm;;i3;ca;;l6q;jw7;;m4;14;;n;c;;o2;57;;r;1a;;s6;10f;;t6;hb;;u1;1l;;w1;1k;;y;15;;z;7;;–;6;;rht;2sas;1;i30;gwn;1;g2p;fl4;1;e6;;;t37;50i;1;r;;1;s;8;;u7j;1e6t;1;i16;6;;r1fxi6;1u1;3; 14;6g;;&1;8;;f12;52;;s3aro5;3io;9;,;e;;?;5;;R2;h;;f;;2;e8;;;o8;;;iggn8;b9;1;c1vp;18;1;hb;17;;l20u4;1m;1; ;5;;pbado;de;2;33;j;;ipic;12;1; ;5;;r1t;k;1;g;c;;v;;3;ae;;;e11;;;i6;;;t1c1p7;1mt;2;A1;9;;S3;2u;;u4dhq;8rnc;c; 7x;n;;.9;;;beh;3f;2;e7;1m;;l;5;;fl;6;;k6h;2e;2;ae;11;;i8;n;;m1j;4kj;1;a;;1; f;5;;n2eo5;6zny;3;a3ln;7j0;3; 1r;4;;n3dz;in;5;a2;c;;c;8;;n5;a7;;s;37;;t;3h;;r4a;jh;1;y46;4;;e28;a8m;2; m;;;i7;;;i29p3;wfu;8;c14a;17;2;oeg;i;1;rcl;h;1;p;a;;u;;1;m;6;;d4x;2b9;1;i4d;f;1;o;7;;g;;1;n;5;;lsl;17;1;l;i;;m2i;r9;1;o2a;2;;n3y;ssp;;s9j;m;1;s;f;;vhg5;5x;1;oj;17;1;cd;3;;r1cb;bd4;5;aco;r;;e3v;h;;ih7;i;;l7m;1j;;o47;k;;s1szw;1ig;3; h;3f;;h1;9f;;u1bh;iv;1;rda;gs;2;eq;a;;pcd;gg;3;a3b;1y;;e7q;36;;ig;;;t33j;1ai;2;m;r;;ta;16b;;v3c;c;;w3e;d;1;a;7;;x;;b; 23;hw;;';6;;,1;c;;.2;a;;8o;47;;b5;f;;k;13;;l1;8;;md;x;1;a7;;;t;c;;y4y;e;1; ;a;;y6atn;ca;1;l1;c;;{6s;r;1;a;7;;|58;m;1;a1;b;;£6cs;8l;1;82b;6o;;À;9;;Áa;o;;Ä3;c;;Å2;k;;Æ4;k;;Éf;2q;;Ò;c;;Ó1;1d;;Öa;16;;Ü4;v;;à7;v;;á5;l;;æ1;m;;è;6;;é4c;bg;1;t3h;29;3;a4;1n;;o;a;;u1;b;;í;5;;ö2;e;;üd;r;1; 7;;;Ā1;b;;ā3;s;;ī;5;;İ4;o;;Ō3;o;;ō;2m;;œ;8;;Ω2;e;;α1c;c1;;ε5;1s;;ω7;1x;;ϵ;8;;е;5;;–3a;1k;2;e;a;;i;9;;ℓ;d;;";
-	var root = {};
-	function fill(prefix, node, dict) {
-		var a = dict.split(';', 3)
-			, n = a.map(function (x) { return parseInt(x, 36) || 0; });
-		node.data = {
-			aCount: n[0],
-			anCount: n[1],
-			prefix: prefix,
-			article: n[0] >= n[1] ? "a" : "an"
-		}
-		dict = dict.substr(1 + a.join(';').length);
-		for (var i = 0; i < n[2]; i++)
-			dict = fill(prefix + dict[0], node[dict[0]] = {}, dict.substr(1));
-		return dict;
-	}
-	fill("", root, dict);
-	return {
-		raw: root,
-		//Usage example: AvsAn.query("example ")
-		//Note that the terminal space indicates this is a complete word - this is sometimes significant, particularly for acronyms!
-		//returns: {
-		//   prefix: "e", //the prefix sufficient to determine the article
-		//   aCount: 9682, //the number of times "a" was seen for this prefix
-		//   anCount: 1028246, //the number of times "an" was seen for this prefix
-		//   article: "an", //the most common article
-		//}
-		query: function (word) {
-
-			var node = root, sI = 0, result, c;
-			do {
-				c = word[sI++];
-			} while ('"‘’“”$\'-('.indexOf(c) >= 0);//also terminates on end-of-string "undefined".
-
-			while (1) {
-				result = node.data || result;
-				node = node[c];
-				if (!node) return result;
-				c = word[sI++] || " ";
-			}
-		}
-	};
-})();
-
 function numberify(selector) {
 	$(() => Links.generateLinkNumbers($(selector)))
 	return "";
diff --git a/game/03-JavaScript/bedroomPills.js b/game/03-JavaScript/bedroomPills.js
index 097df37c4a..211bc1a351 100644
--- a/game/03-JavaScript/bedroomPills.js
+++ b/game/03-JavaScript/bedroomPills.js
@@ -81,7 +81,7 @@ setup.pills = [
 		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
 		icon: 'img/misc/icon/bottomBlocker.png',
 		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["bottom growth"].doseTaken === 0 && V.sexStats.pills["pills"]["bottom reduciton"].doseTaken === 0) ? 1 : 0},
+		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["bottom growth"].doseTaken === 0 && V.sexStats.pills["pills"]["bottom reduction"].doseTaken === 0) ? 1 : 0},
 		effects:[]
 	},
 	{
@@ -132,7 +132,7 @@ setup.pills = [
 		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
 		icon: 'img/misc/icon/breastBlocker.png',
 		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["breast growth"].doseTaken === 0 && V.sexStats.pills["pills"]["breast reduciton"].doseTaken === 0) ? 1 : 0},
+		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["breast growth"].doseTaken === 0 && V.sexStats.pills["pills"]["breast reduction"].doseTaken === 0) ? 1 : 0},
 		effects:[]
 	},
 	{
@@ -183,7 +183,7 @@ setup.pills = [
 		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
 		icon: 'img/misc/icon/penisBlocker.png',
 		display_condition: function(){return (V.player.penisExist && this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["penis growth"].doseTaken === 0 && V.sexStats.pills["pills"]["penis reduciton"].doseTaken === 0)},
+		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["penis growth"].doseTaken === 0 && V.sexStats.pills["pills"]["penis reduction"].doseTaken === 0)},
 		effects:[]
 	},
 	{
@@ -319,7 +319,7 @@ window.onHomePillItemClick = function(item_name) {
 					</div>
 				</div>
 				`
-				window.toggleWhatNeedsToBeToggled(item)
+				window.initPillContextButtons(item)
 				document.getElementById("hpi_desc_img").innerHTML = `<img` + ((item.shape == "galenic") ? ` style="margin-left: 17%;"` : "") + ` src="` + item.icon + `"></img>` +
 				`<div id="hpi_indicator" class="hpi_indicator"></div>`
 				window.addIndicators(item);
@@ -335,22 +335,30 @@ window.addIndicators = function(item){ // Indicators are the "++Control" and "+A
 	}
 }
 
-window.toggleWhatNeedsToBeToggled = function(item){
-	document.getElementById("hpi_take_every_morning").innerHTML = (item.autoTake()) ? "Stop taking them" : "Take every morning"
-	if (item.type == "asylum" || item.type == "harper"){
-		document.getElementById("hpi_take_every_morning").className = "hidden" // prevent from Take every Morning option to show for those type of pills
-		document.getElementById("hpi_take_pills").classList.add("hpi_take_me_single")
-	}
-	document.getElementById("hpi_take_pills").innerHTML = "Take pill"
-	if (document.getElementById("hpi_doseTaken") != undefined)
-		document.getElementById("hpi_doseTaken").outerHTML = `<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>` // Display today taken doses for specific pill
-	else
-		document.getElementById("hpi_take_pills").outerHTML += `<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>` // Display today taken doses for specific pill
-	if (item.take_condition() == 0){
-		document.getElementById("hpi_take_pills").classList.add("hpi_greyed_out")
-		document.getElementById("hpi_take_pills").onclick = "" // disable "Take Pill" button
-	}
-}
+window.initPillContextButtons = function(item){
+    // create button to "Take everyone morning" / "Stop taking them" (every morning)
+    document.getElementById("hpi_take_every_morning").innerHTML = (item.autoTake()) ? "Stop taking them" : "Take every morning"
+    
+    // special case if pill type is "asylum" or "harper"
+    if (item.type == "asylum" || item.type == "harper"){
+        document.getElementById("hpi_take_every_morning").className = "hidden" // prevent 'Take every Morning' option to be displayed for those type of pills
+        document.getElementById("hpi_take_pills").classList.add("hpi_take_me_single") // readapt css since there's only one button now
+    }
+    //  Add 'Take pill' button
+    document.getElementById("hpi_take_pills").innerHTML = "Take pill"
+
+    // If the button doesnt exist, create it. If it exists, display the right dose Taken for that pill
+    if (document.getElementById("hpi_doseTaken") != undefined)
+        document.getElementById("hpi_doseTaken").outerHTML = `<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>` // Display today taken doses for specific pill
+    else
+        document.getElementById("hpi_take_pills").outerHTML += `<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>` // Display today taken doses for specific pill
+    
+    // Check if the player meets the criteria to take the pill.
+    if (item.take_condition() == 0){
+        document.getElementById("hpi_take_pills").classList.add("hpi_greyed_out") // grey the "Take Pill" button out
+        document.getElementById("hpi_take_pills").onclick = "" // disable "Take Pill" onclick event.
+    }
+};
 
 window.setLastTaken = function(type, subtype, fullname=null) {
 	if (fullname != null){
@@ -436,7 +444,7 @@ window.onAutoTakeClick = function(item_name, item_type){
 	for (let item in setup.pills){
 		if (setup.pills[item].name == item_name){
 			V.sexStats.pills["pills"][item_name].autoTake = !V.sexStats.pills["pills"][item_name].autoTake // toggle auto take
-			window.toggleWhatNeedsToBeToggled(setup.pills[item]) // change "Take every morning" button to "Stop taking them"
+			window.initPillContextButtons(setup.pills[item]) // change "Take every morning" button to "Stop taking them"
 		}
 		else if (["breast", "penis", "bottom", "pregnancy"].includes(item_type) && setup.pills[item].type == item_type)
 			V.sexStats.pills["pills"][setup.pills[item].name].autoTake = false // disable auto takes for other similar pills(bottom/penis/breast etc)
@@ -605,4 +613,4 @@ window.resetMostTaken = function() {
 window.getAllPills = function () {
 	for (let item of Object.keys(V.sexStats.pills.pills))
 		V.sexStats.pills.pills[item].owned = 14
-}
\ No newline at end of file
+}
diff --git a/game/03-JavaScript/canvasmodel.js b/game/03-JavaScript/canvasmodel.js
index e3ad283fc7..4e5abaec34 100644
--- a/game/03-JavaScript/canvasmodel.js
+++ b/game/03-JavaScript/canvasmodel.js
@@ -32,17 +32,16 @@
 
 /**
  * @typedef {object} CanvasModelLayer
- *
  * @property {boolean} [show] Show this layer, default false (if no show:true or showfn present, needs explicit <<showlayer>>). Do not use undefined/null/0/"" to hide layer!
- * @property {string} [src] Image path. Either `src` or `srcfn` is required
- * @property {number} [z] Z-index (rendering order), higher=above, lower=below. Either `z` of `zfn` is required
- * @property {number} [alpha] Layer opacity, from 0 (invisible) to 1 (opaque, default)
- * @property {boolean} [desaturate] Convert image to grayscale (before recoloring), default false
- * @property {number} [brightness] Adjust brightness, from -1 to +1 (before recoloring), default 0
- * @property {number} [contrast] Adjust contrast (before recoloring), default 1
- * @property {string} [blendMode] Recoloring mode (see docs for globalCompositeOperation; "hard-light", "multiply" and "screen" ), default none
- * @property {string|object} [blend] Color for recoloring, CSS color string or gradient spec (see model.d.ts)
- * @property {string} [masksrc] Mask image path. If present, only parts where mask is opaque will be displayed
+ * @property {string} [src] Image path. Either `src` or `srcfn` is required.
+ * @property {number} [z] Z-index (rendering order), higher=above, lower=below. Either `z` of `zfn` is required.
+ * @property {number} [alpha] Layer opacity, from 0 (invisible) to 1 (opaque, default).
+ * @property {boolean} [desaturate] Convert image to grayscale (before recoloring), default false.
+ * @property {number} [brightness] Adjust brightness, from -1 to +1 (before recoloring), default 0.
+ * @property {number} [contrast] Adjust contrast (before recoloring), default 1.
+ * @property {string} [blendMode] Recoloring mode (see docs for globalCompositeOperation; "hard-light", "multiply" and "screen" ), default none.
+ * @property {string|object} [blend] Color for recoloring, CSS color string or gradient spec (see model.d.ts).
+ * @property {string} [masksrc] Mask image path. If present, only parts where mask is opaque will be displayed.
  * @property {string} [animation] Name of animation to apply, default none
  * @property {number} [frames] Frame numbers used to display static images, array of subsprite indices. For example, if model frame count is 6 but layer has only 3 subsprites, default frames would be [0, 0, 1, 1, 2, 2].
  * @property {string[]} [filters] Names of filters that should be applied to the layer; filters themselves are taken from model options
@@ -73,26 +72,26 @@
 
 /**
  * @typedef {object} CanvasModelOptions
- * @property {string} name Model name, for debugging
- * @property {number} width Frame width
- * @property {number} height Frame height
- * @property {number} frames Number of frames for CSS animation
- * @property {object<string,CanvasModelLayer>} layers Layers (by name)
- * @property {function} [generatedOptions] Function ()=>string[] names of generated options
- * @property {function} [defaultOptions] Function ()=>object returning default options
+ * @property {string} name Model name, for debugging.
+ * @property {number} width Frame width.
+ * @property {number} height Frame height.
+ * @property {number} frames Number of frames for CSS animation.
+ * @property {Object<string, CanvasModelLayer>} layers Layers (by name).
+ * @property {Function} [generatedOptions] Function ()=>string[] names of generated options.
+ * @property {Function} [defaultOptions] Function ()=>object returning default options.
  * @property {function} [preprocess] Preprocessing function (options)=>void to generate temp options
  */
 
 // Consider doing proper class inheritance
 /**
- * @property {string} name Model name, for debugging
- * @property {number} width Frame width
- * @property {number} height Frame height
- * @property {number} frames Number of frames for CSS animation
- * @property {function} defaultOptions Function ()=>object returning default options
- * @property {string[]} generatedOptions Names of generated options
- * @property {object<string,CanvasModelLayer>} layers Layers (by name)
- * @property {CanvasModelLayer[]} layerList Layers
+ * @property {string} name Model name, for debugging.
+ * @property {number} width Frame width.
+ * @property {number} height Frame height.
+ * @property {number} frames Number of frames for CSS animation.
+ * @property {Function} defaultOptions Function ()=>object returning default options.
+ * @property {string[]} generatedOptions Names of generated options.
+ * @property {Object<string, CanvasModelLayer>} layers Layers (by name).
+ * @property {CanvasModelLayer[]} layerList Layers.
  * @property {CanvasRenderingContext2D} canvas
  */
 window.CanvasModel = class CanvasModel {
@@ -104,22 +103,22 @@ window.CanvasModel = class CanvasModel {
 		this.width = options.width;
 		this.height = options.height;
 		this.frames = options.frames || 1;
-		if ('generatedOptions' in options) this.generatedOptions = options.generatedOptions;
-		if ('defaultOptions' in options) this.defaultOptions = options.defaultOptions;
-		if ('preprocess' in options) this.preprocess = options.preprocess;
+		if ("generatedOptions" in options) this.generatedOptions = options.generatedOptions;
+		if ("defaultOptions" in options) this.defaultOptions = options.defaultOptions;
+		if ("preprocess" in options) this.preprocess = options.preprocess;
 		this.layers = clone(options.layers);
-		for (let name in this.layers) {
-			if (!this.layers.hasOwnProperty(name)) continue;
-			let layer = this.layers[name];
+		for (const name in this.layers) {
+			if (!Object.hasOwn(this.layers, name)) continue;
+			const layer = this.layers[name];
 			layer.name = name;
 			assignDefaults(layer, {
 				show: false, // By default, all layers have to be enabled manually
 				brightness: 0.0,
 				contrast: 1.0,
-				blend: '',
-				blendMode: '',
+				blend: "",
+				blendMode: "",
 				alpha: 1.0,
-				desaturate: false
+				desaturate: false,
 			});
 			layer.defaultOptions = clone(layer); // deep copy
 		}
@@ -138,8 +137,8 @@ window.CanvasModel = class CanvasModel {
 
 	defaultOptions() {
 		return {
-			filters: {}
-		}
+			filters: {},
+		};
 	}
 
 	createCanvas(cssAnimated) {
@@ -148,23 +147,23 @@ window.CanvasModel = class CanvasModel {
 
 	reset() {
 		this.options = {};
-		for (let layer of this.layerList) {
+		for (const layer of this.layerList) {
 			// Reset options
 			jQuery.extend(true, layer, layer.defaultOptions);
 		}
 	}
 
 	showLayer(name, filters) {
-		let layer = this.layers[name];
+		const layer = this.layers[name];
 		if (!layer) {
 			console.error("Layer not found: " + this.name + "/" + name);
 			return;
 		}
 		layer.show = true;
-		for (let filter of filters) {
+		for (const filter of filters) {
 			if (filter === null || filter === undefined) continue; // null & undefined are allowed as "empty filter"
-			if (typeof filter !== 'object') {
-				console.error("Invalid layer " + name + " filter " + typeof (filter), filter);
+			if (typeof filter !== "object") {
+				console.error("Invalid layer " + name + " filter " + typeof filter, filter);
 				continue;
 			}
 			Object.assign(layer, filter);
@@ -172,12 +171,13 @@ window.CanvasModel = class CanvasModel {
 	}
 
 	/**
-	 * Update layers according to options and render them as static image
-	 * @param {CanvasRenderingContext2D} canvas Canvas to render on (can be created with {@link createCanvas})
-	 * @param {object} options Options to use when rendering model
-	 * @param [listener] Listener for Renderer events
+	 * Update layers according to options and render them as static image.
+	 *
+	 * @param {CanvasRenderingContext2D} canvas Canvas to render on (can be created with {@link createCanvas}).
+	 * @param {object} options Options to use when rendering model.
+	 * @param [listener] Listener for Renderer events.
 	 */
-	render(canvas,options,listener) {
+	render(canvas, options, listener) {
 		if (typeof options === "undefined") options = this.options;
 		this.canvas = canvas;
 		this.options = options;
@@ -187,11 +187,12 @@ window.CanvasModel = class CanvasModel {
 	}
 
 	/**
-	 * Update layers according to options and animate them
-	 * @param {CanvasRenderingContext2D} canvas Canvas to render on (can be created with {@link createCanvas})
-	 * @param {object} options Options to use when rendering model
-	 * @param [listener] Listener for Renderer events
-	 * @return {AnimatingCanvas} AnimatingCanvas object
+	 * Update layers according to options and animate them.
+	 *
+	 * @param {CanvasRenderingContext2D} canvas Canvas to render on (can be created with {@link createCanvas}).
+	 * @param {object} options Options to use when rendering model.
+	 * @param [listener] Listener for Renderer events.
+	 * @returns {AnimatingCanvas} AnimatingCanvas object.
 	 */
 	animate(canvas, options, listener) {
 		this.canvas = canvas;
@@ -202,51 +203,56 @@ window.CanvasModel = class CanvasModel {
 	}
 
 	/**
-	 * Redraw the model onto same canvas
+	 * Redraw the model onto same canvas.
 	 */
 	redraw() {
 		if (!this.canvas) {
-			Errors.report("CanvasModel.redraw() called but model was never rendered!")
+			Errors.report("CanvasModel.redraw() called but model was never rendered!");
 			return;
 		}
 		Renderer.lastModel = this;
 		if (this.animated) {
-			return Renderer.animateLayers(this.canvas,
+			return Renderer.animateLayers(
+				this.canvas,
 				this.compile(this.options),
 				this.listener,
-				true);
+				true
+			);
 		} else {
-			return Renderer.composeLayers(this.canvas,
+			return Renderer.composeLayers(
+				this.canvas,
 				this.compile(this.options),
-				this.canvas.canvas.width/this.width,
-				this.listener);
+				this.canvas.canvas.width / this.width,
+				this.listener
+			);
 		}
 	}
 
 	/**
 	 * Pre-process options. Typically you calculate some expression here and store them as generated options
 	 * Override in subclass.
-	 * @param options Model options
+	 *
+	 * @param options Model options.
 	 */
-	preprocess(options) {
-	}
+	preprocess(options) {}
 
 	/**
-	 * Compile list of layers according to options
-	 * @param options Model options
-	 * @return {CompositeLayerSpec[]} layers
+	 * Compile list of layers according to options.
+	 *
+	 * @param options Model options.
+	 * @returns {CompositeLayerSpec[]} Layers.
 	 */
 	compile(options) {
 		const debug = V.debug;
-		if (!options) options = {filters: {}};
-		if (!('filters' in options)) options.filters = {};
+		if (!options) options = { filters: {} };
+		if (!("filters" in options)) options.filters = {};
 		try {
 			this.preprocess(options);
 		} catch (e) {
 			console.error(e);
-			throw "Error in model preprocessing: "+e.stack
+			throw new Error("Error in model preprocessing: " + e.stack);
 		}
-		for (let layer of this.layerList) {
+		for (const layer of this.layerList) {
 			// Reset some options
 			layer.brightness = layer.defaultOptions.brightness;
 			layer.contrast = layer.defaultOptions.contrast;
@@ -267,27 +273,30 @@ window.CanvasModel = class CanvasModel {
 				// This is why we eval all properties in debug mode, but ignore their errors
 				return;
 			}
-			let fnkey = propname + "fn";
+			const fnkey = propname + "fn";
 			if (fnkey in layer) {
 				try {
 					layer[propname] = layer[fnkey](options);
 				} catch (e) {
 					if (layer.show) {
-						console.error("Error evaluating layer " + layer.name + " property " + propname,)
+						console.error(
+							"Error evaluating layer " + layer.name + " property " + propname
+						);
 					}
 				}
 			}
 		}
 
-		for (let layer of this.layerList) {
+		for (const layer of this.layerList) {
 			propeval(layer, "show");
 			propeval(layer, "src");
 			if (!layer.src) {
-				layer.src = ''; // force string value
+				layer.src = ""; // force string value
 				layer.show = false;
 			}
 			propeval(layer, "z");
-			if (typeof layer.z !== 'number' && layer.show !== false) console.error("Layer " + layer.name + " missing property z");
+			if (typeof layer.z !== "number" && layer.show !== false)
+				console.error("Layer " + layer.name + " missing property z");
 			propeval(layer, "alpha");
 			propeval(layer, "blendMode");
 			propeval(layer, "blend");
@@ -302,8 +311,8 @@ window.CanvasModel = class CanvasModel {
 			propeval(layer, "width");
 			propeval(layer, "height");
 			if (layer.show !== false && layer.filters) {
-				for (let filterName of layer.filters) {
-					let filter = options.filters[filterName];
+				for (const filterName of layer.filters) {
+					const filter = options.filters[filterName];
 					if (!filter) {
 						// console.warn("Layer " + layer.name + " needs filter " + filterName + " but it is not provided");
 						continue;
@@ -314,27 +323,28 @@ window.CanvasModel = class CanvasModel {
 		}
 		return this.layerList;
 	}
-}
+};
 
 /**
- * @type {object<string,CanvasModelOptions>}
+ * @type {Object<string, CanvasModelOptions>}
  */
-Renderer.CanvasModels = {}
+Renderer.CanvasModels = {};
 /**
- * @type {object<string,object<string,CanvasModel>>}
+ * @type {Object<string, Object<string, CanvasModel>>}
  */
-Renderer.CanvasModelCaches = {}
+Renderer.CanvasModelCaches = {};
 /**
  * Find or create new CanvasModel.
- * @param {string} modelName CanvasModel name in Renderer.CanvasModels
+ *
+ * @param {string} modelName CanvasModel name in Renderer.CanvasModels.
  * @param {string} [slot] Cache id to speed up rendering between passages.
- * @return {CanvasModel}
+ * @returns {CanvasModel}
  */
-Renderer.locateModel = function(modelName, slot) {
-	let options = Renderer.CanvasModels[modelName];
+Renderer.locateModel = function (modelName, slot) {
+	const options = Renderer.CanvasModels[modelName];
 	if (!options) {
-		Errors.report("Requested non-existing model "+modelName);
-		return new CanvasModel({name:"empty",width:1,height:1,layers:{}});
+		Errors.report("Requested non-existing model " + modelName);
+		return new CanvasModel({ name: "empty", width: 1, height: 1, layers: {} });
 	}
 	if (!slot) {
 		return new CanvasModel(options);
@@ -350,5 +360,4 @@ Renderer.locateModel = function(modelName, slot) {
 		cache[slot] = model;
 		return model;
 	}
-}
-
+};
diff --git a/game/03-JavaScript/eyesRelated.js b/game/03-JavaScript/eyesRelated.js
index b310f1b802..376c2197d2 100644
--- a/game/03-JavaScript/eyesRelated.js
+++ b/game/03-JavaScript/eyesRelated.js
@@ -6,17 +6,17 @@ function buildEyeDetails() {
 
 	if (lenses.right !== 0 || lenses.left !== 0) {
 		sentence += "You wear ";
-		if (typeof lenses.left === 'string') {
+		if (typeof lenses.left === "string") {
 			sentence += setup.colours.eyes_map[lenses.left].name;
 			concatFlag = true;
 		}
-		if (typeof lenses.right === 'string') {
-			if (concatFlag) sentence += ' and ';
+		if (typeof lenses.right === "string") {
+			if (concatFlag) sentence += " and ";
 			sentence += setup.colours.eyes_map[lenses.right].name;
 			concatFlag = true;
 		}
 		if (concatFlag) {
-			sentence += ' eye lenses ';
+			sentence += " eye lenses ";
 		}
 		sentence += "on top of your ";
 	} else {
@@ -26,36 +26,37 @@ function buildEyeDetails() {
 
 	const leftEyeColour = colourMap[V.leftEyeColour];
 	const rightEyeColour = colourMap[V.rightEyeColour];
-	if (typeof leftEyeColour === 'object') {
+	if (typeof leftEyeColour === "object") {
 		sentence += leftEyeColour.name;
 		concatFlag = true;
 	}
-	if (typeof rightEyeColour === 'object' && V.leftEyeColour !== V.rightEyeColour) {
-		if (concatFlag) sentence += ' and ';
+	if (typeof rightEyeColour === "object" && V.leftEyeColour !== V.rightEyeColour) {
+		if (concatFlag) sentence += " and ";
 		sentence += rightEyeColour.name;
 		concatFlag = true;
 	}
-	if (concatFlag) sentence += ' eyes';
-	return sentence += '.';
+	if (concatFlag) sentence += " eyes";
+	return sentence + ".";
 }
 window.buildEyeDetails = buildEyeDetails;
 
 /**
  * Attempts to extrapolate $eyecolour and $makeup.lenses into distinct units.
  * $makeup.lenses gets turned into an object { left : 0, right : 0 }, where the values are 0 or a string.
- * $eyecolour gets assigned to both $leftEyeColour and $rightEyeColour
- * @returns Nothing
+ * $eyecolour gets assigned to both $leftEyeColour and $rightEyeColour.
  */
 function restructureEyeColourVariable() {
 	if (V.objectVersion.eyeRepair === undefined) {
 		V.objectVersion.eyeRepair = 0;
 	}
+
 	switch (V.objectVersion.eyeRepair) {
-		case 0:
+		case 0: {
 			/* Both $leftEyeColour and $rightEyeColour should be the original colours for a character's eyes.
 				This function below sets it to $eyecolour, if that fails, $eyeselect, then defaults to purple, the default.
 				For it to fail, it must be undefined, it is unlikely that $eyeselect is undefined, but it's likely possible. */
-			const getColour = () => (typeof V.eyecolour === 'string' ? V.eyecolour : V.eyeselect) || 'purple';
+			const getColour = () =>
+				(typeof V.eyecolour === "string" ? V.eyecolour : V.eyeselect) || "purple";
 			if (!V.leftEyeColour) {
 				V.leftEyeColour = getColour();
 			}
@@ -63,182 +64,201 @@ function restructureEyeColourVariable() {
 				V.rightEyeColour = getColour();
 			}
 			delete V.eyecolour;
+			V.objectVersion.eyeRepair = 1;
+		}
+		/* falls through */
 		case 1:
-			if (V.makeup == undefined) return;
-			const lenses = V.makeup.eyelenses;
-			/* If the lens variable is a string or number, we need to generate an object, with the value appended to both .right and .left
-				As the heterochromia introduced forces us to define both eye colours. */
-			if (typeof lenses === 'string' || typeof lenses === 'number') {
-				V.makeup.eyelenses = {
-					'left' : lenses,
-					'right' : lenses
-				};
-			/* Captures at least partially correct forms, that may have been generated over time, as well as the correct objects. */
-			} else if (lenses !== null && typeof lenses === 'object') {
-				/* If the properties of the lenses aren't the right typing at all, default them to 0. */
-				if (typeof lenses.left !== 'string' && lenses.left !== 0) {
-					lenses.left = 0;
-				}
-				if (typeof lenses.right !== 'string' && lenses.right !== 0) {
-					lenses.right = 0;
-				}
-			} else {
-				/* Finally, if the lens object is beyond repair, we create it anew. */
-				V.makeup.eyelenses = {
-					'left' : 0,
-					'right' : 0
-				};
-			}
-			V.objectVersion.eyeRepair = 2;
-			break;
-		case 2:	
-			/* If $makeup.eyelenses is not an object/is null. Of if it is, but left/right properties are undefined, rebuild it properly. */
-			if (V.makeup.eyelenses == null || typeof V.makeup.eyelenses !== 'object' || V.makeup.eyelenses.left == undefined || V.makeup.eyelenses.left == undefined) {
+		case 2:
+		case 3: {
+			if (!V.makeup) return; /* back out if makeup broken */
+
+			let lenses = V.makeup.eyelenses;
+			/* If lenses is not string object or number, or null, it's bad and we hard set */
+			if (!["string", "object", "number"].includes(typeof lenses) || !lenses)
+				V.makeup.eyelenses = { left: 0, right: 0 };
+			else if (typeof lenses !== "object") {
+				/* String or Number so we assign in to new object */
 				V.makeup.eyelenses = {
-					'left' : 0,
-					'right' : 0
+					left: lenses,
+					right: lenses,
 				};
 			}
-			V.objectVersion.eyeRepair = 3;
+			lenses = V.makeup.eyelenses;
+			/* object - reassign and fix number if needed */
+			if (typeof lenses.left === "number") lenses.left = 0;
+			if (typeof lenses.right === "number") lenses.right = 0;
+			V.objectVersion.eyeRepair = 4;
 			break;
+		}
 	}
 }
 window.restructureEyeColourVariable = restructureEyeColourVariable;
 
-window.patchCorruptLensesColors = function() {
-	if (V.custom_eyecolours != undefined){
-		for (let index in V.custom_eyecolours)
-			V.custom_eyecolours[index].canvasfilter.blend = window.colorNameTranslate(V.custom_eyecolours[index].variable, "hex")
+window.patchCorruptLensesColors = function () {
+	if (V.custom_eyecolours != null) {
+		for (const index in V.custom_eyecolours)
+			V.custom_eyecolours[index].canvasfilter.blend = window.colorNameTranslate(
+				V.custom_eyecolours[index].variable,
+				"hex"
+			);
 	}
-}
+};
 
-window.initCustomLenses = function (){ // push custom eye_colours into setup.colours.eyes and sync eye colour map
+function initCustomLenses() {
+	/* push custom eye_colours into setup.colours.eyes and sync eye colour map */
 	let found, i, i2;
-	for (i in V.custom_eyecolours){
-	found = 0;
-		for (i2 in setup.colours.eyes){
-			if (setup.colours.eyes[i2].variable == V.custom_eyecolours[i].variable)
-				found = 1;
+	for (i in V.custom_eyecolours) {
+		found = 0;
+		for (i2 in setup.colours.eyes) {
+			if (setup.colours.eyes[i2].variable === V.custom_eyecolours[i].variable) found = 1;
 		}
-		if (found != 1)
-			setup.colours.eyes.push(V.custom_eyecolours[i])
+		if (!found) setup.colours.eyes.push(V.custom_eyecolours[i]);
 	}
-	window.buildColourMap("eyes", "custom_eyecolours")
+	window.buildColourMap("eyes", "custom_eyecolours");
 }
+window.initCustomLenses = initCustomLenses;
 
 function hexToRgbArray(hex) {
-	var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
-	return result ? [
-	  parseInt(result[1], 16),
-	  parseInt(result[2], 16),
-	  parseInt(result[3], 16)
-	] : null;
+	const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+	return result
+		? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]
+		: null;
 }
 
 function ColorToHex(color) {
-	var hexadecimal = color.toString(16);
-	return hexadecimal.length == 1 ? "0" + hexadecimal : hexadecimal;
+	const hexadecimal = color.toString(16);
+	return hexadecimal.length === 1 ? "0" + hexadecimal : hexadecimal;
 }
 
-window.eyeColorGradiant = function (rgb_beginning, rgb_end, p){ // rgb can be RGB value in an array, or hex value in string
-	let w = p * 2 - 1;
-	let w1 = (w + 1) / 2.0;
-	let w2 = 1 - w1;
-	let rgb, rgb_hex;
-
-	if (typeof rgb_beginning == "string" && rgb_beginning[0] == "#")
-		rgb_beginning = hexToRgbArray(rgb_beginning)
-	if (typeof rgb_end == "string" && rgb_end[0] == "#")
-		rgb_end = hexToRgbArray(rgb_end)
-	rgb = [ parseInt(rgb_beginning[0] * w2 + rgb_end[0] * w1),
-			parseInt(rgb_beginning[1] * w2 + rgb_end[1] * w1),
-		   	parseInt(rgb_beginning[2] * w2 + rgb_end[2] * w1)];
-	rgb_hex = "#" + ColorToHex(rgb[0]) + ColorToHex(rgb[1]) + ColorToHex(rgb[2])
-	return rgb_hex;
-}
+const eyeColourGradient = function (rgbBegin, rgbEnd, p) {
+	/* rgb can be RGB value in an array, or hex value in string */
+	const w = p * 2 - 1;
+	const w1 = (w + 1) / 2.0;
+	const w2 = 1 - w1;
+
+	if (typeof rgbBegin === "string" && rgbBegin[0] === "#") rgbBegin = hexToRgbArray(rgbBegin);
+	if (typeof rgbEnd === "string" && rgbEnd[0] === "#") rgbEnd = hexToRgbArray(rgbEnd);
+	const rgb = [
+		parseInt(rgbBegin[0] * w2 + rgbEnd[0] * w1),
+		parseInt(rgbBegin[1] * w2 + rgbEnd[1] * w1),
+		parseInt(rgbBegin[2] * w2 + rgbEnd[2] * w1),
+	];
+	return "#" + ColorToHex(rgb[0]) + ColorToHex(rgb[1]) + ColorToHex(rgb[2]);
+};
 
 /* Randomize array in-place using Durstenfeld shuffle algorithm */
 function shuffleArray(array) {
-	for (var i = array.length - 1; i > 0; i--) {
-		var j = Math.floor(Math.random() * (i + 1));
-		var temp = array[i];
+	for (let i = array.length - 1; i > 0; i--) {
+		const j = Math.floor(Math.random() * (i + 1));
+		const temp = array[i];
 		array[i] = array[j];
 		array[j] = temp;
 	}
 	return array;
 }
 
-var green = "#36f029"
-var yellow = "#fbff26"
-var blue = "#26ccff"
-var orange = "#f59b25"
-
-window.determineCatEyeStages = function () { // to change the amount of changes, you only need to change the stages variable. same for target_colours
-	let target_colours = shuffleArray([green, yellow, blue, orange]) // can add or edit colours
-	let stages = 4; // amount of stages we'll have before reaching final colour
-	let total_percentage = 0.5 + (Math.random() / 4) // Represent how much of the targeted_colour, the current eye_colours will need to adapt into. 0-1 value, where 1 == 100%;
-	var index = 0;
-	let base_colour = [setup.colours.eyes_map[V.leftEyeColour].canvasfilter.blend, setup.colours.eyes_map[V.rightEyeColour].canvasfilter.blend] // base eye colours [left, right]
-
-	for(let i = target_colours.length-1; i>=2; i--) // only keep two colours, randomly chosen
-		target_colours.splice(Math.floor(Math.random()*target_colours.length), 1);
-	if (V.rightEyeColour == "light blue" && target_colours[1] == blue) // right eye is the one we see the most. if this eye is light blue, and the target_colour is also blue, player might not see a difference and that would be a shame.
-		target_colours = [target_colours[1], target_colours[0]]		   // So we swap left/right eye colours.
-	index = 0
-	while (index++ < stages){
-		let eyes_result = [window.eyeColorGradiant(base_colour[0], target_colours[0], (total_percentage / stages) * index), // left eye
-						   window.eyeColorGradiant(base_colour[1], target_colours[1], (total_percentage / stages) * index)] // right eye
-		for (let i in eyes_result){
-			let colour_name = window.colorNamer(eyes_result[i])
-			let colour_object = {
-				variable: "cat_tf_stage_"+(index-1)+(i == 0 ? "_left" : "_right"),
-				name: window.colorNameTranslate(colour_name, "spaced name"),
-				name_cap: window.colorNameTranslate(colour_name, "spaced name").toUpperFirst(),
-				csstext: colour_name,
+window.determineCatEyeStages = function () {
+	/* to change the amount of changes, you only need to change the stages variable.
+	same for targetColours */
+	const green = "#36f029";
+	const yellow = "#fbff26";
+	const blue = "#26ccff";
+	const orange = "#f59b25";
+
+	const stages = 4; // amount of stages we'll have before reaching final colour
+	const totalPercentage = 0.5 + Math.random() / 4;
+	/* How much of targetColour the current eye colour needs to adapt into.
+	0.0 to 1.0 (0%-100%) */
+	const baseColour = [
+		setup.colours.eyes_map[V.leftEyeColour].canvasfilter.blend,
+		setup.colours.eyes_map[V.rightEyeColour].canvasfilter.blend,
+	]; // base eye colours [left, right]
+
+	let targetColours = shuffleArray([green, yellow, blue, orange]); // can add or edit colours
+	/* We've already shuffled these so they're already random */
+	targetColours.splice(-2); /* keep the last 2 */
+
+	/* The right eye is the one we see the most.
+	   If this eye is light blue and the target colour is blue, the player
+	   might not notice a difference.  So, swap the two eyes */
+	if (V.rightEyeColour === "light blue" && targetColours[1] === blue)
+		targetColours = [targetColours[1], targetColours[0]];
+	for (let index = 0; index < stages; index++) {
+		const eyesResult = {
+			left: eyeColourGradient(
+				baseColour[0],
+				targetColours[0],
+				(totalPercentage / stages) * index
+			), // left eye
+			right: eyeColourGradient(
+				baseColour[1],
+				targetColours[1],
+				(totalPercentage / stages) * index
+			), // right eye
+		};
+		/* i goes between "left" and "right" here with these keys */
+		for (const i in eyesResult) {
+			const colourName = window.colorNamer(eyesResult[i]);
+			const colourObject = {
+				variable: "cat_tf_stage_" + (index - 1) + "_" + i,
+				name: window.colorNameTranslate(colourName, "spaced name"),
+				name_cap: window.colorNameTranslate(colourName, "spaced name").toUpperFirst(),
+				csstext: colourName,
 				natural: true,
 				lens: false,
 				canvasfilter: {
-					blend: eyes_result[i],
-					brightness: 0.27
-				}
-			}
-			for (let x in V.custom_eyecolours){ // create new object for our new colour eye
-				if (V.custom_eyecolours[x].variable == "cat_tf_stage_"+(index-1)+(i == 0 ? "_left" : "_right"))
-					V.custom_eyecolours[x] = colour_object
-				else if (x == V.custom_eyecolours.length - 1)
-					V.custom_eyecolours.push(colour_object)
+					blend: eyesResult[i],
+					brightness: 0.27,
+				},
+			};
+			for (const x in V.custom_eyecolours) {
+				/* create new object for our new colour eye */
+				/* again, 'i' is either "left" or "right" here */
+				if (V.custom_eyecolours[x].variable === "cat_tf_stage_" + (index - 1) + "_" + i)
+					V.custom_eyecolours[x] = colourObject;
+				else if (x === V.custom_eyecolours.length - 1)
+					V.custom_eyecolours.push(colourObject);
 			}
-			if (V.custom_eyecolours.length == 0)
-				V.custom_eyecolours.push(colour_object)
+			if (V.custom_eyecolours.length === 0) V.custom_eyecolours.push(colourObject);
 		}
 	}
-	window.initCustomLenses() // sync new eye colours
-}
+	initCustomLenses(); // sync new eye colours
+};
 
-window.defineCustomEyeColourStyle = function() {
-	var normal_eyes = {left:V.leftEyeColour, right:V.rightEyeColour};
-	for (var side of ["left", "right"]){
-		if (V.makeup.eyelenses[side] != 0){ // custom eyes colours
-			let colour_array = (V.makeup.eyelenses[side].includes("colorWheelTemporary") ? setup.colours.eyes : V.custom_eyecolours)
-			for (let colour of colour_array){
-				if (colour.variable == V.makeup.eyelenses[side]){
-					if (side == "left")
-						T.custom_eyelenses_left_style = "filter: " + (V.makeup.eyelenses[side].includes("colorWheelTemporary") ? window.colorNameTranslate(colour.csstext, "hue") : window.colorNameTranslate(V.makeup.eyelenses[side], "hue"))
-					else
-						T.custom_eyelenses_right_style = "filter: " + (V.makeup.eyelenses[side].includes("colorWheelTemporary") ? window.colorNameTranslate(colour.csstext, "hue") : window.colorNameTranslate(V.makeup.eyelenses[side], "hue"))
-				}
+window.defineCustomEyeColourStyle = function () {
+	const normalEyes = { left: V.leftEyeColour, right: V.rightEyeColour };
+	for (const side of ["left", "right"]) {
+		/* This code constructs _custom_eyelenses_left_style / right_style */
+		const varSideStyle = "custom_eyelenses_" + side + "_style";
+
+		if (V.makeup.eyelenses[side] !== 0) {
+			/* custom eyes colours */
+			const colourArray = V.makeup.eyelenses[side].includes("colorWheelTemporary")
+				? setup.colours.eyes
+				: V.custom_eyecolours;
+			for (const colour of colourArray) {
+				/* this does this for left and right */
+				if (colour.variable === V.makeup.eyelenses[side])
+					T[varSideStyle] =
+						"filter: " +
+						(V.makeup.eyelenses[side].includes("colorWheelTemporary")
+							? window.colorNameTranslate(colour.csstext, "hue")
+							: window.colorNameTranslate(V.makeup.eyelenses[side], "hue"));
 			}
-		}
-		else if (normal_eyes[side] != 0 && (normal_eyes[side].includes("colorWheelTemporary") == true || normal_eyes[side].includes("cat_tf_stage") == true)){ // normal eyes colours
-			let colour_array = (normal_eyes[side].includes("cat_tf_stage") == true ? V.custom_eyecolours : setup.colours.eyes)
-			for (let colour of colour_array){
-				if (colour.variable == normal_eyes[side]){
-					if (side == "left")
-						T.custom_eyelenses_left_style = "filter: " + window.colorNameTranslate(colour.csstext, "hue")
-					else
-						T.custom_eyelenses_right_style = "filter: " + window.colorNameTranslate(colour.csstext, "hue")
-				}
+		} else if (
+			normalEyes[side] !== 0 &&
+			(normalEyes[side].includes("colorWheelTemporary") ||
+				normalEyes[side].includes("cat_tf_stage"))
+		) {
+			// normal eyes colours
+			const colourArray = normalEyes[side].includes("cat_tf_stage")
+				? V.custom_eyecolours
+				: setup.colours.eyes;
+			for (const colour of colourArray) {
+				/* this does this for left and right */
+				if (colour.variable === normalEyes[side])
+					T[varSideStyle] = "filter: " + window.colorNameTranslate(colour.csstext, "hue");
 			}
 		}
 	}
-}
\ No newline at end of file
+};
diff --git a/game/03-JavaScript/save.js b/game/03-JavaScript/save.js
index 49847708bd..dd67e6ee1c 100644
--- a/game/03-JavaScript/save.js
+++ b/game/03-JavaScript/save.js
@@ -510,8 +510,16 @@ const importSettingsData = function (data) {
 			const listKey = Object.keys(listObject);
 			const namedObjects = ["map", "skinColor", "shopDefaults"];
 			// correct swapped min/max values
-			if (S.general.breastsizemin > S.general.breastsizemax){let temp = S.general.breastsizemin; S.general.breastsizemin = S.general.breastsizemax, S.general.breastsizemax = temp};
-			if (S.general.penissizemin > S.general.penissizemax){let temp = S.general.penissizemin; S.general.penissizemin = S.general.penissizemax, S.general.penissizemax = temp};
+			if (S.general.breastsizemin > S.general.breastsizemax) {
+				const temp = S.general.breastsizemin;
+				S.general.breastsizemin = S.general.breastsizemax;
+				S.general.breastsizemax = temp;
+			}
+			if (S.general.penissizemin > S.general.penissizemax) {
+				const temp = S.general.penissizemin;
+				S.general.penissizemin = S.general.penissizemax;
+				S.general.penissizemax = temp;
+			}
 
 			for (let i = 0; i < listKey.length; i++) {
 				if (namedObjects.includes(listKey[i]) && S.general[listKey[i]] != null) {
diff --git a/game/04-Variables/variables-start.twee b/game/04-Variables/variables-start.twee
index 3817df13dc..c22d50533b 100644
--- a/game/04-Variables/variables-start.twee
+++ b/game/04-Variables/variables-start.twee
@@ -84,7 +84,6 @@
 <<set $trauma to 0>>
 <<set $traumamax to 5000>>
 <<set $stressmax to 10000>>
-<<set $tirednessmax to 2000>>
 <<set $arousalmax to 10000>>
 <<set $physique to 3500>>
 <<set $physiquemax to 20000>>
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index ff151272f3..b1a8b1cabb 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -3645,6 +3645,17 @@
 		<<unset $crimemax>>
 	<</if>>
 
+	<!-- v0.3.11.4 creampie.npc.penis and tentacle fix -->
+	<!-- IMPORTANT NOTE: please REMOVE this section if these stats come back into use -->
+	<<if _version lte 31104>>
+		<<run delete $sexStats.creampie.npc.penis>>
+		<<run delete $sexStats.creampie.npc.tentacle>>
+	<</if>>
+
+	<!-- v0.3.11.4 $tirednessmax change to C.tiredness.max -->
+	<<if $tirednessmax>>
+		<<unset $tirednessmax>>
+	<</if>>
 	<!-- v0.3.11.4 - Add $makeup.mascara_running -->
 	<<if $makeup.mascara_running is undefined>>
 		<<set $makeup.mascara_running = 0>>
diff --git a/game/base-clothing/canvasmodel-img.twee b/game/base-clothing/canvasmodel-img.twee
index 9e42868ff4..1e78381497 100644
--- a/game/base-clothing/canvasmodel-img.twee
+++ b/game/base-clothing/canvasmodel-img.twee
@@ -267,8 +267,8 @@ if ($skinColor.tanningEnabled is true){
 	<<set _modeloptions.trauma to $trauma gte ($traumamax * 0.9)>>
 <</if>>
 <<set _modeloptions.blink to $blinkingdisable is "f">>
-<<set _modeloptions.eyes_bloodshot to $pain gte 100 and $willpowerpain is 0 or $tiredness >= $tirednessmax>>
-<<set _modeloptions.eyes_half to $halfcloseddisable isnot "t" and ($arousal gte ($arousalmax / 5) * 4 or $orgasmdown gte 1) and $trauma lt ($traumamax * 0.9) and $pain lt 60 and $eyelidTEST is true or ($possessed or $tiredness >= $tirednessmax * 0.75)>>
+<<set _modeloptions.eyes_bloodshot to $pain gte 100 and $willpowerpain is 0 or $tiredness >= C.tiredness.max>>
+<<set _modeloptions.eyes_half to $halfcloseddisable isnot "t" and ($arousal gte ($arousalmax / 5) * 4 or $orgasmdown gte 1) and $trauma lt ($traumamax * 0.9) and $pain lt 60 and $eyelidTEST is true or ($possessed or $tiredness >= C.tiredness.max * 0.75)>>
 
 <!-- Brows -->
 <<if $trauma gte $traumamax or $possessed>>
diff --git a/game/base-combat/audience.twee b/game/base-combat/audience.twee
index abf0abeb76..0895c94ccd 100644
--- a/game/base-combat/audience.twee
+++ b/game/base-combat/audience.twee
@@ -443,7 +443,7 @@
 			<<elseif $mouthactiondefault is "analkiss">>
 				<<switch random(2)>>
 					<<case 0>>
-						"Kissing ass made <<pher>> cum. What a submissive <<slut>>."
+						"Kissing ass made <<phim>> cum. What a submissive <<slut>>."
 					<<case 1>>
 						"Cumming just from kissing ass? You were made to do that, bitch!"
 					<<case 2>>
@@ -686,7 +686,7 @@
 				<<elseif $rng gte 33>>
 					"That sleek chest of yours is a thing of beauty."
 				<<elseif $rng gte 20 and $anusdoubletarget isnot undefined and $NPCList[$anustarget].penis is "anusdouble" and $NPCList[$anusdoubletarget].penis is "anusdouble">>
-					"<<pHer>> hard nipples tell all. This boy loves two hard cocks up the ass!"
+					"<<pHer>> hard nipples tell all. This <<girl>> loves two hard cocks up the ass!"
 				<<else>>
 					"Don't be shy, there's nothing lewd about your boy nipples."
 				<</if>>
@@ -988,13 +988,13 @@
 	<<if $vaginastate is "penetrated">>
 		<<if $enemytype is "beast">>
 			<<if $orgasmdown gte 1>>
-				"I got a nice shot of <<pher>> shuddering on that dick."
+				"I got a nice shot of <<phim>> shuddering on that dick."
 			<<else>>
 				"Wow, <<pher>> pussy is really getting pounded by that <<beasttype>>."
 			<</if>>
 		<<else>>
 			<<if $orgasmdown gte 1>>
-				"I got a nice shot of <<pher>> shuddering on that dick."
+				"I got a nice shot of <<phim>> shuddering on that dick."
 			<<else>>
 				"Wow, <<pher>> pussy is really getting a pounding."
 			<</if>>
@@ -1145,9 +1145,9 @@
 		<<if $rng lt 34>>
 			"Look at this <<bitch>> getting <<pherself>> off!"
 		<<elseif $rng lte 67>>
-			"I got a good shot of <<pher>> playing with <<pherself>>!"
+			"I got a good shot of <<phim>> playing with <<pherself>>!"
 		<<else>>
-			"Watching <<pher>> play with <<pherself>> makes me so horny."
+			"Watching <<phim>> play with <<pherself>> makes me so horny."
 		<</if>>
 	<<else>>
 		<<if $orgasmdown gte 1>>
@@ -1962,7 +1962,7 @@
 			<<if $face is "covered">>
 				"<<pShes>> embarrassed! How adorable."
 			<<else>>
-				"<<pShes>> cumming already, be careful not to make <<pher>> faint."
+				"<<pShes>> cumming already, be careful not to make <<phim>> faint."
 			<</if>>
 		<<else>>
 			<<if $face is "covered">>
@@ -2663,14 +2663,3 @@
 <</if>>
 </div>
 <</widget>>
-
-<<set $audienceselector to 0>>
-<<set $audiencecamera to 0>>
-<<set $audiencecamera1 to 0>>
-<<set $audiencecamera2 to 0>>
-<<set $audiencecamera3 to 0>>
-<<set $audiencecamera4 to 0>>
-<<set $audiencecamera5 to 0>>
-<<set $audiencecamera6 to 0>>
-
-<<set $audiencemember to 0>>
diff --git a/game/base-combat/ejaculation.twee b/game/base-combat/ejaculation.twee
index 25e78807be..b93f83416a 100644
--- a/game/base-combat/ejaculation.twee
+++ b/game/base-combat/ejaculation.twee
@@ -498,7 +498,7 @@
 									<</if>>
 								<<case 2>>
 									<<if $averyragerevealed is 1 and $NPCName[$NPCNameList.indexOf("Avery")].rage gte 60>>
-										<span class="red"><<He>> slaps you back and forth across the face,<span> growing more intense with each strike. By the time <<hes>> done, <<hes>> panting.
+										<span class="red"><<He>> slaps you back and forth across the face,</span> growing more intense with each strike. By the time <<hes>> done, <<hes>> panting.
 										<<print either(
 											`"Don't you dare defy me."`,
 											`"Idiot. You messed up my hair."`,
diff --git a/game/base-combat/machine/machine.twee b/game/base-combat/machine/machine.twee
index f6d0babf61..bf4520ae11 100644
--- a/game/base-combat/machine/machine.twee
+++ b/game/base-combat/machine/machine.twee
@@ -19,6 +19,7 @@
 <<set $leftactiondefault to "rest">>
 <<set $rightactiondefault to "rest">>
 <<set $feetactiondefault to "rest">>
+<<set $NPCList[0].bold to 0>>
 <</widget>>
 
 <<widget "machine_damage">>
@@ -503,4 +504,4 @@
 	<<if $robinMachineSpeed>>
 		<<set $robinMachineSpeed to 4 - _args[0]>>
 	<</if>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/base-combat/struggle.twee b/game/base-combat/struggle.twee
index e091438a74..df791b66ec 100644
--- a/game/base-combat/struggle.twee
+++ b/game/base-combat/struggle.twee
@@ -18,6 +18,7 @@
 		<<set $rightleg to "bound">>
 		<<set $feetuse to "bound">>
 	<</if>>
+	<<set $NPCList[0].bold to 0>>
 <</widget>>
 
 <<widget "struggle_creatures">>
diff --git a/game/base-system/mirror.twee b/game/base-system/mirror.twee
index cf972a08e8..f853059032 100644
--- a/game/base-system/mirror.twee
+++ b/game/base-system/mirror.twee
@@ -1135,7 +1135,7 @@ __Hair__
 <br>
 <<if !$savedHairStyles>>
 	<<set $savedHairStyles to {
-		Default: {hairtype:$hairtype, fringetype:$fringetype, hairposition:$hairposition}
+		Default: { hairtype:$hairtype, fringetype:$fringetype, hairposition:$hairposition }
 	}>>
 <</if>>
 <<set _hairTypeByName to {"Braid left": "braid left", "Braid right": "braid right", "Flat ponytail": "flat ponytail", "Loose": "loose", "Messy": "messy", "Pigtails": "pigtails", "Ponytail": "ponytail", "Short": "short", "Side tail left": "side tail left", "Side tail right": "side tail right", "Straight": "straight", "Swept left": "swept left", "Twin braids": "twin braids", "Twintails": "twintails", "Curl": "curl", "Defined curl": "defined curl", "Neat": "neat", "Curly pigtails": "curly pigtails", "Sailor buns": "sailor buns", "Dreads": "dreads", "Short spiky": "short spiky", "Bubble tails": "bubble tails", "Curly side up": "curly side up", "Heart braid": "heart braid", "Loop braid": "loop braid", "Ruffled": "ruffled"}>>
@@ -1209,7 +1209,7 @@ Your fringe is in the "$fringetype" style.
 	<br>
 	<<link [["Save Current Hairstyle"|$passage]]>>
 		<<set _hairStyleName to _hairStyleName.replace(/[^a-zA-Z0-9_-]+/g,"").substring(0,30)>>
-		<<set $savedHairStyles[_hairStyleName] to {hairtype:$hairtype, fringetype:$fringetype, hairposition:$hairposition}>>
+		<<set $savedHairStyles[_hairStyleName] to { hairtype:$hairtype, fringetype:$fringetype, hairposition:$hairposition }>>
 	<</link>>
 </div>
 
@@ -1234,11 +1234,18 @@ Your fringe is in the "$fringetype" style.
 		<<capture _itemType>>
 		<span class="no-numberify">
 		<<link "Remove">>
-		<<set $makeup[_itemType] = 0>>
+
+		<<if _itemType is "eyelenses">>
+			<!-- A safety check for $makeup.eyelenses -->
+			<<set $makeup.eyelenses to { left: 0, right: 0 }>>
+		<<else>>
+			<<set $makeup[_itemType] to 0>>
+		<</if>>
 		<<if _itemType == 'mascara'>>
 			<<set $makeup.mascara_running = 0>>
 		<</if>>
 		<<run Engine.show()>>
+
 		<</link>></span>
 		<<print " | ">>
 		<</capture>>
@@ -1292,8 +1299,12 @@ __Makeup__
 	<<set $makeup.lipstick to 0>>
 	<<set $makeup.eyeshadow to 0>>
 	<<set $makeup.mascara to 0>>
+<<<<<<< game/base-system/mirror.twee
+	<<set $makeup.eyelenses to { left: 0, right: 0 }>>
+=======
 	<<set $makeup.mascara_running to 0>>
 	<<set $makeup.eyelenses to { "left": 0, "right": 0 }>>
+>>>>>>> game/base-system/mirror.twee
 <</link>> |
 <<link [[Randomise|$passage]]>>
 	<<for _i to 0; _i lt _makeupNames.length; _i++>>
@@ -1301,10 +1312,7 @@ __Makeup__
 		<<if _makeupNames[_i] is "eyelenses">>
 			<<set _rng to random(0, _ownedMakeup.length)>>
 			<<set _lens to _rng is _ownedMakeup.length ? 0 : _ownedMakeup[_rng]>>
-			<<set $makeup[_makeupNames[_i]] to {
-				"left": _lens,
-				"right": _lens
-			}>>
+			<<set $makeup.eyelenses to { left: _lens, right: _lens }>>
 		<<else>>
 			<<set _rngset to []>>
 			<<for _label, _value range _ownedMakeup>>
@@ -1363,26 +1371,26 @@ __Makeup__
 		<<if $makeup.eyelenses.left != 0 || $makeup.eyelenses.right != 0>>
 			<span class="no-numberify">
 			<<link "None">>
-			<<set $makeup.eyelenses = {"left":0, "right":0}>>
+			<<set $makeup.eyelenses = { left:0, right:0 }>>
 			<<run Engine.show()>>
 			<</link>></span>
 			<<print " | ">>
 		<</if>>
 		<<for _i, _colour range $makeup.owned.eyelenses>>
 			<<capture _colour>>
-			<span class="capitalize no-numberify">
-			<<link _colour>>
-			<<if _contact_eye_selected == "Both">>
-				<<set $makeup.eyelenses = {"left":_colour, "right":_colour}>>
-			<<elseif _contact_eye_selected == "Left eye">>
-				<<set $makeup.eyelenses["left"] = _colour>>
-			<<elseif _contact_eye_selected == "Right eye">>
-				<<set $makeup.eyelenses["right"] = _colour>>
-			<</if>>
-			<<run Engine.show()>>
-			<</link>></span>
-				<span @class="'eye-'+_colour.replace(/ /g, '-')"><span class="colour-sample bgcolour-eyes left-iris"></span></span>
-			<<print " | ">>
+				<span class="capitalize no-numberify">
+				<<link _colour>>
+					<<if _contact_eye_selected == "Both">>
+						<<set $makeup.eyelenses = { left:_colour, right:_colour }>>
+					<<elseif _contact_eye_selected == "Left eye">>
+						<<set $makeup.eyelenses.left = _colour>>
+					<<elseif _contact_eye_selected == "Right eye">>
+						<<set $makeup.eyelenses.right = _colour>>
+					<</if>>
+					<<run Engine.show()>>
+				<</link>></span>
+					<span @class="'eye-'+_colour.replace(/ /g, '-')"><span class="colour-sample bgcolour-eyes left-iris"></span></span>
+				<<print " | ">>
 			<</capture>>
 		<</for>>
 		<br>
@@ -1396,7 +1404,7 @@ __Makeup__
 		<<if $makeup.eyelenses.left != 0 || $makeup.eyelenses.right != 0>>
 			<span class="no-numberify">
 			<<link "None">>
-			<<set $makeup.eyelenses = {"left":0, "right":0}>>
+			<<set $makeup.eyelenses = { left:0, right:0 }>>
 			<<run Engine.show()>>
 			<</link>></span>
 			<<print " | ">>
@@ -1409,20 +1417,20 @@ __Makeup__
 				<</if>>
 			<</for>>
 			<<capture _colour _background_colour>>
-			<span class="capitalize no-numberify">
-			<<set _colour_name_with_space = window.colorNameTranslate(_colour, "spaced name")>>
-			<<link _colour_name_with_space>>
-			<<if _custom_eye_selected == "Both">>
-				<<set $makeup.eyelenses = {"left":_colour, "right":_colour}>>
-			<<elseif _custom_eye_selected == "Left eye">>
-				<<set $makeup.eyelenses["left"] = _colour>>
-			<<elseif _custom_eye_selected == "Right eye">>
-				<<set $makeup.eyelenses["right"] = _colour>>
-			<</if>>
-			<<run Engine.show()>>
-			<</link>></span>
-			<span class="eye-custom"><span @style="'background:'+_background_colour" class="colour-sample"></span></span>
-			<<print " | ">>
+				<span class="capitalize no-numberify">
+				<<set _colour_name_with_space = window.colorNameTranslate(_colour, "spaced name")>>
+				<<link _colour_name_with_space>>
+					<<if _custom_eye_selected == "Both">>
+						<<set $makeup.eyelenses = { left:_colour, right:_colour }>>
+					<<elseif _custom_eye_selected == "Left eye">>
+						<<set $makeup.eyelenses.left = _colour>>
+					<<elseif _custom_eye_selected == "Right eye">>
+						<<set $makeup.eyelenses.right = _colour>>
+					<</if>>
+					<<run Engine.show()>>
+				<</link>></span>
+				<span class="eye-custom"><span @style="'background:'+_background_colour" class="colour-sample"></span></span>
+				<<print " | ">>
 			<</capture>>
 		<</for>>
 		<br><br>
@@ -1512,29 +1520,27 @@ Preset: <<print _args[0]>>
 <</for>>
 <br>
 <<link [[Apply preset makeup|$passage]]>>
-	<<for $_i to 0; $_i lt _makeupNames.length; $_i++>>
-		<<if _makeupNames[$_i] is "eyelenses">>
-			<<if _presetChosen[_makeupNames[$_i]].left is 0 && _presetChosen[_makeupNames[$_i]].right is 0>>
-				<<set $makeup[_makeupNames[$_i]] to 0>>
-			<<elseif $makeup.owned[_makeupNames[$_i]].includes(_presetChosen[_makeupNames[$_i]].left) &&
-					$makeup.owned[_makeupNames[$_i]].includes(_presetChosen[_makeupNames[$_i]].right)>>
-				<<set $makeup[_makeupNames[$_i]] to _presetChosen[_makeupNames[$_i]]>>
-			<<elseif $makeup.owned.custom_eyelenses.includes(_presetChosen[_makeupNames[$_i]].left) &&
-					$makeup.owned.custom_eyelenses.includes(_presetChosen[_makeupNames[$_i]].right)>>
-				<<set $makeup[_makeupNames[$_i]] to _presetChosen[_makeupNames[$_i]]>>
+	<<for $_makeupName range _makeupNames>>
+		<<set _preset to _presetChosen[$_makeupName]>>
+		<<if $_makeupName is "eyelenses">>
+			<<if _preset.left is 0 and _preset.right is 0>>
+				<<set $makeup.eyelenses to { left:0, right:0 }>>
+			<<elseif $makeup.owned.eyelenses.includes(_preset.left) and $makeup.owned.eyelenses.includes(_preset.right)>>
+				<<set $makeup.eyelenses to _preset>>
+			<<elseif $makeup.owned.custom_eyelenses.includes(_preset.left) and $makeup.owned.custom_eyelenses.includes(_preset.right)>>
+				<<set $makeup.eyelenses to _preset>>
 			<</if>>
-		<<elseif _presetChosen[_makeupNames[$_i]] is 0 and _makeupNames[$_i] is "hairdye">>
+		<<elseif _preset is 0 and $_makeupName is "hairdye">>
 			/*Do Nothing*/
-		<<elseif _presetChosen[_makeupNames[$_i]] is 0>>
-			<<set $makeup[_makeupNames[$_i]] to 0>>
+		<<elseif _preset is 0>>
+			<<set $makeup[$_makeupName] to 0>>
 		<<else>>
-			<<for $_label, $_value range $makeup.owned[_makeupData[$_i]]>>
-				<<if $_value.colour is _presetChosen[_makeupNames[$_i]] and $_value.colour isnot $makeup[_makeupNames[$_i]] and $_value.count gt 0>>
-					<<set $makeup[_makeupNames[$_i]] to clone($_value.colour)>>
-					<<set $_value.count-->>
-					<<break>>
-				<</if>>
-			<</for>>
+			<<set $_makeupName2 to ($_makeupName is "browscolour" ? "hairdye" : $_makeupName)>>
+			<<set $_target to $makeup.owned[$_makeupName2].find(invMakeup => invMakeup.colour is _preset and invMakeup.colour isnot $makeup[$_makeupName] and invMakeup.count gt 0)>>
+			<<if $_target>>
+				<<set $makeup[$_makeupName] to clone($_target.colour)>>
+				<<set $_target.count-->>
+			<</if>>
 		<</if>>
 	<</for>>
 <</link>> |
diff --git a/game/base-system/mobileStats.twee b/game/base-system/mobileStats.twee
index 1859199d36..28abd6e796 100644
--- a/game/base-system/mobileStats.twee
+++ b/game/base-system/mobileStats.twee
@@ -12,7 +12,7 @@
 		Ar
 	</div>
 <</if>>
-<<if $sidebarStats is "All" or $tiredness gt $tirednessmax / 2>>
+<<if $sidebarStats is "All" or $tiredness gt C.tiredness.max / 2>>
 	<<mobileStatsColor "fatigue">>
 	<div @class="'stat ' + _mobileColor">
 		F
@@ -86,7 +86,7 @@
 	<<case "arousal">>
 		<<mobileStatsColorSet `Math.clamp($arousal, 0, $arousalmax)` $arousalmax>>
 	<<case "fatigue">>
-		<<mobileStatsColorSet `Math.clamp($tiredness, 0, $tirednessmax)` $tirednessmax>>
+		<<mobileStatsColorSet `Math.clamp($tiredness, 0, C.tiredness.max)` `C.tiredness.max`>>
 	<<case "stress">>
 		<<mobileStatsColorSet `Math.clamp($stress, 0, $stressmax)` $stressmax>>
 	<<case "innocence">>
@@ -171,4 +171,4 @@
 			<<set _mobileColor to "pink">>
 		<</switch>>
 	<</if>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/base-system/orgasm.twee b/game/base-system/orgasm.twee
index a3a349e895..1a45286cd5 100644
--- a/game/base-system/orgasm.twee
+++ b/game/base-system/orgasm.twee
@@ -88,7 +88,8 @@
 						<<personselect $_i>>
 						<<penileejacstat>>
 						<span class="pink">You are overcome by sensation and ejaculate over <<his>> penis.</span>
-						<<purity -1>><<internalejac>><<creampie "npc" "penis">>
+						<<purity -1>><<internalejac>>
+						<!-- <<creampie "npc" "penis">> -->
 					<<elseif $NPCList[$_i].penis is "penisimminent" or $NPCList[$_i].penis is "penisentrance">>
 						<<personselect $_i>>
 						<span class="pink">You are overcome by sensation and ejaculate over <<his>> cock and stomach.</span>
@@ -101,7 +102,8 @@
 				<<if $penisstate isnot "tentacleentrance" and $penisstate isnot "tentacleimminent">>
 					<<penileejacstat>>
 					<span class="pink">You are overcome by sensation. The $tentaclePenis milks you of your semen.</span>
-					<<purity -1>><<internalejac>><<creampie "npc" "tentacle">>
+					<<purity -1>><<internalejac>>
+					<!-- <<creampie "npc" "tentacle">> -->
 				<<else>>
 					<span class="pink">You are overcome by sensation and ejaculate on the $tentaclePenis.</span>
 				<</if>>
@@ -576,7 +578,7 @@
 			<<elseif $exposed gte 1>>
 				<<set $_hidden to true>>
 			<<else>>
-				The sight and sound of a <<girl>> convulsing in climax draws the attention of those in the studio. Their reactions are mixed. Some avoid looking. Some stare at you with displeasure. But some also cheer you on. As you regain control of yourself, you notice how rowdy the studio has become. Face red, you try to make yourself look as small and unassumng as possible.
+				The sight and sound of a <<girl>> convulsing in climax draws the attention of those in the studio. Their reactions are mixed. Some avoid looking. Some stare at you with displeasure. But some also cheer you on. As you regain control of yourself, you notice how rowdy the studio has become. Face red, you try to make yourself look as small and unassuming as possible.
 				<<gtrauma>><<gstress>><<trauma 6>><<stress 6>><<fameexhibitionism 10>>
 			<</if>>
 		<<case "pound">>
@@ -594,7 +596,7 @@
 			<<elseif $exposed gte 1>>
 				<<set $_hidden to true>>
 			<<else>>
-				The sight and sound of a <<girl>> convulsing in climax draws the attention of the patrons. Their reactions are mixed. Some avoid looking. Some stare at you with displeasure. But some also cheer you on. As you regain control of yourself, you notice how rowdy the cafe has become. Face red, you try to make yourself look as small and unassumng as possible.
+				The sight and sound of a <<girl>> convulsing in climax draws the attention of the patrons. Their reactions are mixed. Some avoid looking. Some stare at you with displeasure. But some also cheer you on. As you regain control of yourself, you notice how rowdy the cafe has become. Face red, you try to make yourself look as small and unassuming as possible.
 				<<gtrauma>><<gstress>><<trauma 6>><<stress 6>><<fameexhibitionism 10>>
 			<</if>>
 		<<case "arcade">>
@@ -1014,4 +1016,4 @@
 		<<set $orgasmcount += _args[0]>>
 		<<set $orgasmcount = Math.clamp($orgasmcount, 0, 25)>>
 	<</if>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/base-system/overlays/cheats.twee b/game/base-system/overlays/cheats.twee
index cfae7577a2..6cc40f9dec 100644
--- a/game/base-system/overlays/cheats.twee
+++ b/game/base-system/overlays/cheats.twee
@@ -380,7 +380,7 @@ Arousal: <span id="statsarousal"><<print Math.trunc($arousal)>></span>
 Fatigue: <span id="statstiredness"><<print Math.trunc($tiredness)>></span>
  | <<link ">">><<set $tiredness += 10>><<clamp>><<replace "#statstiredness">><<print Math.trunc($tiredness)>><</replace>> <<updatesidebarimg>><</link>>
  | <<link ">>">><<set $tiredness += 100>><<clamp>><<replace "#statstiredness">><<print Math.trunc($tiredness)>><</replace>> <<updatesidebarimg>><</link>>
- | <<link ">>>">><<set $tiredness += 1000>><<clamp>><<replace "#statstiredness">><<print Math.trunc($tiredness)>><</replace>> <<updatesidebarimg>><</link>> (Bar full at $tirednessmax)
+ | <<link ">>>">><<set $tiredness += 1000>><<clamp>><<replace "#statstiredness">><<print Math.trunc($tiredness)>><</replace>> <<updatesidebarimg>><</link>> (Bar full at <<print C.tiredness.max>>)
 <br>
 
 <<link "<<<">><<set $stress -= 1000>><<clamp>><<replace "#statsstress">><<print Math.trunc($stress)>><</replace>> <<updatesidebarimg>><</link>> |
diff --git a/game/base-system/physicalAdjustments.twee b/game/base-system/physicalAdjustments.twee
index 3d12173077..5ba7869c16 100644
--- a/game/base-system/physicalAdjustments.twee
+++ b/game/base-system/physicalAdjustments.twee
@@ -15,8 +15,7 @@
 			"npc":{
 				"anus":0,
 				"mouth":0,
-				"vagina":0,
-				"tentacle":0
+				"vagina":0 /* , "tentacle":0 */
 			}
 		},
 		"pills":{
@@ -450,7 +449,11 @@
 <<set $sexStats.creampie.npc.anus to 0>>
 <<set $sexStats.creampie.npc.mouth to 0>>
 <<set $sexStats.creampie.npc.vagina to 0>>
-<<set $sexStats.creampie.npc.tentacle to 0>>
+<!-- <<set $sexStats.creampie.npc.tentacle to 0>> -->
+<!-- <<set $sexStats.creampie.npc.penis to 0>> -->
+<!-- IMPORTANT NOTE: If you uncomment the above sections,
+find a section in backComp widget labeled: v0.3.11.4 creampie.npc.penis and tentacle fix
+And REMOVE it or comment it out -->
 <<set $sexStats.creampie.self.anus to 0>>
 <<set $sexStats.creampie.self.mouth to 0>>
 <<set $sexStats.creampie.self.vagina to 0>>
@@ -515,8 +518,8 @@
 /*<<creampie "self" "mouth">> -- <<set $sexStats.creampie.self.mouth++>>*/
 :: Widgets creampie [widget]
 <<widget "creampie">>
-<<if _args[0] and _args[1] and $pregnancyTesting>>
+<<if _args[0] and _args[1]>>
 	<<set $sexStats.creampie[_args[0]][_args[1]]++>>
 <</if>>
 <<set $internalejac to 1>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/base-system/settings.twee b/game/base-system/settings.twee
index 6610a5a9ed..d1683015c3 100644
--- a/game/base-system/settings.twee
+++ b/game/base-system/settings.twee
@@ -1710,7 +1710,7 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 			<</link>>
 		<</if>>
 		<br>
-		<span data-disabledif="V.per_npc[T.pNPCId].pronoun==='i'">
+		<span data-target="pernpc-npcidpronoun" data-disabledif="V.per_npc[T.pNPCId].pronoun==='i'">
 		<label><<radiobutton "$per_npc[_pNPCId].pronoun" "f" autocheck>> Female</label> |
 		<label><<radiobutton "$per_npc[_pNPCId].pronoun" "m" autocheck>> Male</label>
 		</span>
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index 8063f29b9b..0b0f5a6956 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -928,20 +928,14 @@
 <</silently>><<print _text_output>><</widget>>
 
 <<widget "underoutfit">><<silently>>
-<<outfitChecks>>
-<<breasts>><<set _breasts_text to _text_output>>
-<<genitals>><<set _genitals_text to _text_output>>
-<<if _underOutfit>>
-	<<set _text_output to $worn.under_upper.name>>
-<<elseif $worn.under_upper.name is "naked" and $worn.under_lower.name is "naked">>
-	<<set _text_output to _breasts_text + " and " + _genitals_text>>
-<<elseif $worn.under_lower.name is "naked">>
-	<<set _text_output to $worn.under_upper.name + " and " + _breasts_text>>
-<<elseif $worn.under_upper.name is "naked">>
-	<<set _text_output to _breasts_text + " and " + $worn.under_lower.name>>
-<<else>>
-	<<set _text_output to $worn.under_upper.name + " and " + $worn.under_lower.name>>
-<</if>>
+	<<outfitChecks>>
+	<<undies>><<set $_secondhalf to _text_output>>
+	<<undertop>>
+	<!-- _text_output now has top (either worn under_upper name, or breasts desc) -->
+	
+	<<if !_underOutfit>> <!-- Two separate items, not an outfit -->
+		<<set _text_output += " and " + $_secondhalf>>
+	<</if>>
 <</silently>><<print _text_output>><</widget>>
 
 <<widget "genitalstate">><<silently>>
@@ -4138,7 +4132,8 @@ A sign reads "Opening hours: <<ampm 8 00>> - <<ampm 21 00>>"
 	<<set _text_output to $worn.upper.name>>
 	<<set $stripset to 1>>
 <<else>>
-	<<set _text_output to $worn.upper.name + " and " + $worn.lower.name>>
+	<<set $_clothes to [$worn.upper.name, $worn.lower.name].filter(a => a !== "naked")>>
+	<<set _text_output to $_clothes.formatList()>>
 	<<set $stripset to 0>>
 <</if>>
 <</silently>>_text_output<</widget>>
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 9dae3f9f01..631ad275fa 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -1122,15 +1122,15 @@
 	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
 		Fatigue:
 		<<if $showCaptionText is true>>
-			<<if $tiredness gte $tirednessmax>>
+			<<if $tiredness gte C.tiredness.max>>
 				<span class="red">You are exhausted.</span>
-			<<elseif $tiredness gte ($tirednessmax / 5) * 4>>
+			<<elseif $tiredness gte (C.tiredness.max / 5) * 4>>
 				<span class="pink">You are fatigued.</span>
-			<<elseif $tiredness gte ($tirednessmax / 5) * 3>>
+			<<elseif $tiredness gte (C.tiredness.max / 5) * 3>>
 				<span class="purple">You are tired.</span>
-			<<elseif $tiredness gte ($tirednessmax / 5) * 2>>
+			<<elseif $tiredness gte (C.tiredness.max / 5) * 2>>
 				<span class="blue">You are wearied.</span>
-			<<elseif $tiredness gte $tirednessmax / 5>>
+			<<elseif $tiredness gte C.tiredness.max / 5>>
 				<span class="lblue">You are alert.</span>
 			<<elseif $tiredness gte 1>>
 				<span class="teal">You are wide awake.</span>
@@ -1140,13 +1140,13 @@
 		<</if>>
 	</div>
 
-	<<if $tiredness gte $tirednessmax>>
-		<<set $stress += (($tiredness - $tirednessmax) * 16)>><<set $trauma += (($tiredness - $tirednessmax) / 3)>>
+	<<if $tiredness gte C.tiredness.max>>
+		<<set $stress += (($tiredness - C.tiredness.max) * 16)>><<set $trauma += (($tiredness - C.tiredness.max) / 3)>>
 	<</if>>
 
-	<<set $tiredness = Math.clamp($tiredness, 0, $tirednessmax)>>
+	<<set $tiredness = Math.clamp($tiredness, 0, C.tiredness.max)>>
 	<<set _showCaptionText to !$showCaptionText>>
-	<<statbar $tiredness $tirednessmax _showCaptionText>>
+	<<statbar $tiredness `C.tiredness.max` _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
 <</widget>>
@@ -4785,6 +4785,9 @@ __Map__<br>
 
 <<widget "cheatStart">>
 <<set $cheatdisable to "f">><<set $money to 500000>>
+<<set $rentmoney to 10000>><<rentmod>>
+<<set $renttime to 7>><<set $rentday to $weekday>>
+<<set $rentstage to 1>>
 <</widget>>
 
 <<widget "swim_check">>
diff --git a/game/overworld-forest/loc-asylum/events.twee b/game/overworld-forest/loc-asylum/events.twee
index 7d9234cecb..88db8a0ef5 100644
--- a/game/overworld-forest/loc-asylum/events.twee
+++ b/game/overworld-forest/loc-asylum/events.twee
@@ -1070,7 +1070,7 @@ You reach across the desk and grab <<his>> coat with both hands. "You're wrong,"
 :: Asylum Rape Sub
 
 <<set $outside to 0>><<set $location to "asylum">><<asylumeffects>><<effects>>
-"I-It's all me?" you say. "It's my fault?"
+"I-It's all me?" you ask. "It's my fault?"
 <br><br>
 <<He>> shakes <<his>> head. "There's no fault," <<he>> says. "But you understand. People are responding to your provocation. The way you dress and carry yourself. Most people aren't as talented." <<He>> glances at the clock. "That's all for today. Be well."
 <br><br>
@@ -1114,7 +1114,7 @@ You reach across the desk and grab <<his>> coat with both hands. "You're wrong,"
 :: Asylum Beast Sub
 
 <<set $outside to 0>><<set $location to "asylum">><<asylumeffects>><<effects>>
-"It's my fault?" you say. "I'm the one making animals attack me?"
+"It's my fault?" you ask. "I'm the one making animals attack me?"
 <br><br>
 <<He>> shakes <<his>> head. "You're attacking them," <<he>> says. "But you're on the right track." <<He>> glances at the clock. "That's all for today. Be well."
 <br><br>
@@ -1136,7 +1136,7 @@ You reach across the desk and grab <<his>> coat with both hands. "You're wrong,"
 :: Asylum Tentacles Sub
 
 <<set $outside to 0>><<set $location to "asylum">><<asylumeffects>><<effects>>
-"They aren't real?" you say. "But why did they feel good?"
+"They aren't real?" you ask. "But why did they feel good?"
 <br><br>
 "You were either sleeping with someone, or touching yourself," <<he>> says. "Likely the former." <<He>> glances at the clock. "That's all for today. Be well."
 <br><br>
@@ -1158,10 +1158,10 @@ You reach across the desk and grab <<his>> coat with both hands. "You're wrong,"
 :: Asylum Hurt Sub
 
 <<set $outside to 0>><<set $location to "asylum">><<asylumeffects>><<effects>>
-"If they were hurting me," you say. "Why did it feel good?"
+"I did this to myself?" you ask. "But why?"
 <br><br>
-"Quite," <<He>> says. "You did this to yourself. Because you felt guilty." <<He>> glances at the clock. "That's all for today. Be well."
+"Yes," <<he>> says. "You did this to yourself. Because you felt guilty." <<He>> glances at the clock. "That's all for today. Be well."
 <br><br>
 <<endevent>>
 <<link [[Next|Asylum]]>><</link>>
-<br>
\ No newline at end of file
+<br>
diff --git a/game/overworld-forest/loc-asylum/widgets.twee b/game/overworld-forest/loc-asylum/widgets.twee
index 6dab0bcc0f..6076ef62f3 100644
--- a/game/overworld-forest/loc-asylum/widgets.twee
+++ b/game/overworld-forest/loc-asylum/widgets.twee
@@ -390,7 +390,7 @@ Harper stares at you across the desk. "In your sleep you talk about being raped
 		<<link [[Next|Asylum Cell]]>><</link>>
 		<br>
 	<<else>>
-		Show <<pher>> around. Let the others see."
+		Show <<phim>> around. Let the others see."
 		<br><br>
 
 		You are led through the occupied part of the asylum. Most patients ignore you, but some jeer. They leave you near your room.
diff --git a/game/overworld-forest/loc-cabin/events.twee b/game/overworld-forest/loc-cabin/events.twee
index 208e0abb0e..d86444f0b9 100644
--- a/game/overworld-forest/loc-cabin/events.twee
+++ b/game/overworld-forest/loc-cabin/events.twee
@@ -580,7 +580,7 @@ You feel more comfortable about your nudity with <<his>> back turned.
 	<<else>>
 		Just as you're about to place the sponge aside, Eden grabs your wrist in a secure but gentle grip.
 	<</if>>
-	"Do you want me to wash you too?" <<He>> asks.
+	"Do you want me to wash you too?" <<he>> asks.
 	<br><br>
 
 	<<if !$edenbathintro>>
diff --git a/game/overworld-forest/loc-cabin/main.twee b/game/overworld-forest/loc-cabin/main.twee
index d26f687776..5780fc1a76 100644
--- a/game/overworld-forest/loc-cabin/main.twee
+++ b/game/overworld-forest/loc-cabin/main.twee
@@ -1837,7 +1837,7 @@ You climb to your knees and look up at <<him>>.
 <<set $edendays to 0>><<asylumescape>>
 After you enter the cabin, Eden shuts the door behind you and wraps you up in a big hug. Is <<he>> trembling?
 <br><br>
-"I was so, so worried." <<He>> says. You think you feel tears land on your shoulder, but Eden gathers <<him>>self before you can address it.
+"I was so, so worried," <<he>> says. You think you feel tears land on your shoulder, but Eden gathers <<him>>self before you can address it.
 <br><br>
 <<if $pain gte 10>>
 	The tightness of Eden's hold irritates your wounds, and you tap on <<his>> shoulder to notify <<him>>.
diff --git a/game/overworld-forest/loc-lake/widgets.twee b/game/overworld-forest/loc-lake/widgets.twee
index a94f3ba2c9..e8eaead2e6 100644
--- a/game/overworld-forest/loc-lake/widgets.twee
+++ b/game/overworld-forest/loc-lake/widgets.twee
@@ -577,4 +577,4 @@ A pair of eyes stares at you from between the trees, then vanishes.
 		<<link [[Next|Lake Ruin Deep]]>><<endevent>><<set $eventskip to 1>><</link>>
 <</switch>>
 <br>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-forest/loc-wolfpack/wolf.twee b/game/overworld-forest/loc-wolfpack/wolf.twee
index a05df4ce69..ecd8dfc9e3 100644
--- a/game/overworld-forest/loc-wolfpack/wolf.twee
+++ b/game/overworld-forest/loc-wolfpack/wolf.twee
@@ -128,7 +128,7 @@
 				<<bHe>> seems unnerved.
 			<</if>>
 		<<case 7>>
-			<<bHe>> starts sniffing you, burying <<his>> snout on your hair and huffing on it.
+			<<bHe>> starts sniffing you, burying <<bhis>> snout on your hair and huffing on it.
 			<<if $monster is 1>>
 				"Could never forget <<ppackbrother>>'s scent," <<bhe>> says. "Could track all over forest if necessary."
 			<<else>>
@@ -154,7 +154,7 @@
 				<<if $monster is 1>>
 					"<<pPackbrother>> has lost <<pher>> way," <<bhe>> says, shaking <<bhis>> head. "Should stay with pack for some time."
 				<<else>>
-					<<bHe>> growls, but stops himself from snapping at you.
+					<<bHe>> growls, but stops <<bhimself>> from snapping at you.
 				<</if>>
 			<<elseif $bird gte 4 and $transformationParts.bird.plumage isnot "hidden">>
 				<<bHe>> stares at your plumage in fascination.
@@ -407,13 +407,13 @@ Having lived like the rest of your pack, you feel a deeper connection to them. "
 		<<if $monster is 1>>
 			As you approach, the Black Wolf snaps out of <<bhis>> restful state, keeping an eye on you as you sit.
 			<br><br>
-			<<bHe>> stays cautious, even as <<he>> sniffs, eyes flickering between you and the trees.
+			<<bHe>> stays cautious, even as <<bhe>> sniffs, eyes flickering between you and the trees.
 			<br><br>
-			"Something there," <<he>> growls, standing and rushing off. You wonder if it is just an excuse to be alone.
+			"Something there," <<bhe>> growls, standing and rushing off. You wonder if it is just an excuse to be alone.
 		<<else>>
 			As you approach, the Black Wolf snaps out of <<bhis>> restful state, keeping an eye on you as you sit.
 			<br><br>
-			<<bHe>> stays cautious, even as <<he>> sniffs, eyes flickering between you and the trees.
+			<<bHe>> stays cautious, even as <<bhe>> sniffs, eyes flickering between you and the trees.
 			<br><br>
 			<<bHe>> growls, standing and rushing off. You wonder if it is just an excuse to be alone.
 		<</if>>
@@ -660,4 +660,4 @@ Satisfied nothing will attack you in your sleep, you turn to make your way back.
 	<<endcombat>><<clotheson>>
 <</if>>
 
-<<link [[Next|Wolf Cave Clearing]]>><<set $wolfevent to 0>><</link>>
\ No newline at end of file
+<<link [[Next|Wolf Cave Clearing]]>><<set $wolfevent to 0>><</link>>
diff --git a/game/overworld-plains/loc-estate/cards_widgets.twee b/game/overworld-plains/loc-estate/cards_widgets.twee
index f5e648a9fe..775d4fa724 100644
--- a/game/overworld-plains/loc-estate/cards_widgets.twee
+++ b/game/overworld-plains/loc-estate/cards_widgets.twee
@@ -1079,7 +1079,7 @@ Total: <<print $blackjack.playersScore>>
 
 <<if !($worn.upper.type.includes("naked") and $worn.under_upper.type.includes("naked") and $worn.lower.type.includes("naked") and $worn.under_lower.type.includes("naked"))>>
 	<<clothesruined>><<exposure>>
-	"Let's get <<pher>> ready," the <<person2>><<person>> says. Hands grasp your clothes from all directions, pulling and tearing the fabric, until you're left exposed. <<covered>>
+	"Let's get <<phim>> ready," the <<person2>><<person>> says. Hands grasp your clothes from all directions, pulling and tearing the fabric, until you're left exposed. <<covered>>
 	<br><br>
 <</if>>
 <<fameexhibitionism 7>>
diff --git a/game/overworld-plains/loc-estate/main.twee b/game/overworld-plains/loc-estate/main.twee
index a4e2f005e9..50587fcc99 100644
--- a/game/overworld-plains/loc-estate/main.twee
+++ b/game/overworld-plains/loc-estate/main.twee
@@ -386,12 +386,11 @@ You walk to the front of the carriage, and the pullable lever. It clicks into a
 <br><br>
 
 You hear shouting over the roar of the engine, but can't make out the words. They're left far behind as the carriage plunges into darkness.
-<<endcombat>>
 
 Rings of light occasionally whip by as the vehicle rattles along the tracks.
 <br><br>
 
-<<link [[Next|Elk Compound Station]]>><<estate_end>><</link>>
+<<link [[Next|Elk Compound Station]]>><<estate_end>><<endevent>><</link>>
 <br>
 
 :: Estate Stone Carriage Stop
diff --git a/game/overworld-plains/loc-estate/sabotage.twee b/game/overworld-plains/loc-estate/sabotage.twee
index aa95905699..c630e8bb64 100644
--- a/game/overworld-plains/loc-estate/sabotage.twee
+++ b/game/overworld-plains/loc-estate/sabotage.twee
@@ -212,7 +212,7 @@ Wren hesitates a moment, then
 <</if>>
 beneath.
 
-<<His>> friends seems more interested in ogling you, for the moment.
+<<His>> friends seem more interested in ogling you, for the moment.
 <br><br>
 
 "It's warm in here anyway," <<he>> says, chucking the garment on the counter. "My turn next," <<he>> pauses.
diff --git a/game/overworld-plains/loc-farm/events.twee b/game/overworld-plains/loc-farm/events.twee
index a060c74455..4181bf9958 100644
--- a/game/overworld-plains/loc-farm/events.twee
+++ b/game/overworld-plains/loc-farm/events.twee
@@ -1330,7 +1330,7 @@ Alex arrives at the stable, and runs along the lane. "You okay?" <<he>> asks. "Y
 		<br><br>
 	<</if>>
 	<<if $farm.beasts.horses lte -20 and $rng gte 51>>
-		"Fuck this," the second centaur says. "Lets give <<pher>> a proper seeing to." Still holding your arms, <<farm_he horse>> lifts you into the air and throws you over a nearby fence. <<farm_He horse>> steps over you.
+		"Fuck this," the second centaur says. "Lets give <<phim>> a proper seeing to." Still holding your arms, <<farm_he horse>> lifts you into the air and throws you over a nearby fence. <<farm_He horse>> steps over you.
 		<br><br>
 
 		<<link [[Next|Farm Horse Rape]]>><<set $molestationstart to 1>><</link>>
diff --git a/game/overworld-plains/loc-livestock/main.twee b/game/overworld-plains/loc-livestock/main.twee
index f2103a6043..36ea988426 100644
--- a/game/overworld-plains/loc-livestock/main.twee
+++ b/game/overworld-plains/loc-livestock/main.twee
@@ -1245,7 +1245,7 @@ Remy calls for help, and two farmhands rush to <<his>> side. "If you're going to
 <br><br>
 <<actionsman>>
 
-<<if _combatend or (gte 100 and $willpowerpain is 0)>>
+<<if _combatend or ($pain gte 100 and $willpowerpain is 0)>>
 	<span id="next"><<link [[Next|Livestock Fight Finish]]>><</link>></span><<nexttext>>
 <<else>>
 	<span id="next"><<link [[Next|Livestock Fight]]>><</link>></span><<nexttext>>
diff --git a/game/overworld-town/loc-adultshop/events.twee b/game/overworld-town/loc-adultshop/events.twee
index 76a2f77c34..7f9471c1b7 100644
--- a/game/overworld-town/loc-adultshop/events.twee
+++ b/game/overworld-town/loc-adultshop/events.twee
@@ -3011,7 +3011,7 @@ After some time, you decide to head back to the shop. <<He>> seems reluctant to
 <<set _toy to randomSexToy("all")>>
 As you enter the shop, Sydney waves at you from behind the counter. A <<person>> browses the merchandise but stops when <<he>> sees you. In an attempt to keep it casual, <<he>> walks over.
 <br><br>
-"I bet you're bored all by yourself in this big shop. Why don't we try out a few of these and make it more interesting?" <<He>> says.
+"I bet you're bored all by yourself in this big shop. Why don't we try out a few of these and make it more interesting?" <<he>> says.
 <br><br>
 Before you formulate a reply, Sydney appears.<<person2>>
 <<if _sydneyStatus.includes("pure")>>
diff --git a/game/overworld-town/loc-adultshop/intro.twee b/game/overworld-town/loc-adultshop/intro.twee
index 44626a7104..71c6e5fc28 100644
--- a/game/overworld-town/loc-adultshop/intro.twee
+++ b/game/overworld-town/loc-adultshop/intro.twee
@@ -508,7 +508,7 @@ Still cautious, Sydney steps out of <<his>> hiding place. "I recognise some from
 :: Dilapidated Gawker Ignore
 <<effects>>
 
-You let Sydney hide until the gawkers more on.
+You let Sydney hide until the gawkers move on.
 <br><br>
 
 <<link [[Next|Dilapidated End]]>><</link>>
diff --git a/game/overworld-town/loc-adultshop/shop.twee b/game/overworld-town/loc-adultshop/shop.twee
index 31be312ff7..2cd1f32007 100644
--- a/game/overworld-town/loc-adultshop/shop.twee
+++ b/game/overworld-town/loc-adultshop/shop.twee
@@ -227,7 +227,7 @@ You spot Sirris right by the entrance. It doesn't look like you'll be able to sn
 After making sure that you close the shop's door as quietly as you can, you turn around and are shocked to
 find a <<person>> face to face with you. <<He>> places a hand on your shoulder before you can even think of running.
 <br><br>
-"What do we have here? A little rat thief, trying to make off with some fuck toys?" <<He>> says with a
+"What do we have here? A little rat thief, trying to make off with some fuck toys?" <<he>> says with a
 disapproving expression, "I'll be informing the owners of this situation."
 <br><br>
 <<He>> pulls out <<his>> phone and seems to call to Sirris.
diff --git a/game/overworld-town/loc-adultshop/widgets.twee b/game/overworld-town/loc-adultshop/widgets.twee
index 4d2cf5f769..420f46a41a 100644
--- a/game/overworld-town/loc-adultshop/widgets.twee
+++ b/game/overworld-town/loc-adultshop/widgets.twee
@@ -388,7 +388,7 @@
 				<<if $player.perceived_breastsize lte 1>>
 					"I'd lick those nipples, cutie," <<he>> remarks.<<gstress>><<stress 5>><<insecurity "breasts_tiny" 5>><<ginsecurity "breasts_tiny">>
 				<<elseif $player.perceived_breastsize lte 5>>
-					"Cute lil' titties!" <<He>> exclaims, grinning broadly.<<gstress>><<stress 5>><<insecurity "breasts_small" 5>><<ginsecurity "breasts_small">>
+					"Cute lil' titties!" <<he>> exclaims, grinning broadly.<<gstress>><<stress 5>><<insecurity "breasts_small" 5>><<ginsecurity "breasts_small">>
 				<<elseif $player.perceived_breastsize lte 7>>
 					"Get a load of those honkers," <<he>> jeers.<<gstress>><<stress 5>><<insecurity "breasts_big" 5>><<ginsecurity "breasts_big">>
 				<<else>>
@@ -605,7 +605,7 @@
 			"Sorry, <<if $NPCList[0].pronoun is "m">>sir<<else>>ma'am<</if>>. I've no idea what you want."
 			The <<personsimple>>'s gestures become erratic, <<his>> face turning bright red. You shrug your shoulders.
 			<br><br>
-			"Oh come on, don't be so dense! It's your job to know this stuff!" <<He>> shouts. You remain silent. "Where's your manager!"<<gstress>><<stress 3>><<gtrauma>><<trauma 3>>
+			"Oh come on, don't be so dense! It's your job to know this stuff!" <<he>> shouts. You remain silent. "Where's your manager!"<<gstress>><<stress 3>><<gtrauma>><<trauma 3>>
 			<br><br>
 			"Is there a problem?" Sirris asks after hearing the shouting.
 			The <<person>> goes on to describe the object in question, making sure to point out how stupid you are for not knowing. Sirris picks up an item from the shelf and completes the customer's transaction before giving you a heavy sigh and shaking <<nnpc_his Sirris>> head. <<llove "Sirris">><<npcincr Sirris love -2>>
diff --git a/game/overworld-town/loc-brothel/main.twee b/game/overworld-town/loc-brothel/main.twee
index 3ace663994..5e3b0970a3 100644
--- a/game/overworld-town/loc-brothel/main.twee
+++ b/game/overworld-town/loc-brothel/main.twee
@@ -1748,7 +1748,7 @@ Due to the high police presence, you have a to wait for things to calm down befo
 	<<person1>>"Okay," the <<person>> says.
 	<br><br>
 	<<if $crime gte 4500>>
-		<<person2>>"This one's slippery," says the <<person>>. "Cuff <<pher>> first so <<pshe>> doesn't try anything."
+		<<person2>>"This one's slippery," says the <<person>>. "Cuff <<phim>> first so <<pshe>> doesn't try anything."
 		<br><br>
 		"Okay."
 		<<set $leftarm to "bound">><<set $rightarm to "bound">>
diff --git a/game/overworld-town/loc-cafe/main.twee b/game/overworld-town/loc-cafe/main.twee
index 36c358e20b..61aade5647 100644
--- a/game/overworld-town/loc-cafe/main.twee
+++ b/game/overworld-town/loc-cafe/main.twee
@@ -383,7 +383,7 @@ Please be patient with them; they don't mean nothing by it! We're always underst
 		<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
 			<<if $worn.under_lower.type.includes("naked")>>
 				As you turn to leave, the <<person1>><<person>> lifts the hem of your $worn.lower.name, revealing your bare <<bottom>> to the cafe.
-				"No underwear?" <<He>> says with incredulity. "You're a little slut, aren't you?"
+				"No underwear?" <<he>> says with incredulity. "You're a little slut, aren't you?"
 				<<fameexhibitionism 10>><<stress 6>><<arousal 600>><<gstress>><<garousal>>
 				<br><br>
 
@@ -405,7 +405,7 @@ Please be patient with them; they don't mean nothing by it! We're always underst
 		<<else>>
 			<<if $worn.under_lower.type.includes("naked")>>
 				As you turn to leave, the <<person1>><<person>> pulls down the back of your $worn.lower.name, revealing your bare <<bottom>> to the cafe.
-				"No underwear!" <<He>> says with incredulity. "Bet you regret that now."
+				"No underwear!" <<he>> says with incredulity. "Bet you regret that now."
 				<<fameexhibitionism 5>><<stress 3>><<arousal 300>><<gstress>><<garousal>>
 				<br><br>
 
diff --git a/game/overworld-town/loc-compound/main.twee b/game/overworld-town/loc-compound/main.twee
index 86c0f1f4d9..41b903c060 100644
--- a/game/overworld-town/loc-compound/main.twee
+++ b/game/overworld-town/loc-compound/main.twee
@@ -346,7 +346,7 @@ The <<person3>><<person>> films you.
 	<br><br>
 	"Think we should tell them downstairs?" the <<person2>><<person>> asks.
 	<br><br>
-	"Sure. You got it all on your phone didn't you? It'll make their day. This <<bitch>> just broke in for the thrill and has paid for it, we don't need to keep <<pher>> longer."
+	"Sure. You got it all on your phone didn't you? It'll make their day. This <<bitch>> just broke in for the thrill and has paid for it, we don't need to keep <<phim>> longer."
 	They shove you out the gate, closing it behind you.
 	<br><br>
 	<<tearful>> you rise to your feet.
@@ -367,7 +367,7 @@ The <<person3>><<person>> films you.
 	<br><br>
 	"Think we should tell them downstairs?" the <<person2>><<person>> asks.
 	<br><br>
-	"Sure. You got it all on your phone didn't you? It'll make their day. This <<bitch>> just broke in for the thrill and has paid for it, we don't need to keep <<pher>> any longer."
+	"Sure. You got it all on your phone didn't you? It'll make their day. This <<bitch>> just broke in for the thrill and has paid for it, we don't need to keep <<phim>> any longer."
 	They shove you out the gate, closing it behind you.
 	<br><br>
 	<<tearful>> you rise to your feet.
diff --git a/game/overworld-town/loc-dance-studio/widgets.twee b/game/overworld-town/loc-dance-studio/widgets.twee
index 835240abc8..abaf141aed 100644
--- a/game/overworld-town/loc-dance-studio/widgets.twee
+++ b/game/overworld-town/loc-dance-studio/widgets.twee
@@ -3,7 +3,6 @@
 	<<wearoutfit>>
 	<<set _store_location to "dance_studio">>
 	<<storeon _store_location "check">>
-	<<set _clothes to clothingInStorage(_store_location)>>
 	<<if $wearoutfittext isnot undefined>>
 		<<if $wearoutfittext is 1>>
 			<<set _slots to _clothes.filter(item => setup.clothingLayer.torso.includes(item.slot))>>
@@ -23,6 +22,7 @@
 		<<unset $wearoutfittext>>
 	<</if>>
 	<<if _store_check is 1>>
+		<<set _clothes to clothingInStorage(_store_location)>>
 		<<if _clothes.length gt 0>>
 			<<if _clothes.length gt 2>>
 				Your clothes are hanging on the hooks on the wall.
@@ -51,4 +51,4 @@
 	<</if>>
 	<br>
 	<br>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-town/loc-danube-homes/work.twee b/game/overworld-town/loc-danube-homes/work.twee
index 33729ed36d..6f71196fc4 100644
--- a/game/overworld-town/loc-danube-homes/work.twee
+++ b/game/overworld-town/loc-danube-homes/work.twee
@@ -24,7 +24,7 @@ You walk up to one of the mansions and knock on the door.
 		<<set $phase to 1>>
 	<</addinlineevent>>
 	<<addinlineevent "Danube Attic Pre-Intro">>
-		<<generate1>><<person1>>A <<person>> answers the door. "I do not like being disturbed. Speak." <<he>> says.
+		<<generate1>><<person1>>A <<person>> answers the door. "I do not like being disturbed. Speak," <<he>> says.
 		<<set $phase to 2>>
 	<</addinlineevent>>
 	<<addinlineevent "Danube Tea Pre-Intro">>
@@ -286,7 +286,7 @@ You suckle. It tastes sweet and warm. A calmness falls over you. <<His>> free ha
 <<promiscuity3>>
 After a while, the milk stops flowing. You look up.
 <br><br>
-"You can do the other one too, if you want." <<He>> says. "But you don't have to. I'll still pay you."
+"You can do the other one too, if you want," <<he>> says. "But you don't have to. I'll still pay you."
 <br><br>
 
 <<link [[Stop|Danube Breast Stop]]>><</link>>
@@ -853,7 +853,7 @@ The <<person>> takes a seat and gestures for you to do the same.
 <<if $player.bodyliquid.mouth.semen + $player.bodyliquid.face.semen + $player.bodyliquid.hair.semen gte 4>>
 	At one point <<he>> hands you a napkin. "You have some, ah... cream...
 	<<if $player.bodyliquid.mouth.semen gte 2>>
-		running down your chin." <<he>> says politely.
+		running down your chin," <<he>> says politely.
 		<<bodyliquid "mouth" "semen" -1>>
 	<<elseif $player.bodyliquid.face.semen gte 2>>
 		you got it up there on your cheek, somehow!" <<he>> says.
diff --git a/game/overworld-town/loc-docks/main.twee b/game/overworld-town/loc-docks/main.twee
index 73debb9492..95443b7601 100644
--- a/game/overworld-town/loc-docks/main.twee
+++ b/game/overworld-town/loc-docks/main.twee
@@ -1448,7 +1448,7 @@ The <<person>> grasps your neck and leans in. "I tried asking nicely," <<he>> wh
 		<<link [[Match their bet (£60)|Docks Pub Crawl Bet]]>><<set $money -= 6000>><</link>>
 		<br>
 	<</if>>
-	<<link [[Don't bet anything|Docks Pub Crawl Refuse]]>><</link>>
+	<<link [[Don't bet anything|Docks Pub Crawl Quiz Refuse]]>><</link>>
 	<br>
 
 <</if>>
diff --git a/game/overworld-town/loc-domus-homes/nude.twee b/game/overworld-town/loc-domus-homes/nude.twee
index 65b2850f7e..85f12fdc0d 100644
--- a/game/overworld-town/loc-domus-homes/nude.twee
+++ b/game/overworld-town/loc-domus-homes/nude.twee
@@ -170,13 +170,13 @@ You walk up to one of the homes and knock.
 		"<<pShes>> shy," the <<person3>><<person>> says as you cover your rear while reaching up to brush a cabinet.
 	<</if>>
 	<br><br>
-	You finish cleaning the living room, and leave the gaze of the guests and report to the <<person>> for payment. "Good job," <<He>> says, still leering at you. "Here's some stuff I found in a closet. Thanks for entertaining my guests."
+	You finish cleaning the living room, and leave the gaze of the guests and report to the <<person>> for payment. "Good job," <<he>> says, still leering at you. "Here's some stuff I found in a closet. Thanks for entertaining my guests."
 	<br><br>
 	<<pass 5>>
 	<<link [[Get changed and leave (0:01)|Domus Street]]>><<spareclothesdomus>><<endevent>><<pass 1>><</link>>
 	<br>
 <<else>>
-	Once the living room is cleaned, you report to the <<person>> for payment. "Good job," <<He>> says, still leering at you. "Here's some stuff I found in a closet."
+	Once the living room is cleaned, you report to the <<person>> for payment. "Good job," <<he>> says, still leering at you. "Here's some stuff I found in a closet."
 	<br><br>
 	<<pass 5>>
 	<<link [[Get changed and leave (0:01)|Domus Street]]>><<spareclothesdomus>><<endevent>><<pass 1>><</link>>
@@ -281,4 +281,4 @@ Running as fast as you can, you reach the house and hit the buzzer before turnin
 		<<upperwear 1>><<set $worn.lower.colour to either("black", "blue", "brown", "green", "pink", "purple", "red", "tangerine", "teal", "white", "yellow")>><<set $worn.upper.colour to $worn.lower.colour>>
 		<<set $worn.lower.integrity /= 2>><<set $worn.upper.integrity /= 2>>
 	<</if>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-town/loc-home/widgets.twee b/game/overworld-town/loc-home/widgets.twee
index dab174db97..4c5876f15c 100644
--- a/game/overworld-town/loc-home/widgets.twee
+++ b/game/overworld-town/loc-home/widgets.twee
@@ -81,7 +81,7 @@
 		<<set _coveredIn to (_coveredIn is "slime" ? "slime and semen" : "semen")>>
 		<<slime_wake_bodyliquid "semen">>
 	<</if>>
-	<<if _coveredIn isnot "">>
+	<<if _coveredIn isnot undefined>>
 		<<set $slimeSleepEvent += 2>>
 		On top of this predicament, you find yourself covered in <<print _coveredIn>>. If this was the slime's doing, it clearly had its fun with your body while you slept.
 		<br><br>
@@ -89,4 +89,4 @@
 	Having a look round your surroundings, you think that you've somehow been relocated to the <<print _newLocation.toLocaleLowerCase()>>.
 	<br><br>
 	<<link [[Next|_newLocation]]>><</link>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-town/loc-hospital/main.twee b/game/overworld-town/loc-hospital/main.twee
index eeb69c5584..349f2a3984 100644
--- a/game/overworld-town/loc-hospital/main.twee
+++ b/game/overworld-town/loc-hospital/main.twee
@@ -496,7 +496,7 @@ You've pushed yourself too much.
 		<<link [[Next|Hospital Foyer]]>><<endevent>><<towelup>><</link>>
 		<br>
 	<<else>>
-		You make it the cart without incident. Crouching beside it, you help yourself the towels, eyes affixed on a nearby door. You still feel exposed, but at least now you're covered. You should find something more suitable as soon as you can, before you attract unwanted attention.
+		You make it the cart without incident. Crouching beside it, you help yourself to the towels, eyes affixed on a nearby door. You still feel exposed, but at least now you're covered. You should find something more suitable as soon as you can, before you attract unwanted attention.
 		<br><br>
 
 		<<link [[Next|Hospital Foyer]]>><<endevent>><<towelup>><</link>>
diff --git a/game/overworld-town/loc-park/run.twee b/game/overworld-town/loc-park/run.twee
index bfe3e5062d..d798b9cc03 100644
--- a/game/overworld-town/loc-park/run.twee
+++ b/game/overworld-town/loc-park/run.twee
@@ -383,7 +383,7 @@ Your heart is pounding with the thrill as you quietly move on.
 			<<elseif $fame.bestiality gte 600 and ($player.bodyliquid.mouth.semen + $player.bodyliquid.face.semen + $player.bodyliquid.vagina.semen + $player.bodyliquid.anus.semen ) gte 3>>"That's probably animal cum
 			<<elseif (setup.bodyliquid.combined("mouth") + setup.bodyliquid.combined("face")) gte 5>>"<<pHer>> face! Sucked off every teacher
 			<<elseif $liquidoutsidecount gte 6>>"Covered in cum
-			<<elseif $fame.rape gte 600>>"Half the town's raped <<pher>> already
+			<<elseif $fame.rape gte 600>>"Half the town's raped <<phim>> already
 			<<elseif $fame.bestiality gte 600>>"<<pShe>> probably fucked five dogs already
 			<<elseif (setup.bodyliquid.combined("vagina") + setup.bodyliquid.combined("anus")) gte 2>>"You can see the cum dripping out
 			<<elseif $fame.sex gte 400>>"Half the town has <<pher>> fuck-vids
diff --git a/game/overworld-town/loc-photography/model.twee b/game/overworld-town/loc-photography/model.twee
index 382885a63a..cfd2cf0160 100644
--- a/game/overworld-town/loc-photography/model.twee
+++ b/game/overworld-town/loc-photography/model.twee
@@ -671,7 +671,13 @@ Niki returns, carrying a stool ahead of <<nnpc_him "Niki">>. You use it as a pro
 	<<set $photo.refused to 0>>
 	<<exposure>>
 	<<set $photo.evidence to 1>>
-	You step behind the screen, and remove the $worn.upper.name. Before you can dress however, <span class="purple">you hear a creak,</span> and the screen collapses, <span class="pink">exposing you to the room.</span><<gtrauma>><<gstress>><<trauma 6>><<stress 6>>
+	You step behind the
+	<<if $worn.upper.name isnot "naked">>
+		screen, and remove the $worn.upper.name.
+	<<else>>
+		screen.
+	<</if>>
+	Before you can dress however, <span class="purple">you hear a creak,</span> and the screen collapses, <span class="pink">exposing you to the room.</span><<gtrauma>><<gstress>><<trauma 6>><<stress 6>>
 	<br><br>
 	<<set $worn.upper to clone(setup.clothes.upper[0])>>
 	<<set $worn.lower to clone(setup.clothes.lower[0])>>
@@ -1073,4 +1079,4 @@ The light of the camera blinks as it records the scene.
 
 <</if>>
 
-<<link [[Next|Photo Model Topless End]]>><</link>>
\ No newline at end of file
+<<link [[Next|Photo Model Topless End]]>><</link>>
diff --git a/game/overworld-town/loc-police/pillory.twee b/game/overworld-town/loc-police/pillory.twee
index 077d7499e6..a84463ae1f 100644
--- a/game/overworld-town/loc-police/pillory.twee
+++ b/game/overworld-town/loc-police/pillory.twee
@@ -610,7 +610,7 @@ You kick the <<person>> in the shin. "Ow!" <<he>> says. "Fucking bitch." <<He>>
 		<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
 			"<<pShe>> isn't wearing anything under <<pher>> skirt!" the <<person>> announces loudly.
 		<<else>>
-			"<<pShe>> isn't wearing anything under <<pher>> there!" the <<person>> announces loudly.
+			"<<pShe>> isn't wearing anything under there!" the <<person>> announces loudly.
 		<</if>>
 		<br><br>
 	"What a pervert," says someone in the crowd.
diff --git a/game/overworld-town/loc-pound/abduction.twee b/game/overworld-town/loc-pound/abduction.twee
index c1ee6401a8..16a822ad25 100644
--- a/game/overworld-town/loc-pound/abduction.twee
+++ b/game/overworld-town/loc-pound/abduction.twee
@@ -160,7 +160,6 @@ They continue to pull you towards the door.
 <<if $pound is undefined>>
 	<<pound_init>>
 <</if>>
-<<set $pound.door to 0>>
 Inside are rows of cages, each containing barking <<pound_text>>. Some stick their noses through the bars, straining to sniff you.
 
 <<if $wolfgirl gte 6>>
@@ -186,6 +185,8 @@ The <<person1>><<person>> pulls you along, towards an empty cage near the back,
 :: Pound Cage
 <<location "pound">><<set $outside to 0>><<effects>>
 
+<<if !$pound.door>><<set $pound.door to 0>><</if>>
+
 You are imprisoned in the pound on Starfish Street. <<pound_text cap>> fill the cages. There's a bowl of water, but nowhere to sleep except the cold floor.
 <br><br>
 
@@ -291,7 +292,7 @@ You try to force the door open with all your might.
 
 	You rush forward and lock <<him>> in. "Y-you stupid <<bitch>>," <<he>> says, surprised by this sudden reversal. "Let me out!"
 	<br><br>
-	<<link [[Next|Pound Escape]]>><<set $pound.door to 0>><</link>>
+	<<link [[Next|Pound Escape]]>><</link>>
 	<br>
 <<else>>
 	<<link [[Next|Pound Cage]]>><</link>>
@@ -908,6 +909,7 @@ Footsteps approach. "Serves you right," a <<person>> says, freeing you. "Get wit
 
 :: Pound Escape
 <<effects>>
+<<run delete $pound.door>>
 
 The <<pound_text>> and caged employee yap at you. The commotion will attract attention. You'll be caught soon.
 <br><br>
@@ -1883,4 +1885,4 @@ You arrive at the orphanage. "I'm glad you're okay," the <<person>> says. "I thi
 <br><br>
 
 <<link [[Next|Orphanage]]>><<endevent>><</link>>
-<br>
\ No newline at end of file
+<br>
diff --git a/game/overworld-town/loc-pub/seduction.twee b/game/overworld-town/loc-pub/seduction.twee
index dd114049ec..9615f529e0 100644
--- a/game/overworld-town/loc-pub/seduction.twee
+++ b/game/overworld-town/loc-pub/seduction.twee
@@ -1013,7 +1013,7 @@ You swallow the pill. A daze descends on you and a perverse warmth grows in your
 :: Pub Refuse 2
 <<location "forest">><<effects>>
 
-"Suit yourself." <<He>> says. "I'd be careful if I were you. You don't want to get lost in here." <<He>> heads back to town.
+"Suit yourself," <<he>> says. "I'd be careful if I were you. You don't want to get lost in here." <<He>> heads back to town.
 <br><br>
 
 <<link [[Next|Forest]]>><<set $forest to 0>><<endevent>><</link>>
diff --git a/game/overworld-town/loc-school/fame.twee b/game/overworld-town/loc-school/fame.twee
index f051f111b6..50f69dada9 100644
--- a/game/overworld-town/loc-school/fame.twee
+++ b/game/overworld-town/loc-school/fame.twee
@@ -79,7 +79,7 @@ You follow <<person1>> into <<his>> office and stand in front of <<his>> desk wh
 :: School Fame Blackmail Refuse
 <<set $outside to 0>><<set $location to "school">><<schooleffects>><<effects>>
 
-You turn away from Leighton, but <<he>> steps forward and grasps your shoulder. "You better do as I say, believe me." <<He>> says, quiet enough that only you can hear. "Or things will be difficult for you."
+You turn away from Leighton, but <<he>> steps forward and grasps your shoulder. "You better do as I say, believe me," <<he>> says, quiet enough that only you can hear. "Or things will be difficult for you."
 <br><br>
 
 <<link [[Enter|School Fame Blackmail]]>><</link>>
diff --git a/game/overworld-town/loc-school/infirmary.twee b/game/overworld-town/loc-school/infirmary.twee
index 014068b184..db3a4b7220 100644
--- a/game/overworld-town/loc-school/infirmary.twee
+++ b/game/overworld-town/loc-school/infirmary.twee
@@ -126,7 +126,7 @@ The nurse shrugs. "Suit yourself." <<He>> places the bottle back in the cabinet,
 		The nurse gets up from <<his>> desk and walks over to you. <<He>> cups a hand under your chin, tilting your head upwards. <<He>> narrows <<his>> eyes, <<his>> gaze boring into you as <<he>> scrutinises your expression.
 		<br><br>
 
-		<<if $tiredness gte ($tirednessmax / 5) * 3>>
+		<<if $tiredness gte (C.tiredness.max / 5) * 3>>
 			Finally, <<he>> steps away from you and sighs. "You folks should sleep at night instead of partying. Alright. I can see you're tired." <<He>> glances at <<his>> watch. "I'll wake you up in half an hour. That ought to get you through the rest of the school day."
 			<br><br>
 
@@ -186,7 +186,7 @@ The nurse shrugs. "Suit yourself." <<He>> places the bottle back in the cabinet,
 			The nurse rises from <<his>> desk and walks over to you. <<He>> cups a hand under your chin and tilts your head upwards. <<He>> narrows <<his>> eyes, staring deeply into yours.
 			<br><br>
 
-			<<if $tiredness gte ($tirednessmax / 5) * 3>>
+			<<if $tiredness gte (C.tiredness.max / 5) * 3>>
 				Finally, <<he>> steps away from you and sighs. "You folks should spend less time partying. Alright. I can see you're tired." <<He>> glances at <<his>> watch. "I'll wake you up in half an hour. That ought to get you through the rest of the school day."
 				<br><br>
 
@@ -361,7 +361,7 @@ You wake up in an unfamiliar bed. Thin curtains surround you, hiding the rest of
 	<br>
 	"... 'unprofessional?' Oh, blow it out your..."
 	<br>
-	"... just send someone to pick <<pher>> up as soon..."
+	"... just send someone to pick <<phim>> up as soon..."
 	<br><br>
 
 	You try to listen on, but you can feel your mind giving out. You fall back into a deep sleep.
diff --git a/game/overworld-town/loc-school/maths-project.twee b/game/overworld-town/loc-school/maths-project.twee
index f2a5e447d4..c1ed82be9b 100644
--- a/game/overworld-town/loc-school/maths-project.twee
+++ b/game/overworld-town/loc-school/maths-project.twee
@@ -1023,7 +1023,7 @@ Inside is a table covered with cider cans and playing cards. As if a game were i
 
 	"<<pShe>> won't resist for long."
 	<br>
-	"Let's rape <<pher>> until <<pshe>> likes it."
+	"Let's rape <<phim>> until <<pshe>> likes it."
 	<br>
 	"So feisty."
 	<br>
diff --git a/game/overworld-town/loc-school/science-project.twee b/game/overworld-town/loc-school/science-project.twee
index 1a07a78a27..480a975ace 100644
--- a/game/overworld-town/loc-school/science-project.twee
+++ b/game/overworld-town/loc-school/science-project.twee
@@ -169,7 +169,7 @@ You enter the town hall. It's full of other students setting up their projects.
 	<br>
 <</if>>
 <<if $scienceshroomknown is 1>>
-	<<link [[Enter mushroom project (3:00)|Science Fair Mushroom]]>><<pass 3 hour>><</link>><<note "$sciencemushroomchance% chance of winning" "gold">>
+	<<link [[Enter mushroom project (3:00)|Science Fair Mushroom]]>><<pass 3 hour>><</link>><<note "$scienceshroomchance% chance of winning" "gold">>
 	<br>
 <</if>>
 <<if $sciencephallusknown is 1>>
diff --git a/game/overworld-town/loc-school/special-olive.twee b/game/overworld-town/loc-school/special-olive.twee
index cda205dcb2..63778f9226 100644
--- a/game/overworld-town/loc-school/special-olive.twee
+++ b/game/overworld-town/loc-school/special-olive.twee
@@ -337,7 +337,7 @@ A <<girl>>, a <<lass>> by the name of Lew,
 <br>
 <span class="black">"Please, tell me, <<if $pronoun is "m">>Santa<<else>>Mrs<</if>> Claus!"</span>
 <br>
-So dastardly clever, <<he>> spun <<pher>> a ruse
+So dastardly clever, <<he>> spun <<phim>> a ruse
 <br>
 <span class="black">With just the slightest pause.</span>
 <br><br>
diff --git a/game/overworld-town/loc-school/widgets-events.twee b/game/overworld-town/loc-school/widgets-events.twee
index 10da7fc2fa..c066e4c3dc 100644
--- a/game/overworld-town/loc-school/widgets-events.twee
+++ b/game/overworld-town/loc-school/widgets-events.twee
@@ -575,7 +575,7 @@
 				"But you didn't look into the alley?"<br>
 				"There are things I prefer not to see."
 			<<else>>
-				"Yes, dogs!" the <<person1>><<person>> whispers. "About three of them, on top of <<pher>>, one after the other."<br>
+				"Yes, dogs!" the <<person1>><<person>> whispers. "About three of them, on top of <<phim>>, one after the other."<br>
 				"My god, that's disgusting!"<br>
 				"I think it's hot."<<set _trauma to true>>
 			<</if>>
@@ -585,9 +585,9 @@
 				"I'm serious!" a <<person2>><<person>> says. "People have wild tastes."<br>
 				<<person1>><<He>> shakes <<his>> head. "Is that even legal?"
 			<<else>>
-				"<<pShe>> can't get people to like <<pher>>," a <<person1>><<person>> snickers. "That's why <<pshe>> fucks..." You can't make out the rest.
+				"<<pShe>> can't get people to like <<phim>>," a <<person1>><<person>> snickers. "That's why <<pshe>> fucks..." You can't make out the rest.
 				"No way," <<his>> friend gawks. "No one's that much of a freak."<br>
-				"You haven't met <<pher>>, have you?"<<set _trauma to true>>
+				"You haven't met <<phim>>, have you?"<<set _trauma to true>>
 			<</if>>
 		<</if>>
 	<<elseif _selectedRumour is "exhibitionism">>
@@ -617,8 +617,8 @@
 			"Well, I couldn't see their face very well..."
 		<<else>>
 			"Can confirm it," the <<person1>><<person>> whispers. "<<pShe>> is a whore, and a really cheap one. Best five quid of my life!"<br>
-			"Five quid still sounds too much for <<pher>>." The group laugh.<br>
-			"Maybe I would give <<pher>> a penny or two."<<set _trauma to true>>
+			"Five quid still sounds too much for <<phim>>." The group laugh.<br>
+			"Maybe I would give <<phim>> a penny or two."<<set _trauma to true>>
 		<</if>>
 	<<elseif _selectedRumour is "rape">>
 		<<if $cool gte 120>>
@@ -1609,7 +1609,7 @@
 			<<if $player.gender is _whitney.pronoun>>
 				<<He>> tries to push you into the <<print ($player.gender is "m" ? "girl" : "boy")>>s' toilets.
 				<br><br>
-				"A new rule, slut," <<he>> says. "You're a failure of a <<print ($player.gender is "m" ? "girl" : "boy")>>. You don't deserve to use the same toilets as me."
+				"A new rule, slut," <<he>> says. "You're a failure of a <<print ($player.gender is "m" ? "boy" : "girl")>>. You don't deserve to use the same toilets as me."
 				<<He>> pushes you closer.
 			<<else>>
 				<!-- includes player.gender is "h" -->
diff --git a/game/overworld-town/loc-school/widgets.twee b/game/overworld-town/loc-school/widgets.twee
index 91abe51d88..49515f2fed 100644
--- a/game/overworld-town/loc-school/widgets.twee
+++ b/game/overworld-town/loc-school/widgets.twee
@@ -2620,10 +2620,10 @@
 				Your clothes are gathered in a neat pile next to the lockers.
 				<br>
 			<<elseif _clothes.length is 2>>
-				Your _clothes[0] and _clothes[1] are lying on the bench next to the lockers.
+				Your _clothes[0].name and _clothes[1].name are lying on the bench next to the lockers.
 				<br>
 			<<else>>
-				Your _clothes[0] is lying on the bench next to the lockers.
+				Your _clothes[0].name is lying on the bench next to the lockers.
 				<br>
 			<</if>>
 			<<link [[Put on|$passage]]>><<storeload _args[0]>><<set $eventskip to 1>><<set $wearoutfittext to 1>><</link>>
diff --git a/game/overworld-town/loc-street/events.twee b/game/overworld-town/loc-street/events.twee
index fd23818cd2..4ddb82db88 100644
--- a/game/overworld-town/loc-street/events.twee
+++ b/game/overworld-town/loc-street/events.twee
@@ -6224,7 +6224,7 @@ The <<person2>><<person>> looks concerned. "Are you injured?" <<he>> asks.
 	<br><br>
 	"Fuck," the <<person1>><<person>> says. "Can't I get any fucking privacy? The <<girl>> is a whore."
 	<br><br>
-	"Why are you gagging <<pher>> then?" the <<person2>><<person>> responds, unconvinced. The <<person1>><<person>> shoots you a dirty look, releases you, and runs.
+	"Why are you gagging <<phim>> then?" the <<person2>><<person>> responds, unconvinced. The <<person1>><<person>> shoots you a dirty look, releases you, and runs.
 	<br><br>
 
 	<<link [[Next|Street Bodywriting Rescue]]>><</link>>
@@ -6293,7 +6293,7 @@ The <<person2>><<person>> looks concerned. "Are you injured?" <<he>> asks.
 	<br><br>
 	"Fuck," the <<person1>><<person>> says. "Can't I get any fucking privacy? The <<girl>> is a whore."
 	<br><br>
-	"Why are you gagging <<pher>> then?" the <<person2>><<person>> responds, unconvinced. The <<person1>><<person>> shoots you a dirty look, releases you, and runs.
+	"Why are you gagging <<phim>> then?" the <<person2>><<person>> responds, unconvinced. The <<person1>><<person>> shoots you a dirty look, releases you, and runs.
 	<br><br>
 
 	<<link [[Next|Street Bodywriting Rescue]]>><</link>>
@@ -8435,7 +8435,7 @@ They seem pleased by your display, but you can tell by the look in their eyes th
 
 		"That was pathetic," the <<person2>><<person>> complains. "<<pShe>> didn't even cum!"
 		<br>
-		A devious smile grows on the <<person1>><<persons>> face. "Poor thing. Maybe we should lend <<pher>> a hand."
+		A devious smile grows on the <<person1>><<persons>> face. "Poor thing. Maybe we should lend <<phim>> a hand."
 		<br><br>
 
 		The three of them close in around you, blocking your escape.
@@ -8527,7 +8527,7 @@ They seem pleased by your display, but you can tell by the look in their eyes th
 
 		"What's that?" <<he>> sneers. "Speak up."
 		<br>
-		"I think <<pshe>> said we can do whatever we want with a slut like <<pher>>," the <<person3>><<person>> interjects. The <<group>> begins to close in around you.
+		"I think <<pshe>> said we can do whatever we want with a slut like <<phim>>," the <<person3>><<person>> interjects. The <<group>> begins to close in around you.
 	<<elseif $submissive lte 850>>
 		You angrily refuse their offer. The three seem annoyed by your behaviour.
 		<br><br>
@@ -9325,7 +9325,7 @@ Despite the <<persons>> sincere tone, you think better of accepting a ride from
 <<else>>
 	You realise what is happening and, before the <<person>> can walk away, pull open your <<outfit>>,
 	<<upperstrip>><<lowerstrip>><<exposure>>
-	exposing your <<undertop>> and <<undies>> with a triumphant smirk.
+	exposing your <<underoutfit>> with a triumphant smirk.
 	<br><br>
 	<<if $exposed gte 2>>
 		<<He>> blushes, not expecting this outcome, and hurriedly escapes the situation. <<He>> only remembers to redo <<his>> trench coat halfway down the street.
diff --git a/game/overworld-town/special-avery/main.twee b/game/overworld-town/special-avery/main.twee
index f94c6c668f..69596a6119 100644
--- a/game/overworld-town/special-avery/main.twee
+++ b/game/overworld-town/special-avery/main.twee
@@ -623,7 +623,7 @@ A click at the door snaps you from your reverie. Your heart races as it opens. A
 <<effects>><<pass 5>>
 A click at the door grabs your attention. Avery walks in, glancing around the room before smiling and walking over. "Glad to see you found your way, <<pcpetname "Avery">>. I have a delightful evening planned. Just the two of us."
 <br><br>
-<<He>> slides <<his>> jacket off, folding it neat and placing it on the nearset chair. "Let's order some dinner. They'll bring it right to us." <<He>> hands you a menu for room service. Looks like the hotel has a full restaurant, if the size of the menu is anything to go by.
+<<He>> slides <<his>> jacket off, folding it neat and placing it on the nearest chair. "Let's order some dinner. They'll bring it right to us." <<He>> hands you a menu for room service. Looks like the hotel has a full restaurant, if the size of the menu is anything to go by.
 <br><br>
 
 <<link [[Let Avery order for you|Avery Hotel Order]]>><<set $phase to 0>><<npcincr Avery love 1>><<set $endear += 10>><</link>><<glove>><<gendear>>
diff --git a/game/overworld-town/special-kylar/abduction_events.twee b/game/overworld-town/special-kylar/abduction_events.twee
index 7473e2ef95..e750ebdd0e 100644
--- a/game/overworld-town/special-kylar/abduction_events.twee
+++ b/game/overworld-town/special-kylar/abduction_events.twee
@@ -1,27 +1,29 @@
 :: Kylar Abduction Event End
 <<effects>>
 
+<<set _kylar to $NPCList[0]>>
+
 <<if $NPCName[$NPCNameList.indexOf("Kylar")].lust gte 100>>
 	<<switch $syndromekylarbuild>>
 		<<case 4>>
 			Kylar crawls towards you, and pulls <<himself>> up your legs.
-			<<if $NPCList[0].penis isnot "none">>
-				<<if ($genderknown.includes("Kylar") and $player.penisExist) or $player.gender_appearance is "m">>
-					<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
-				<<else>>
-					<<He>> straddles your thighs, pulling <<his>> body against yours.
-				<</if>>
+			<<if _kylar.penis isnot "none">>
+				<!-- Kylar penis - will try to fuck you -->
+				<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
+			<<elseif ($genderknown.includes("Kylar") and $player.penisExist) or $player.gender_appearance is "m">>
+				<!-- Kylar vag and you penis - will try to ride you -->
+				<<He>> straddles your thighs, pulling <<his>> body against yours.
 			<<else>>
-				<<if ($genderknown.includes("Kylar") and $player.vaginaExist) or $player.gender_appearance is "f">>
-					<<He>> straddles your thighs, pulling <<his>> body against yours.
-				<<else>>
-					<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
-				<</if>>
+				<!-- Kylar vag and you vag - will try to scissor -->
+				<<He>> spreads your legs, pulling <<his>> body against yours.
 			<</if>>
 			<br><br>
-			<<if ($genderknown.includes("Kylar") and ($player.penisExist and $NPCList[0].vagina isnot "none") or ($player.vaginaExist and $NPCList[0].penis isnot "none"))
-			or (($player.gender_appearance is "m" and $NPCList[0].vagina isnot "none") or ($player.gender_appearance is "f" and $NPCList[0].penis isnot "none")) and $pregnancyspeechdisable is "f">>
-				<<if $pronoun is "m">>
+			<<if $pregnancyspeechdisable is "f" and (
+				(_kylar.vagina isnot "none" and ($genderKnown.includes("Kylar") ? $player.penisExist : $player.gender_appearance is "m") ) 
+				or
+				(_kylar.penis isnot "none" and ($genderKnown.includes("Kylar") ? $player.vaginaExist : $player.gender_appearance is "f") )
+			)>>
+				<<if $pronoun is "f">>
 					"Your sperm is so delicious," <<he>> says. "It must be potent. S-so potent. I need you to mark me again and again."
 				<<else>>
 					"I need to mark you with my sperm," <<he>> says. "S-so the universe knows you're mine. N-no one else's!"
@@ -45,22 +47,22 @@
 			<br>
 		<<case 2>>
 			Kylar's eyes up your body, any anxiety overcome by lust.
-			<<if $NPCList[0].penis isnot "none">>
-				<<if ($genderknown.includes("Kylar") and $player.penisExist) or $player.gender_appearance is "m">>
-					<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
-				<<else>>
-					<<He>> straddles your thighs, pulling <<his>> body against yours.
-				<</if>>
+			<<if _kylar.penis isnot "none">>
+				<!-- Kylar penis - will try to fuck you -->
+				<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
+			<<elseif ($genderknown.includes("Kylar") and $player.penisExist) or $player.gender_appearance is "m">>
+				<!-- Kylar vag and you penis - will try to ride you -->
+				<<He>> straddles your thighs, pulling <<his>> body against yours.
 			<<else>>
-				<<if ($genderknown.includes("Kylar") and $player.vaginaExist) or $player.gender_appearance is "f">>
-					<<He>> straddles your thighs, pulling <<his>> body against yours.
-				<<else>>
-					<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
-				<</if>>
+				<!-- Kylar vag and you vag - will try to scissor -->
+				<<He>> spreads your legs, pulling <<his>> body against yours.
 			<</if>>
 			<br><br>
-			<<if ($genderknown.includes("Kylar") and ($player.penisExist and $NPCList[0].vagina isnot "none") or ($player.vaginaExist and $NPCList[0].penis isnot "none"))
-			or (($player.gender_appearance is "m" and $NPCList[0].vagina isnot "none") or ($player.gender_appearance is "f" and $NPCList[0].penis isnot "none")) and $pregnancyspeechdisable is "f">>
+			<<if $pregnancyspeechdisable is "f" and (
+				(_kylar.vagina isnot "none" and ($genderKnown.includes("Kylar") ? $player.penisExist : $player.gender_appearance is "m") ) 
+				or
+				(_kylar.penis isnot "none" and ($genderKnown.includes("Kylar") ? $player.vaginaExist : $player.gender_appearance is "f") )
+			)>>
 				<<if $pronoun is "m">>
 					<<He>> rubs your belly. "I'm going to get you pregnant with my child. I-I'm fertile. I'm sure of it!"
 				<<else>>
@@ -85,22 +87,22 @@
 		<<default>>
 			"A-ah, aha," Kylar pants, gazing at you with hunger in <<his>> eyes.
 
-			<<if $NPCList[0].penis isnot "none">>
-				<<if ($genderknown.includes("Kylar") and $player.penisExist) or $player.gender_appearance is "m">>
-					<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
-				<<else>>
-					<<He>> straddles your thighs, pulling <<his>> body against yours.
-				<</if>>
+			<<if _kylar.penis isnot "none">>
+				<!-- Kylar penis - will try to fuck you -->
+				<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
+			<<elseif ($genderknown.includes("Kylar") and $player.penisExist) or $player.gender_appearance is "m">>
+				<!-- Kylar vag and you penis - will try to ride you -->
+				<<He>> straddles your thighs, pulling <<his>> body against yours.
 			<<else>>
-				<<if ($genderknown.includes("Kylar") and $player.vaginaExist) or $player.gender_appearance is "f">>
-					<<He>> straddles your thighs, pulling <<his>> body against yours.
-				<<else>>
-					<<He>> lifts your thighs, and rests your legs against <<his>> shoulders.
-				<</if>>
+				<!-- Kylar vag and you vag - will try to scissor -->
+				<<He>> spreads your legs, pulling <<his>> body against yours.
 			<</if>>
 			<br><br>
-			<<if ($genderknown.includes("Kylar") and ($player.penisExist and $NPCList[0].vagina isnot "none") or ($player.vaginaExist and $NPCList[0].penis isnot "none"))
-			or (($player.gender_appearance is "m" and $NPCList[0].vagina isnot "none") or ($player.gender_appearance is "f" and $NPCList[0].penis isnot "none")) and $pregnancyspeechdisable is "f">>
+			<<if $pregnancyspeechdisable is "f" and (
+				(_kylar.vagina isnot "none" and ($genderKnown.includes("Kylar") ? $player.penisExist : $player.gender_appearance is "m") ) 
+				or
+				(_kylar.penis isnot "none" and ($genderKnown.includes("Kylar") ? $player.vaginaExist : $player.gender_appearance is "f") )
+			)>>
 				"We're going to make lots of babies," <<he>> says.
 			<</if>>
 			<<He>> gazes into your eyes with a mad intensity. "I'm going to fuck you again and again. Until I'm the only one who can satisfy you."
diff --git a/game/overworld-town/special-kylar/main.twee b/game/overworld-town/special-kylar/main.twee
index cb4c22153d..656ebe6649 100644
--- a/game/overworld-town/special-kylar/main.twee
+++ b/game/overworld-town/special-kylar/main.twee
@@ -1054,7 +1054,7 @@ The vicar turns to you. "Do you take Kylar as your <<person1>><<nnpc_wife "Kylar
 	The Vicar turns to Kylar, "Do you-"
 	<br><br>
 
-	"I do, yes." <<He>> says. "Can I kiss <<phim>> now?"
+	"I do, yes," <<he>> says. "Can I kiss <<phim>> now?"
 	<br><br>
 
 	The vicar nods. Kylar closes <<his>> eyes and licks <<his>> upper lip. <<He>> leans close.
diff --git a/game/overworld-town/special-robin/crossdressing.twee b/game/overworld-town/special-robin/crossdressing.twee
index 9f3107fd4a..7f2d20b5a3 100644
--- a/game/overworld-town/special-robin/crossdressing.twee
+++ b/game/overworld-town/special-robin/crossdressing.twee
@@ -117,7 +117,7 @@
 		<<else>>
 			Robin looks at you, <<his>> frown vanishing instantly. "R-really? Thank you. Thank you so much!"
 		<</if>>
-		There's a pause as <<he>> takes a deep breath. "Would you mind helping me sometime? With all this." <<He>> says, pausing a moment before continuing.
+		There's a pause as <<he>> takes a deep breath. "Would you mind helping me sometime? With all this," <<he>> says, pausing a moment before continuing.
 		"It's no pressure or anything, I just don't really have anyone else to ask. Actually you know just forget I said anything. You wanted to see me?"
 		Robin ignores any response to <<his>> earlier question.
 	<</if>>
@@ -640,7 +640,7 @@ you're left to stew in your curiosity.
 		"I just want to sell my <<print ($season is "winter" ? "hot chocolate" : "lemonade")>>, so if you're not going to buy anything could you please leave us alone?"
 		<br><br>
 
-		The <<person2>><<person>> doesn't seem dissuaded however. "I like it when they're feisty." <<He>> says before moving a hand towards Robin's crotch.
+		The <<person2>><<person>> doesn't seem dissuaded however. "I like it when they're feisty," <<he>> says before moving a hand towards Robin's crotch.
 		<<He>> doesn't get very far, however, before it's slapped away by Robin.
 		<br><br>
 
@@ -1203,7 +1203,7 @@ you're left to stew in your curiosity.
 	<br><br>
 
 	Robin groans on the floor while rubbing <<person1>><<his>> head. "I think I'm ok," <<he>> says between sniffles.
-	"Don't worry about me, I was just caught off guard." <<He>> says, wiping <<his>> eyes. "I'm fine, really."
+	"Don't worry about me, I was just caught off guard," <<he>> says, wiping <<his>> eyes. "I'm fine, really."
 	<br><br>
 
 	<<if $submissive gte 1150>>
diff --git a/game/overworld-town/special-robin/main.twee b/game/overworld-town/special-robin/main.twee
index 59dfa7d248..7a41b33c26 100644
--- a/game/overworld-town/special-robin/main.twee
+++ b/game/overworld-town/special-robin/main.twee
@@ -2317,7 +2317,7 @@ Robin leans on to you, panting, beads of sweat dripping down <<his>> naked body.
 	<<endevent>><<npc Robin>><<person1>>
 
 	Robin's arms wrap around you from behind. "You saved me," <<he>> says. "My hero." You feel your face flush too.
-	You sit and chat with Robin while you eat. "I'm going to wait in the classroom." <<He>> says when you finish. "I don't like being late."
+	You sit and chat with Robin while you eat. "I'm going to wait in the classroom," <<he>> says when you finish. "I don't like being late."
 	<<ltrauma>><<lstress>><<trauma -2>><<stress -4>><<pass 20>>
 	<br><br>
 
@@ -2334,7 +2334,7 @@ Robin leans on to you, panting, beads of sweat dripping down <<his>> naked body.
 	<<endevent>><<npc Robin>><<person1>>
 
 	Robin's arms wrap around you from behind. "You saved me," <<he>> says. "My hero." You feel your face flush.
-	You sit and chat with Robin while you eat. "I'm going to wait in the classroom." <<He>> says when you finish. "I don't like being late."
+	You sit and chat with Robin while you eat. "I'm going to wait in the classroom," <<he>> says when you finish. "I don't like being late."
 	<<ltrauma>><<lstress>><<trauma -2>><<stress -4>><<pass 20>>
 	<br><br>
 
@@ -2390,7 +2390,7 @@ Robin leans on to you, panting, beads of sweat dripping down <<his>> naked body.
 
 	Robin's arms wrap around you from behind.
 	"You saved me," <<he>> says. "My hero." You feel your face flush. You sit and chat with Robin while you eat.
-	"I'm going to wait in the classroom." <<He>> says when you finish. "I don't like being late."
+	"I'm going to wait in the classroom," <<he>> says when you finish. "I don't like being late."
 	<<ltrauma>><<lstress>><<trauma -2>><<stress -4>><<pass 20>>
 	<br><br>
 
diff --git a/game/overworld-town/special-robin/widgets.twee b/game/overworld-town/special-robin/widgets.twee
index fd1a1353ce..b8b7936585 100644
--- a/game/overworld-town/special-robin/widgets.twee
+++ b/game/overworld-town/special-robin/widgets.twee
@@ -141,7 +141,7 @@
 			<<set $robinconsoleintro to 1>><<set $robinconsole to 1>>
 			You knock on the door, and hear a flurry of activity on the other side. Robin throws the door open and hugs you.
 			"You came," <<he>> says. "Look." <<He>> pulls you into the room. In the corner beneath an old television is a new games console.
-			"I've been saving up." <<He>> says, sitting on the bed. "What are you waiting for?" <<He>> pats the bed beside <<him>>.
+			"I've been saving up," <<he>> says, sitting on the bed. "What are you waiting for?" <<He>> pats the bed beside <<him>>.
 			<<lstress>><<stress -12>>
 			<br><br>
 		<<elseif $robinconsole is 1 and $robinpaid isnot 1 and $robindebt gte ($robindebtlimit - 1) and $robinconsolelost isnot 1>>
@@ -386,7 +386,7 @@
 					<<if $robinconsole is 1>>
 						"Let me know if there's a game you'd like to play," <<he>> says. "You always let me choose."
 					<<else>>
-						"I like spending time with you." <<he>> says. "I'd choose your company over my console every day."
+						"I like spending time with you," <<he>> says. "I'd choose your company over my console every day."
 					<</if>>
 				<br><br>
 			<<elseif _robin.love gte 40 and _robin.lovestage is 2>>
diff --git a/game/overworld-town/special-sydney/temple.twee b/game/overworld-town/special-sydney/temple.twee
index 555f7af8a2..8bedc7f7b1 100644
--- a/game/overworld-town/special-sydney/temple.twee
+++ b/game/overworld-town/special-sydney/temple.twee
@@ -1241,7 +1241,11 @@ The two of you reluctantly rise after what feels like far too short of a time. Y
 
 :: Sydney Temple Corrupt End 2
 <<effects>>
-Sydney wraps <<his>> arms around you, and<<if $exposed gte 1>> offers you a towel to cover yourself. "Sorry, I must have wrecked some of your clothes."<<towelup>> He<</if>> kisses you on the cheek.
+Sydney wraps <<his>> arms around you, and
+<<if $exposed gte 1>>
+	offers you a towel to cover yourself. "Sorry, I must have wrecked some of your clothes." <<towelup>> <<He>>
+<</if>>
+kisses you on the cheek.
 <br><br>
 <<if !$sydneySeen.includes("corruptroom")>>
 	<<set $sydneySeen.pushUnique("corruptroom")>>
diff --git a/game/overworld-town/special-whitney/park.twee b/game/overworld-town/special-whitney/park.twee
index 8fbc97488e..92e985c4b0 100644
--- a/game/overworld-town/special-whitney/park.twee
+++ b/game/overworld-town/special-whitney/park.twee
@@ -199,7 +199,7 @@
 		You shove Whitney back, before scrambling backwards and getting to your feet. <<tearful>> you flee. Whitney is gone when you look back.
 	<<elseif $alarm is 1>>
 		Your cries for help attract attention, and Whitney shoves you backwards with a scowl.
-		"You're in luck this time." <<He>> says, fixing <<his>> clothes and storming off.
+		"You're in luck this time," <<he>> says, fixing <<his>> clothes and storming off.
 		<br><br>
 
 		<<tearful>> you rise to your feet.
diff --git a/game/overworld-town/special-whitney/street.twee b/game/overworld-town/special-whitney/street.twee
index c59d027842..56498ab9b4 100644
--- a/game/overworld-town/special-whitney/street.twee
+++ b/game/overworld-town/special-whitney/street.twee
@@ -2267,7 +2267,7 @@ Over <<his>> shoulder, you spy Whitney hiding under a parked car. <<nnpc_He "Whi
 
 	<<tearful>> you look around. Whitney's gone. <<He>> must have slipped away in the confusion.
 <<elseif $alarm is 1 and $rescue is 1>>
-	The <<person>> rears <<his>> hand back for another slap, but someone catches <<his>> wrist from behind. "No one makes <<pher>> cry but me." <span class="green">It's Whitney.</span>
+	The <<person>> rears <<his>> hand back for another slap, but someone catches <<his>> wrist from behind. "No one makes <<phim>> cry but me." <span class="green">It's Whitney.</span>
 	<<npc Whitney>><<person1>>
 	<br><br>
 
diff --git a/game/overworld-underground/loc-sewers/morgan.twee b/game/overworld-underground/loc-sewers/morgan.twee
index 00e7e307d9..c240ed01f4 100644
--- a/game/overworld-underground/loc-sewers/morgan.twee
+++ b/game/overworld-underground/loc-sewers/morgan.twee
@@ -823,9 +823,9 @@ You tell Morgan that this is disgusting and that you hate <<his>> cooking. This
 <<effects>><<set $location to "sewers">><<set $outside to 0>>
 
 <<if $exposed gte 2>>
-	You do as instructed. Morgan strips <<his>> clothing, and climbs on top of you. "Now, dear, stretch your legs back." <<He>> says. "Work hard and I'm sure you can get an A+."
+	You do as instructed. Morgan strips <<his>> clothing, and climbs on top of you. "Now, dear, stretch your legs back," <<he>> says. "Work hard and I'm sure you can get an A+."
 <<else>>
-	You do as instructed, blushing as you undress. Morgan strips too, and climbs on top of you. "Now, dear, stretch your legs back." <<He>> says. "Work hard and I'm sure you can get an A+."
+	You do as instructed, blushing as you undress. Morgan strips too, and climbs on top of you. "Now, dear, stretch your legs back," <<he>> says. "Work hard and I'm sure you can get an A+."
 	<<clothesstrip>>
 <</if>>
 <br><br>
diff --git a/game/overworld-underground/loc-sewers/old-sewers.twee b/game/overworld-underground/loc-sewers/old-sewers.twee
index f4b2496eb8..4f7654da5b 100644
--- a/game/overworld-underground/loc-sewers/old-sewers.twee
+++ b/game/overworld-underground/loc-sewers/old-sewers.twee
@@ -835,7 +835,7 @@ You find a safe sat on one of the tables. Something inside is ticking. At your t
 <br><br>
 "40...39...38..."
 <br><br>
-There's a keypad and a note with the numbers <<print random(0, 999)>> beside the safe. The last number has been torn off.
+There's a keypad and a note with the numbers <<print String(random(0, 999)).padStart(3, '0')>> beside the safe. The last number has been torn off.
 <br><br>
 You type in the three numbers, but what of the fourth?
 <br><br>
@@ -970,4 +970,4 @@ You lower yourself into the water and try to swim against the current.
 	<br><br>
 	<<link [[Next|Sewers Commercial]]>><</link>>
 	<br>
-<</if>>
\ No newline at end of file
+<</if>>
diff --git a/game/overworld-underground/loc-underground/events.twee b/game/overworld-underground/loc-underground/events.twee
index 87d09a4c7a..047f66fe05 100644
--- a/game/overworld-underground/loc-underground/events.twee
+++ b/game/overworld-underground/loc-underground/events.twee
@@ -1262,7 +1262,7 @@ The <<person1>><<person>> holds you close and continues to lick along your neck,
 The <<person1>><<person>> blinks, before frowning. "Aw... well, if you're sure, I guess. Would've loved to keep you for myself..." <<He>> reluctantly lets you go.
 <br><br>
 
-"We'll take <<pher>> from here," the <<person3>><<person>> says, walking toward you. "As per our agreement, you'll supply us with your nectar now-"
+"We'll take <<phim>> from here," the <<person3>><<person>> says, walking toward you. "As per our agreement, you'll supply us with your nectar now-"
 <br><br>
 
 The <<person1>><<person>> lazily flips <<person3>><<him>> off. A vine whips forward and <span class="green">smashes the camera, wrecking it</span>.
diff --git a/game/special-exhibition/main.twee b/game/special-exhibition/main.twee
index dd9254c17e..27fcd84b7c 100644
--- a/game/special-exhibition/main.twee
+++ b/game/special-exhibition/main.twee
@@ -81,7 +81,7 @@ You peek up and down the road, and see a car parked between the rows of stalls.
 <<set $outside to 1>><<set $location to "town">><<effects>><<set $bus to "connudatus">>
 <<fameexhibitionism 10>><<arousal 600>><<stress 6>><<trauma 6>>
 <<if $phase is 1>>
-	"Fine," the <<person>> grabs you by the neck and drags you into the daylight. "Look everyone." <<He>> shouts. "Look what I found!" Both hawkers and customers turn to investigate, and see you struggling to stand up, exposed and vulnerable. With nowhere to hide, there's not much you can do but flee.
+	"Fine," the <<person>> grabs you by the neck and drags you into the daylight. "Look everyone," <<he>> shouts. "Look what I found!" Both hawkers and customers turn to investigate, and see you struggling to stand up, exposed and vulnerable. With nowhere to hide, there's not much you can do but flee.
 	<br><br>
 <<else>>
 	You grab the underside of the stall and are hoisted into the air with it. The ride is too bumpy and your grip slips, causing you to drop painfully to the ground. The stall moves on without you, leaving you uncovered in the middle of the crowded street. With nowhere to hide, there's not much you can do but flee.
-- 
GitLab


From 31abf7bb169e920721f173f6622f6b6bfc5b9bfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=B6st?= <35009-Host@users.noreply.gitgud.io>
Date: Thu, 1 Sep 2022 22:51:01 +0000
Subject: [PATCH 21/50] Disable gardening and grooming with both arms tied

---
 game/base-system/tending.twee          | 121 +++++++++++---------
 game/overworld-town/loc-home/main.twee | 152 +++++++++++++++----------
 2 files changed, 158 insertions(+), 115 deletions(-)

diff --git a/game/base-system/tending.twee b/game/base-system/tending.twee
index b49db8bc95..332e9ac357 100644
--- a/game/base-system/tending.twee
+++ b/game/base-system/tending.twee
@@ -121,10 +121,14 @@
 					<<default>> <<set $_timeStr to "1:00">><<set _pass to 60>>
 				<</switch>>
 
-				<<if $images is 1 and $_plantedPlant.icon>>
-					<img class="tending_icon" @src="`img/misc/icon/tending/` + $_plantedPlant.icon">
+				<<if $leftarm is "bound" and $rightarm is "bound">>
+					<span class="red">Can't pick when your arms are bound.</span>
+				<<else>>
+					<<if $images is 1 and $_plantedPlant.icon>>
+						<img class="tending_icon" @src="`img/misc/icon/tending/` + $_plantedPlant.icon">
+					<</if>>
+					<<link "Pick ($_timeStr)" $passage>><<pass _pass>><<tending_harvest _plantbed>><<clear_plot _plantbed>><</link>>
 				<</if>>
-				<<link "Pick ($_timeStr)" $passage>><<pass _pass>><<tending_harvest _plantbed>><<clear_plot _plantbed>><</link>>
 				<br>
 
 			<<elseif _plantbed.stage is 4>>
@@ -176,9 +180,11 @@
 		<<if $location is "alex_farm" and _plotsToWater.length gte $_hoursUntilAttack>>
 			<span class="pink">You won't have enough time to water all your fields before Remy's arrival.</span>
 		<<else>>
-			<<link "Water all dry beds ($_time)" $passage>>
-				<<tendingWaterAllDryBeds _plotsToWater>><<tiredness _water_needed>><<physique _water_needed>><<tending _water_needed>>
-			<</link>><<gtiredness>><<gtending>>
+			<<if !($leftarm is "bound" and $rightarm is "bound")>>
+				<<link "Water all dry beds ($_time)" $passage>>
+					<<tendingWaterAllDryBeds _plotsToWater>><<tiredness _water_needed>><<physique _water_needed>><<tending _water_needed>>
+				<</link>><<gtiredness>><<gtending>>
+			<</if>>
 		<</if>>
 		<br>
 
@@ -202,10 +208,14 @@
 	<</switch>>
 
 	<<set $_time to getTimeString(_tPass)>>
-	<<link "Water ($_time)" $passage>>
-		<<tending _tStatup>><<pass _tPass>><<set _plantbed.water to 1>><<set $tendingvars.plot_watered to true>>
-		<<tiredness _tStatup>><<physique _tStatup>><<event_trigger>>
-	<</link>><<gtiredness>><<gtending>>
+	<<if $leftarm is "bound" and $rightarm is "bound">>
+		<span class="red">Can't water when your arms are bound.</span>
+	<<else>>
+		<<link "Water ($_time)" $passage>>
+			<<tending _tStatup>><<pass _tPass>><<set _plantbed.water to 1>><<set $tendingvars.plot_watered to true>>
+			<<tiredness _tStatup>><<physique _tStatup>><<event_trigger>>
+		<</link>><<gtiredness>><<gtending>>
+	<</if>>
 <</widget>>
 
 <<widget "tendingWaterAllDryBeds">>
@@ -288,52 +298,57 @@
 	<<if $farm_attack_timer is 0>>
 		<<set $_timeUntilAttack to ((23 - $hour) * 60) + (60 - $minute)>>
 	<</if>>
-	<<if $location is "alex_farm" and _baseTime gte $_timeUntilAttack>>
-		<span class="pink">Not enough time to till the field before Remy's arrival.</span>
+	<<if $leftarm is "bound" and $rightarm is "bound">>
+		<span class="red">Can't till when your arms are bound.</span>
+		<br>
 	<<else>>
-		<<capture _baseTiredsness _baseTime _plantbed>>
-			<<link "Till (_timeString)" $passage>>
-				<<set $tendingvars.plot_tilled to true>>
-				<<tiredness _baseTiredsness>><<physique _baseTiredsness>>
-				<<pass _baseTime>>
-				<<if $location is "farm">>
-					<<farm_count _baseTime>>
-				<</if>>
-				<<set _plantbed.till to 1>>
-			<</link>><<gtiredness>>
-		<</capture>>
-	<</if>>
-	<br>
-	<<if $fertiliser.current gte 1 and _plantbed.quality lt 4 and currentSkillValue('tending') gte 400>>
-		<<set _baseTimeFert to Math.floor(_baseTime * 1.5)>>
-		<<set _timeString to getTimeString(_baseTimeFert)>>
-		<<set _fertTiredness to Math.floor(_baseTiredsness * 1.5)>>
-		<<capture _baseTimeFert _fertTiredness _plantbed>>
-			<<link "Till and apply fertiliser (_timeString)" $passage>>
-				/* Till */
-				<<set $tendingvars.plot_tilled_fertiliser to true>>
-				<<tiredness _fertTiredness>><<physique _fertTiredness>>
-				<<pass _baseTimeFert>>
-				<<if $location is "farm">>
-					<<farm_count _baseTimeFert>>
-				<</if>>
-				<<set _plantbed.till to 1>>
-
-				/* Fertilise */
-				<<set $fertiliser.current-->><<set $fertiliser.used++>>
-				<<set _plantbed.quality++>>
-				<<if !$backgroundTraits.includes("greenthumb")>>
-					<<if _plantbed.baseQuality is undefined>>
-						<<set _plantbed.baseQuality to clone(_plantbed.quality - 1)>>
-					<</if>>
-					<<set _plantbed.fertiliserDecay to 2>>
-					<<if _plantbed.size isnot "large">>
-						<<set _plantbed.fertiliserDecay++>>
+		<<if $location is "alex_farm" and _baseTime gte $_timeUntilAttack>>
+			<span class="pink">Not enough time to till the field before Remy's arrival.</span>
+		<<else>>
+			<<capture _baseTiredsness _baseTime _plantbed>>
+				<<link "Till (_timeString)" $passage>>
+					<<set $tendingvars.plot_tilled to true>>
+					<<tiredness _baseTiredsness>><<physique _baseTiredsness>>
+					<<pass _baseTime>>
+					<<if $location is "farm">>
+						<<farm_count _baseTime>>
 					<</if>>
-				<</if>>
-			<</link>><<gtiredness>>
-		<</capture>>
+					<<set _plantbed.till to 1>>
+				<</link>><<gtiredness>>
+			<</capture>>
+		<</if>>
 		<br>
+		<<if $fertiliser.current gte 1 and _plantbed.quality lt 4 and currentSkillValue('tending') gte 400>>
+			<<set _baseTimeFert to Math.floor(_baseTime * 1.5)>>
+			<<set _timeString to getTimeString(_baseTimeFert)>>
+			<<set _fertTiredness to Math.floor(_baseTiredsness * 1.5)>>
+			<<capture _baseTimeFert _fertTiredness _plantbed>>
+				<<link "Till and apply fertiliser (_timeString)" $passage>>
+					/* Till */
+					<<set $tendingvars.plot_tilled_fertiliser to true>>
+					<<tiredness _fertTiredness>><<physique _fertTiredness>>
+					<<pass _baseTimeFert>>
+					<<if $location is "farm">>
+						<<farm_count _baseTimeFert>>
+					<</if>>
+					<<set _plantbed.till to 1>>
+
+					/* Fertilise */
+					<<set $fertiliser.current-->><<set $fertiliser.used++>>
+					<<set _plantbed.quality++>>
+					<<if !$backgroundTraits.includes("greenthumb")>>
+						<<if _plantbed.baseQuality is undefined>>
+							<<set _plantbed.baseQuality to clone(_plantbed.quality - 1)>>
+						<</if>>
+						<<set _plantbed.fertiliserDecay to 2>>
+						<<if _plantbed.size isnot "large">>
+							<<set _plantbed.fertiliserDecay++>>
+						<</if>>
+					<</if>>
+				<</link>><<gtiredness>>
+			<</capture>>
+			<br>
+		<</if>>
 	<</if>>
 <</widget>>
 
diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index 7923707e82..827fa6421c 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -617,7 +617,12 @@ You are in the bathroom.
 <<if $stress gte $stressmax>>
 	<<passouthome>>
 <<else>>
-	<<ind>><<link [[Have a bath (0:30)->Bath]]>><<strip>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
+	<<if $leftarm is "bound" and $rightarm is "bound">>
+		<<set _clothed = ![V.worn.upper.name, V.worn.lower.name, V.worn.under_upper.name, V.worn.under_lower.name, V.worn.over_upper.name, V.worn.over_lower.name].every(x => x == 'naked')>>
+		<<ind>><<link [["Have a bath " + (_clothed ? " in clothes " : "") + "(0:30)"->Bath]]>><<water>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
+	<<else>>
+		<<ind>><<link [[Have a bath (0:30)->Bath]]>><<strip>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
+	<</if>>
 	<br>
 	<!-- Check if there's any hair-->
 	<<if $pbdisable is "f" and ($pblevel gte 2 or $pbstrip gte 1 or $pblevelballs gte 2)>>
@@ -1287,7 +1292,11 @@ As you remove the plug to drain the water, you feel something probe your <<genit
 		<<if $exhibitionism gte 75 and $uncomfortable.nude is false>>
 			You yelp in surprise, but make no effort to hide your <<lewdness>>. They stare at you with wide eyes, surprised you are letting them. The <<person1>><<person>> grins and closes the door.
 		<<else>>
-			You cover your <<lewdness>>. They stare at you with wide eyes. The <<person1>><<person>> grins and closes the door.
+			<<if $leftarm is "bound" and $rightarm is "bound">>
+				You want to cover your <<lewdness>>, but with <span class="red">your arms bound</span> you can't. You feel deep embarrassement and your face reddens.<<stress 6>> They stare at you with wide eyes. The <<person1>><<person>> grins and closes the door.
+			<<else>>
+				You cover your <<lewdness>>. They stare at you with wide eyes. The <<person1>><<person>> grins and closes the door.
+			<</if>>
 		<</if>>
 			<br><br>
 
@@ -1309,7 +1318,11 @@ As you remove the plug to drain the water, you feel something probe your <<genit
 		<<if $exhibitionism gte 75 and $uncomfortable.nude is false>>
 			You yelp in surprise, but make no effort to hide your <<lewdness>>. They stare at you with wide eyes, surprised you are letting them. The <<person1>><<person>> grins and closes the door.
 		<<else>>
-			You cover your <<lewdness>>. They stare at you with wide eyes. The <<person1>><<person>> grins and closes the door.
+			<<if $leftarm is "bound" and $rightarm is "bound">>
+				You want to cover your <<lewdness>>, but with <span class="red">your arms bound</span> you can't. You feel deep embarrassement and your face reddens.<<stress 6>> They stare at you with wide eyes. The <<person1>><<person>> grins and closes the door.
+			<<else>>
+				You cover your <<lewdness>>. They stare at you with wide eyes. The <<person1>><<person>> grins and closes the door.
+			<</if>>
 		<</if>>
 
 		<<if $player.penisExist and ($player.penissize lte 1 or $player.penissize is 4) and random(0,9) gte 6>>
@@ -1338,27 +1351,35 @@ You wash until you're squeaky clean.<<wash>>
 :: Bath Finish
 <<effects>><<set $location to "home">><<set $outside to 0>>
 
-Your skin is still damp.
+<<if $upperwetstage >= 3 or $lowerwetstage >= 3 or $underupperwetstage >= 3 or $underlowerwetstage >= 3 or $overupperwetstage >= 3 or $overlowerwetstage >= 3>>
+	Your clothes are drenched, water drips from you onto the floor.
+<<else>>
+	Your skin is still damp.
+<</if>>
 <br><br>
-<<link [[Dress as you were|Bathroom]]>><<clotheson>><</link>>
-<br>
-<<link [[Wrap yourself in a towel|Bathroom]]>>
-	<<if $player.gender == "f" or $player.breastsize > 0>>
-		<<set $wear_upper = "large_towel">>
-	<<else>>
-		<<set $wear_lower = "towel">>
-	<</if>>
-	<<returnCarried>>
-	<<wardrobewear>>
-<</link>>
-
-<<if $wardrobe.upper.findIndex(x => x.name == "bathrobe") >= 0 or $carried.upper.name == "bathrobe">>
+<<if $leftarm is "bound" and $rightarm is "bound">>
+	<<link [[Next|Bathroom]]>><</link>>
+<<else>>
+	<<link [[Dress as you were|Bathroom]]>><<clotheson>><</link>>
 	<br>
-	<<link [[Put on a bathrobe|Bathroom]]>>
+	<<link [[Wrap yourself in a towel|Bathroom]]>>
+		<<if $player.gender == "f" or $player.breastsize > 0>>
+			<<set $wear_upper = "large_towel">>
+		<<else>>
+			<<set $wear_lower = "towel">>
+		<</if>>
 		<<returnCarried>>
-		<<set $wear_upper = $wardrobe.upper.findIndex(x => x.name == "bathrobe")>>
 		<<wardrobewear>>
 	<</link>>
+
+	<<if $wardrobe.upper.findIndex(x => x.name == "bathrobe") >= 0 or $carried.upper.name == "bathrobe">>
+		<br>
+		<<link [[Put on a bathrobe|Bathroom]]>>
+			<<returnCarried>>
+			<<set $wear_upper = $wardrobe.upper.findIndex(x => x.name == "bathrobe")>>
+			<<wardrobewear>>
+		<</link>>
+	<</if>>
 <</if>>
 
 :: Passout home
@@ -2698,60 +2719,67 @@ You grab your clothes and dress with haste.
 
 :: Shave
 <<effects>>
-<<dontHideForNow>><<shavestrip>>
-You take off your clothes and look at your <<genitals>>.
-<br>
-<<if $worn.genitals.name is "chastity belt" or $worn.genitals.name is "gold chastity belt">>
-The belt fits snug against your body and it seems that reaching pubes with a razor is almost impossible.
-<br>
-<<link [[Dress up->Bathroom]]>><<clotheson>><<dontHideRevert>><</link>>
-<<else>>
-<<if $worn.genitals.name is "chastity cage">>
-Your penis is locked inside the cage. Shaving around it will be a bit more tricky, but that's not a big deal.
-<br>
-<</if>>
-<<if $pblevel gte 2 or $pbstrip gte 1 or $pblevelballs gte 2>>
-	<<link [[Shave clean (0:15)->Shave clean]]>><<pass 15>><<arousal 100>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<set $pbstrip to 0>><<set $makeup.pbcolour to 0>><</link>>
+<<dontHideForNow>>
+<<if $leftarm is "bound" and $rightarm is "bound">>
+	<span class="red">Both of your arms are bound</span> and you find it difficult to do anything about your pubes this way.
 	<br>
-<</if>>
-<<if $pblevel gte 5 or $pbstrip gte 2 or ($pbstrip is 1 and $pblevel gte 2)>>
-	<<link [[Form a landing strip (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat landing strip">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 1>><</link>>
+	<<link [[Back->Bathroom]]>><<dontHideRevert>><</link>>
+<<else>>
+	<<shavestrip>>
+	You take off your clothes and look at your <<genitals>>.
 	<br>
-<</if>>
-<<if $pblevel gte 5 or $pbstrip gte 3 or ($pbstrip gte 2 and $pblevel gte 2)>>
-	<<link [[Form a heart (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "cute heart shape">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 2>><</link>>
+	<<if $worn.genitals.name is "chastity belt" or $worn.genitals.name is "gold chastity belt">>
+	The belt fits snug against your body and it seems that reaching pubes with a razor is almost impossible.
 	<br>
-<</if>>
-<<if $pblevel gte 5 or $pbstrip gte 4 or ($pbstrip gte 3 and $pblevel gte 2)>>
-	<<link [[Form a triangle (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat triangle">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 3>><</link>>
+	<<link [[Dress up->Bathroom]]>><<clotheson>><<dontHideRevert>><</link>>
+	<<else>>
+	<<if $worn.genitals.name is "chastity cage">>
+	Your penis is locked inside the cage. Shaving around it will be a bit more tricky, but that's not a big deal.
 	<br>
-<</if>>
-<<if $player.ballsExist is true>>
-	<<if $pblevel gte 2 or $pbstrip gte 1>>
-		<<link [[Shave only pubis (0:10)->Shave pubis]]>><<pass 10>><<arousal 50>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 0>><<if $pblevelballs is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
+	<</if>>
+	<<if $pblevel gte 2 or $pbstrip gte 1 or $pblevelballs gte 2>>
+		<<link [[Shave clean (0:15)->Shave clean]]>><<pass 15>><<arousal 100>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<set $pbstrip to 0>><<set $makeup.pbcolour to 0>><</link>>
 		<br>
 	<</if>>
-	<<if $pblevelballs gte 3>>
-		<<link [[Shave only balls (0:05)->Shave balls]]>><<pass 5>><<arousal 50>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<if $pblevel is 0 and $pbstrip is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
+	<<if $pblevel gte 5 or $pbstrip gte 2 or ($pbstrip is 1 and $pblevel gte 2)>>
+		<<link [[Form a landing strip (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat landing strip">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 1>><</link>>
 		<br>
 	<</if>>
-<</if>>
-<<if $pblevel gt 5 or $pblevelballs gt 5>>
-	<<link [[Trim short (0:10)->Shave trim]]>><<pass 10>><<arousal 100>>
-		<<if $pblevel gte 5>>
-			<<set $pblevel to 5>><<set $pbgrowth to 7>><<set $pbstrip to 0>>
+	<<if $pblevel gte 5 or $pbstrip gte 3 or ($pbstrip gte 2 and $pblevel gte 2)>>
+		<<link [[Form a heart (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "cute heart shape">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 2>><</link>>
+		<br>
+	<</if>>
+	<<if $pblevel gte 5 or $pbstrip gte 4 or ($pbstrip gte 3 and $pblevel gte 2)>>
+		<<link [[Form a triangle (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat triangle">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 3>><</link>>
+		<br>
+	<</if>>
+	<<if $player.ballsExist is true>>
+		<<if $pblevel gte 2 or $pbstrip gte 1>>
+			<<link [[Shave only pubis (0:10)->Shave pubis]]>><<pass 10>><<arousal 50>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 0>><<if $pblevelballs is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
+			<br>
 		<</if>>
-		<<if $pblevelballs gte 5>>
-			<<set $pblevelballs to 5>><<set $pbgrowthballs to 10>>
+		<<if $pblevelballs gte 3>>
+			<<link [[Shave only balls (0:05)->Shave balls]]>><<pass 5>><<arousal 50>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<if $pblevel is 0 and $pbstrip is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
+			<br>
 		<</if>>
-	<</link>>
-	<br>
-<</if>>
-<<if $worn.genitals.name isnot "chastity belt">>
-	<<link [[Dye pubic hair->Dye pubic hair]]>><</link>>
-	<br>
+	<</if>>
+	<<if $pblevel gt 5 or $pblevelballs gt 5>>
+		<<link [[Trim short (0:10)->Shave trim]]>><<pass 10>><<arousal 100>>
+			<<if $pblevel gte 5>>
+				<<set $pblevel to 5>><<set $pbgrowth to 7>><<set $pbstrip to 0>>
+			<</if>>
+			<<if $pblevelballs gte 5>>
+				<<set $pblevelballs to 5>><<set $pbgrowthballs to 10>>
+			<</if>>
+		<</link>>
+		<br>
+	<</if>>
+	<<if $worn.genitals.name isnot "chastity belt">>
+		<<link [[Dye pubic hair->Dye pubic hair]]>><</link>>
+		<br>
+	<</if>>
+	<<link [[Don't shave anything->Bathroom]]>><<clotheson>><<dontHideRevert>><</link>>
 <</if>>
-<<link [[Don't shave anything->Bathroom]]>><<clotheson>><<dontHideRevert>><</link>>
 <</if>>
 
 :: Shave clean
-- 
GitLab


From e27a207bff7cdab976ee17fe1c402971b929631b Mon Sep 17 00:00:00 2001
From: Pumping Lemma <pumping.lemma@email.com>
Date: Fri, 2 Sep 2022 22:33:40 +0000
Subject: [PATCH 22/50] Fix: Double anal

---
 game/base-combat/man-combat.twee | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/game/base-combat/man-combat.twee b/game/base-combat/man-combat.twee
index c242b8ad4c..693ccc351f 100644
--- a/game/base-combat/man-combat.twee
+++ b/game/base-combat/man-combat.twee
@@ -3167,7 +3167,7 @@ and clicks <<his>> fingers.
 									<<sex 10 _n>><<set $speechanusentrance to 1>>
 								<<case 2>>
 									<<if $anusWetness gte ($NPCList[_n].penissize * 15) + random(1, 40) or random(0, 2) is 2>>
-										<<if $npcSub>>You rub<<else>><<He>> rubs<</if>> <<his>> $NPCList[_n].penisdesc against your anus and your $worn.butt_plug.name, a thrust away from penetrating.
+										<<anus_lube_text>><<if $npcSub>>you press<<else>><<he>> presses<</if>> <<his>> $NPCList[_n].penisdesc against your anus and your $worn.butt_plug.name, <span class="pink">a thrust away from penetrating.</span>
 										<<sex 10 _n>><<set $NPCList[_n].penis to "anusimminent">><<set $anusstate to "imminent">><<set $speechanusimminent to 1>>
 									<<else>>
 										<<if $npcSub>>You push<<else>><<He>> pushes<</if>> <<his>> $NPCList[_n].penisdesc against your <<bottom>> and your $worn.butt_plug.name, <span class="blue">but fail<<if !$npcSub>>s<</if>> to penetrate,</span> instead angling away and rubbing it between your cheeks.
@@ -3448,8 +3448,9 @@ and clicks <<his>> fingers.
 									<<sex 10 _n>><<set $speechanusentrance to 1>>
 								<<case 2>>
 									<<if $anusWetness gte ($NPCList[_n].penissize * 15) + random(1, 40) or random(0, 2) is 2>>
-										<<if $npcSub>>You rub<<else>><<He>> rubs<</if>> <<his>> $NPCList[_n].penisdesc against your anus and your $worn.butt_plug.name, a thrust away from penetrating.
-										<<sex 10 _n>><<set $NPCList[_n].penis to "anusimminent">><<set $anusstate to "imminent">><<set $speechanusimminent to 1>>
+										<<anus_lube_text>><<if $npcSub>>you press<<else>><<he>> presses<</if>> <<his>> $NPCList[_n].penisdesc against your anus and your $worn.butt_plug.name, <span class="pink">a thrust away from penetrating.</span>
+										<<sex 10 _n>><<set $NPCList[_n].penis to "anusimminentdouble">>
+										<<if $anusstate isnot "doublepenetrated">><<set $anusstate to "doubleimminent">><</if>><<set $speechanusimminent to 1>>
 									<<else>>
 										<<if $npcSub>>You push<<else>><<He>> pushes<</if>> <<his>> $NPCList[_n].penisdesc against your <<bottom>> and your $worn.butt_plug.name, <span class="blue">but fail<<if !$npcSub>>s<</if>> to penetrate,</span> instead angling away and rubbing it between your cheeks.
 										<<sex 5 _n>><<set $speechanusimminent to 1>>
-- 
GitLab


From d3da62dd0889b2b2097e3193311b76deb19fc51b Mon Sep 17 00:00:00 2001
From: xao <33469-xao321@users.noreply.gitgud.io>
Date: Fri, 2 Sep 2022 22:50:12 +0000
Subject: [PATCH 23/50] Options menu rework and overlay changes

---
 DolSettingsExport.json                        |   51 +-
 game/01-config/start.twee                     |    6 +-
 game/03-JavaScript/IronMan.js                 |   10 +-
 game/03-JavaScript/UI.js                      |   40 +-
 game/03-JavaScript/base.js                    |   46 +-
 game/03-JavaScript/ingame.js                  |    2 +-
 game/03-JavaScript/save.js                    |   57 +-
 game/03-JavaScript/scroll-bar.js              |    2 +-
 game/03-JavaScript/tabs.js                    |   30 +
 game/03-JavaScript/theme.js                   |    6 +-
 game/04-Variables/presets.twee                |   28 +-
 .../04-Variables/variables-passageFooter.twee |   14 +-
 game/04-Variables/variables-start.twee        |   50 +-
 game/04-Variables/variables-start2.twee       |    6 -
 .../04-Variables/variables-versionUpdate.twee |   41 +
 game/base-clothing/canvasmodel-img.twee       |   14 +-
 game/base-clothing/clothing-sets.twee         |    2 -
 game/base-clothing/images.twee                |   34 +-
 game/base-clothing/lighting.twee              |   78 +-
 game/base-clothing/wardrobes.twee             |    2 +-
 game/base-combat/actions-feet.twee            |    4 +-
 game/base-combat/actions-hands.twee           |   56 +-
 game/base-combat/actions-speech.twee          |    4 +-
 game/base-combat/actions.twee                 |    6 +-
 game/base-combat/actionsGeneration.twee       |  192 +--
 game/base-combat/beast-images.twee            |   18 +-
 game/base-combat/close-images.twee            |    4 +-
 game/base-combat/doggy-images.twee            |   30 +-
 game/base-combat/ejaculation.twee             |    4 +-
 game/base-combat/images.twee                  |    4 +-
 game/base-combat/init.twee                    |    8 +-
 game/base-combat/machine/actions.twee         |   36 +-
 game/base-combat/missionary-images.twee       |   22 +-
 game/base-combat/stalk/stalk.twee             |    2 +-
 game/base-combat/state.twee                   |    8 +-
 game/base-combat/struggle.twee                |   74 +-
 game/base-combat/swarm-effects.twee           |   62 +-
 game/base-combat/tentacles/abomination.twee   |   26 +-
 .../tentacles/tentacle-images.twee            |    4 +-
 .../tentacles/tentacleActionsGeneration.twee  |   80 +-
 game/base-combat/tentacles/tentacles.twee     |    2 +-
 game/base-combat/vore.twee                    |   24 +-
 game/base-combat/widgets.twee                 |    4 +-
 game/base-debug/clothesTesting.twee           |   14 +-
 game/base-debug/test demon.twee               |    2 +-
 game/base-debug/testing-skinColor.twee        |   42 +-
 game/base-system/caption.twee                 |  146 +--
 game/base-system/images.twee                  |   30 +-
 game/base-system/mobileStats.twee             |   15 +-
 .../base-system/overlays/characteristics.twee |   23 +-
 game/base-system/overlays/cheats.twee         |  132 +-
 game/base-system/overlays/featsUI.twee        |    5 +-
 game/base-system/overlays/journal.twee        |    9 +-
 game/base-system/overlays/options.twee        |  385 +++---
 game/base-system/overlays/overlayReplace.twee |  393 +++---
 .../overlays/saves-export-import.twee         |    7 +-
 game/base-system/overlays/saves.twee          |    5 +-
 game/base-system/overlays/social.twee         |   44 +-
 game/base-system/overlays/statistics.twee     | 1076 +++++++++--------
 game/base-system/settings.twee                |  168 +--
 game/base-system/skinColor.twee               |   32 +-
 game/base-system/tending.twee                 |    8 +-
 game/base-system/text.twee                    |    4 +-
 game/base-system/widgets.js                   |    8 +-
 game/base-system/widgets.twee                 |   94 +-
 .../loc-estate/cards_widgets.twee             |    1 -
 game/overworld-plains/loc-farm/widgets.twee   |    2 +-
 .../loc-livestock/widgets.twee                |    2 +-
 game/overworld-town/loc-alley/commercial.twee |    4 +-
 game/overworld-town/loc-alley/industrial.twee |    4 +-
 game/overworld-town/loc-alley/park.twee       |    4 +-
 .../overworld-town/loc-alley/residential.twee |    4 +-
 game/overworld-town/loc-brothel/main.twee     |    2 +-
 game/overworld-town/loc-cafe/main.twee        |    2 +-
 game/overworld-town/loc-cafe/widgets.twee     |    2 +-
 game/overworld-town/loc-market/widgets.twee   |    6 +-
 .../overworld-town/loc-prison/punishment.twee |    8 +-
 game/overworld-town/loc-prison/widgets.twee   |    2 +-
 game/overworld-town/loc-prison/work.twee      |   16 +-
 game/overworld-town/loc-shop/clothing-v2.twee |   52 +-
 .../loc-shop/clothingCategories-v2.twee       |   30 +-
 game/overworld-town/loc-shop/widgets.twee     |    6 +-
 game/overworld-town/loc-street/barb.twee      |    4 +-
 game/overworld-town/loc-street/cliff.twee     |    4 +-
 .../overworld-town/loc-street/connudatus.twee |    4 +-
 game/overworld-town/loc-street/danube.twee    |    4 +-
 game/overworld-town/loc-street/domus.twee     |    4 +-
 game/overworld-town/loc-street/elk.twee       |    4 +-
 game/overworld-town/loc-street/exposed.twee   |    4 +-
 game/overworld-town/loc-street/harvest.twee   |    4 +-
 game/overworld-town/loc-street/high.twee      |    4 +-
 game/overworld-town/loc-street/mer.twee       |    4 +-
 .../loc-street/nightingale.twee               |    4 +-
 game/overworld-town/loc-street/oxford.twee    |    4 +-
 game/overworld-town/loc-street/starfish.twee  |    4 +-
 game/overworld-town/loc-street/wolf.twee      |    4 +-
 game/overworld-town/mapLocations.twee         |   12 +-
 .../loc-underground/robin.twee                |    8 +-
 game/special-masturbation/widgets.twee        |    2 +-
 .../battleTestControls/characterDebug.js      |    2 -
 modules/css/base.css                          |  233 +++-
 101 files changed, 2321 insertions(+), 1974 deletions(-)
 create mode 100644 game/03-JavaScript/tabs.js

diff --git a/DolSettingsExport.json b/DolSettingsExport.json
index 06be00f850..f8bf29266b 100644
--- a/DolSettingsExport.json
+++ b/DolSettingsExport.json
@@ -72,43 +72,48 @@ DolSettingsExport = {
 		"bottomsizemax":8,
 		"penissizemax":4,
 		"penissizemin":-2,
-		"images":1,
-		"sidebarAnimations": true,
-		"combatAnimations": true,
-		"bodywritingImages": true,
-		"silhouettedisable":false,
 		"numberify_enabled":1,
 		"timestyle":"military",
 		"tipdisable":false,
 		"debugdisable":true,
 		"statdisable":false,
 		"cheatdisabletoggle":true,
-		"showCaptionText":true,
 		"confirmSave":false,
 		"confirmLoad":false,
 		"confirmDelete":false,
-		"lightSpotlight": 0.2,
-		"lightGradient": 0,
-		"lightGlow": 0,
-		"lightFlat": 0,
-		"lightCombat": 0.2,
-		"lightTFColor": 0.2,
-		"sidebarStats":"Disabled",
-		"sidebarTime":"Disabled",
-		"combatControls":"radio",
 		"reducedLineHeight":false,
-		"neverNudeMenus":false,
-		"skipStatisticsConfirmation":false,
 		"multipleWardrobes":"isolated",
 		"outfitEditorPerPage":10,
-		"map":{
-			"movement":true,
-			"top":false,
-			"markers":false
-		},
-		"skinColor":{
+		"options":{
+			"neverNudeMenus":false,
+			"showCaptionText":true,
+			"sidebarStats":"disabled",
+			"sidebarTime":"disabled",
+			"combatControls":"radio",
+			"mapMovement":true,
+			"mapTop":false,
+			"mapMarkers":false,
+			"images":1,
+			"combatImages":1,
+			"bodywritingImages": true,
+			"silhouetteEnabled":true,
 			"tanImgEnabled": true,
 			"tanningEnabled": true,
+			"sidebarAnimations": true,
+			"blinkingEnabled": true,
+			"combatAnimations": true,
+			"halfClosedEnabled": false,
+			"characterLightEnabled": true,
+			"lightSpotlight": 0.2,
+			"lightGradient": 0.1,
+			"lightGlow": 0.1,
+			"lightFlat": 0,
+			"lightCombat": 0.2,
+			"lightTFColor": 0.2,
+			"maxStates": 1,
+			"newWardrobeStyle": true,
+			"useNarrowMarket": false,
+			"skipStatisticsConfirmation":false,
 		},
 		"shopDefaults": {
 			"alwaysBackToShopButton":false,
diff --git a/game/01-config/start.twee b/game/01-config/start.twee
index c403f1b605..4914f3c933 100644
--- a/game/01-config/start.twee
+++ b/game/01-config/start.twee
@@ -14,11 +14,11 @@ Degrees of Lewdity
 <</if>>
 <!-- <<effects>> --> <!-- commented this out - why were we running effects without a working player init'd? -->
 
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<img class="resize" src="img/misc/banner.png">
 <</if>>
 
-This work of fiction contains content of a sexual nature and is inappropriate for minors. All characters <span class="camouflage text"><a onclick="V.debug = 1, V.debugdisable = 'f', V.maxStates = 5">de</a></span>picted are at least 18 years of age. Everything is consensual role play, and any animals are actually people in costumes.
+This work of fiction contains content of a sexual nature and is inappropriate for minors. All characters <span class="camouflage text"><a onclick="V.debug = 1, V.debugdisable = 'f', V.options.maxStates = 5">de</a></span>picted are at least 18 years of age. Everything is consensual role play, and any animals are actually people in costumes.
 <br><br>
 
 Save files are stored in your browser's cache. Save to file or text in the "Export/Import" tab in "Saves" to avoid losing them.
@@ -26,7 +26,7 @@ Save files are stored in your browser's cache. Save to file or text in the "Expo
 
 If the image on the "Feat Boosts" tab is broken, please ensure that you have properly extracted the zip file.
 /*
-<<if $images is 1>>
+<<if $options.images is 1>>
 	If you have, you may want to overwrite the "img" folder with one from a fresh download of the game.
 <</if>>
 */
diff --git a/game/03-JavaScript/IronMan.js b/game/03-JavaScript/IronMan.js
index 160d7a1a89..a7345ed987 100644
--- a/game/03-JavaScript/IronMan.js
+++ b/game/03-JavaScript/IronMan.js
@@ -70,9 +70,11 @@ var IronMan = (Save => {
 				ironmanautosaveschedule: Object.assign({}, readonly, {
 					value: V.ironmanautosaveschedule,
 				}),
-				autosavedisabled: Object.assign({}, readonly, { value: true }),
 				virginity: Object.assign({}, readonly, { value: V.player.virginity }),
 			});
+			Object.defineProperties(V.options, {
+				autosaveDisabled: Object.assign({}, readonly, { value: true })
+			});
 			if (!IRONMAN_DEBUG) {
 				Object.defineProperty(V, "debug", Object.assign({}, readonly, { value: 0 }));
 			}
@@ -100,7 +102,7 @@ var IronMan = (Save => {
 	function getSignature(save = null) {
 		const keys = [
 			"debug",
-			"autosavedisabled",
+			"options",
 			"virginity",
 			"player",
 			"enemyhealth",
@@ -156,9 +158,9 @@ var IronMan = (Save => {
 							'<<replace #sliderAllureMode>><<numberslider "$alluremod" $alluremod 0.2 2 0.1 $ironmanmode>><</replace>>'
 						);
 					}
-					V.maxStates = 1;
+					V.options.maxStates = 1;
 					V.cheatdisabletoggle = "t";
-					V.autosavedisabled = true;
+					V.options.autosaveDisabled = true;
 					$(".ironman-slider input")
 						.on("input change", e => sliderPerc(e))
 						.trigger("change");
diff --git a/game/03-JavaScript/UI.js b/game/03-JavaScript/UI.js
index 7155d02278..8070c82af7 100644
--- a/game/03-JavaScript/UI.js
+++ b/game/03-JavaScript/UI.js
@@ -209,7 +209,7 @@ var defaultSkinColorRanges = {
 };
 
 window.skinColor = function (enabled, percent, overwrite) {
-	if (enabled === "f") {
+	if (enabled === false) {
 		return "";
 	}
 
@@ -450,15 +450,51 @@ window.settingsDisableElement = function() {
 				});
 			};
 			let orig = $(this);
+			let target = orig.data("target");
 			let disabledif = orig.data("disabledif");
 			if(orig.data("target") && disabledif){
 				updateButtonsActive();
-				$(document).on("click.evt", "[name*='" + Util.slugify(orig.data("target")) + "']", function(){ updateButtonsActive(); });
+				$(document).on("click.evt", "[name*='" + (Array.isArray(target) ? target.map(x => Util.slugify(x)).join("'], [name*='") : Util.slugify(target)) + "']", function(){ updateButtonsActive(); });
 			}
 		});
 	});
 }
 
+/* Adds event listeners to input on current page */
+window.onInputChanged = function(func) {
+	if (!func || (typeof func !== "function")) return;
+	$(document).ready(() => {
+		$("input").on("change", function() { func(); });
+	});
+}
+
+window.closeOverlay = function() {
+	updateOptions();
+	V.currentOverlay = null;
+	T.buttons.reset();
+	$("#customOverlay").addClass("hidden").parent().addClass("hidden");
+}
+
+window.updateOptions = function() {
+	if(V.currentOverlay === "options" && T.optionsRefresh && V.passage != 'Start'){
+		updatehistorycontrols();
+		let optionsData = clone(V.options);
+		let tmpButtons = T.buttons;
+		let tmpKey = T.key;
+
+		State.restore();
+		V.options = optionsData;
+		State.show();
+
+		T.key = tmpKey;
+		T.buttons = tmpButtons;
+		T.buttons.setupTabs();
+		if(T.key !== "options") {
+			T.buttons.setActive(T.buttons.activeTab);	
+		}
+	}
+}
+
 $(document).on('click', '#cbtToggleMenu .cbtToggle', function (e) {
 	$('#cbtToggleMenu').toggleClass('visible');
 });
diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index fb2e0737c6..8de8c2225b 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -604,7 +604,7 @@ window.nullable = nullable;
  */
 Macro.add("icon", {
 	handler() {
-		if (!V.images) return;
+		if (!V.options.images) return;
 		const name = typeof(this.args[0]) === "string" ? this.args[0] : "error";
 		const iconImg = document.createElement("img");
 		iconImg.className = "icon";
@@ -615,6 +615,50 @@ Macro.add("icon", {
 	}
 });
 
+/**
+ * Adds a foldout, which can be expanded and collapsed
+ * It uses the first element in the content as a header (which can be clicked on), and all other elements as the body (which gets expanded/collapsed)
+ * First argument defines whether it starts expanded or not.
+ * Second argument defines the variable where the foldout state is saved (if no variable is defined, the foldout will reset to default if you leave the page)
+ * Example: <<foldout true "_tempVar">><div>header here</div>body here<</foldout>>
+ */
+Macro.add("foldout", {
+	tags: null,
+	handler: function() {
+		function setFoldoutState(state, transition = 0) {
+			if(state) {
+				toggle.addClass("extended");
+				body.slideDown(transition);
+			}
+			else {
+				toggle.removeClass("extended");
+				body.slideUp(transition);
+			}
+			State.setVar(varname, foldoutState);
+		}
+
+		let def = this.args[0] !== undefined ? this.args[0] : true;
+		let varname = this.args[1] || null;
+		let foldoutState = State.getVar(varname) != null ? State.getVar(varname) : def;
+		let content = this.payload[0].contents;
+
+		let e = $("<div>")
+			.addClass("foldout")
+			.append(Wikifier.wikifyEval(content));
+		let header = e.children().first().addClass("foldoutHeader");
+		let toggle = $("<span>").addClass("foldoutToggle").appendTo(header);
+		let body = e.contents().not(header).wrapAll("<div>").parent().insertAfter(header);
+		
+		setFoldoutState(foldoutState);
+
+		header.on('click', function () {
+				foldoutState = !foldoutState;
+				setFoldoutState(foldoutState, 100);
+			});
+		e.appendTo(this.output);
+	}
+});
+
 window.pickRandom = function (list) {
 	if (!list)
 		return undefined;
diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index 60e82b4283..893ae71cc8 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -1494,7 +1494,7 @@ function outfitHoodPosition(outfit) {
 window.outfitHoodPosition = outfitHoodPosition;
 
 window.combatCharacterShadow = function() {
-	if(!V.lightCombat) return;
+	if(!V.options.characterLightEnabled || !V.options.images || !V.options.combatImages) return;
 	const targetClass = "char-shadow-combat";
 	const mainDiv = ".char_combat";
 
diff --git a/game/03-JavaScript/save.js b/game/03-JavaScript/save.js
index dd67e6ee1c..7a478e1320 100644
--- a/game/03-JavaScript/save.js
+++ b/game/03-JavaScript/save.js
@@ -791,7 +791,6 @@ function settingsObjects(type) {
 				},
 				gamemode: { strings: ["normal", "soft", "hard"] },
 				ironmanmode: { bool: false },
-				maxStates: { min: 1, max: 20, decimals: 0 },
 				player: {
 					gender: { strings: ["m", "f", "h"], randomize: "characterAppearance" },
 					gender_body: { strings: ["m", "f", "a"], randomize: "characterAppearance" },
@@ -891,13 +890,6 @@ function settingsObjects(type) {
 				// playerPregnancyHumanDisable: {boolLetter: true, bool: true},
 				// playerPregnancyBeastDisable: {boolLetter: true, bool: true},
 				// npcPregnancyDisable: {boolLetter: true, bool: true},
-				images: { min: 0, max: 1, decimals: 0 },
-				sidebarAnimations: { bool: true },
-				combatAnimations: { bool: true },
-				bodywritingImages: { bool: true },
-				silhouettedisable: { boolLetter: true, bool: true },
-				blinkingdisable: { boolLetter: true, bool: true },
-				halfcloseddisable: { boolLetter: true, bool: true },
 				numberify_enabled: { min: 0, max: 1, decimals: 0 },
 				timestyle: { strings: ["military", "ampm"] },
 				checkstyle: {
@@ -908,33 +900,42 @@ function settingsObjects(type) {
 				debugdisable: { boolLetter: true, bool: true },
 				statdisable: { boolLetter: true, bool: true },
 				cheatdisabletoggle: { boolLetter: true, bool: true },
-				showCaptionText: { bool: true },
 				confirmSave: { bool: true },
 				confirmLoad: { bool: true },
 				confirmDelete: { bool: true },
-				newWardrobeStyle: { bool: true },
-				lightSpotlight: { decimals: 0.1 },
-				lightGradient: { decimals: 0 },
-				lightGlow: { decimals: 0 },
-				lightFlat: { decimals: 0 },
-				lightCombat: { decimals: 0.1 },
-				lightTFColor: { decimals: 0.1 },
-				sidebarStats: { strings: ["Disabled", "Limited", "All"] },
-				sidebarTime: { strings: ["Disabled", "top", "bottom"] },
-				combatControls: { strings: ["radio", "lists", "limitedLists"] },
 				reducedLineHeight: { bool: true },
-				neverNudeMenus: { bool: true },
-				skipStatisticsConfirmation: { bool: true },
 				multipleWardrobes: { strings: [false, "isolated"] }, //, "all"
 				outfitEditorPerPage: { min: 5, max: 20, decimals: 0 }, //, "all"
-				map: {
-					movement: { bool: true },
-					top: { bool: true },
-					markers: { bool: true },
-				},
-				skinColor: {
-					tanImgEnabled: { boolLetter: true, bool: true },
+				options:{
+					neverNudeMenus: { bool: true },
+					showCaptionText: { bool: true },
+					sidebarStats: { strings: ["disabled", "limited", "all"] },
+					sidebarTime: { strings: ["disabled", "top", "bottom"] },
+					combatControls: { strings: ["radio", "lists", "limitedLists"] },
+					mapMovement: { bool: true },
+					mapTop: { bool: true },
+					mapMarkers: { bool: true },
+					images: { min: 0, max: 1, decimals: 0 },
+					combatImages: { min: 0, max: 1, decimals: 0 },
+					bodywritingImages: { bool: true },
+					silhouetteEnabled: { bool: true },
+					tanImgEnabled: { bool: true },
 					tanningEnabled: { bool: true },
+					sidebarAnimations: { bool: true },
+					blinkingEnabled: { bool: true },
+					combatAnimations: { bool: true },
+					halfClosedEnabled: { bool: true },
+					characterLightEnabled: { bool: true },
+					lightSpotlight: { min: 0, max: 1, decimals: 2 },
+					lightGradient: { min: 0, max: 1, decimals: 2 },
+					lightGlow: { min: 0, max: 1, decimals: 2 },
+					lightFlat: { min: 0, max: 1, decimals: 2 },
+					lightCombat: { min: 0, max: 1, decimals: 2 },
+					lightTFColor: { min: 0, max: 1, decimals: 2 },
+					maxStates: { min: 1, max: 20, decimals: 0 },
+					newWardrobeStyle: { bool: true },
+					useNarrowMarket: { bool: true },
+					skipStatisticsConfirmation:{ bool: true },
 				},
 				shopDefaults: {
 					alwaysBackToShopButton: { bool: true },
diff --git a/game/03-JavaScript/scroll-bar.js b/game/03-JavaScript/scroll-bar.js
index 2c7b02ab74..65edf3f68c 100644
--- a/game/03-JavaScript/scroll-bar.js
+++ b/game/03-JavaScript/scroll-bar.js
@@ -3,7 +3,7 @@
 $(document).on(":passageend", function (event) {
 	//simplified fix, iteration 2
 	if (window.scroll_uibar) document.querySelector("#storyCaptionDiv").scroll(0, window.scroll_uibar);
-	if (V.scroll_remember && V.passage === V.passagePrev) document.scrollingElement.scroll(0, window.scroll_main);
+	if (V.options.scrollRemember && V.passage === V.passagePrev) document.scrollingElement.scroll(0, window.scroll_main);
 	/*previous version
 	//get sidebar dom element, assign it to variable for convenience
 	let sidebar = document.querySelector("#storyCaptionDiv");
diff --git a/game/03-JavaScript/tabs.js b/game/03-JavaScript/tabs.js
new file mode 100644
index 0000000000..74293b0818
--- /dev/null
+++ b/game/03-JavaScript/tabs.js
@@ -0,0 +1,30 @@
+window.Tab = class {
+	constructor(element, selectedClass) {
+		this.element = element;
+		this.selectedClass = selectedClass;
+		this.activeTab = -1;
+		this.setupTabs();
+	}
+
+	setupTabs() {
+		$(() => { this.tabs = $("#" + this.element).find("button"); });
+	}
+	setActive(index = 0) {
+		$(() => {
+			if(index === -1) return;
+			this.activeTab = index;
+			this.toggle(this.tabs.eq(index));
+		});
+	}
+
+	toggle(target = $(window.event.target)) {
+		this.reset();
+		this.activeTab = this.tabs.index(target);
+		target.addClass(this.selectedClass);
+	}
+
+	reset() {
+		this.activeTab = -1;
+		this.tabs.removeClass(this.selectedClass);
+	}
+};
\ No newline at end of file
diff --git a/game/03-JavaScript/theme.js b/game/03-JavaScript/theme.js
index 778117638b..2cce08d4e7 100644
--- a/game/03-JavaScript/theme.js
+++ b/game/03-JavaScript/theme.js
@@ -70,13 +70,13 @@ var ThemeManager = (() => {
 
 	window.Theme = {
 		initControl() {
-			$(document).one("overlay-load", () => {
+			$(document).ready(() => {
 				$(`input[name=theme][value="${getPreference()}"]`).prop("checked", true);
 
 				$("input[name=theme]").on("change", event => {
 					setPreference(event.currentTarget.value);
 				});
 			});
-		},
+		}
 	};
-})();
+})();
\ No newline at end of file
diff --git a/game/04-Variables/presets.twee b/game/04-Variables/presets.twee
index 71a9d689c6..6985abf347 100644
--- a/game/04-Variables/presets.twee
+++ b/game/04-Variables/presets.twee
@@ -5,13 +5,13 @@
 	<<set _preset to "">>
 	<<switch _args[0]>>
 		<<case "vrelDefault">>
-			<<set _preset to '{"general":{"map":{"movement":true,"top":false,"markers":false},"skinColor":{"tanImgEnabled":"f","tanningEnabled":false},"malechance":50,"dgchance":0,"cbchance":0,"malevictimchance":50,"homochance":4,"breast_mod":0,"penis_mod":0,"whitechance":90,"blackchance":10,"straponchance":0,"alluremod":1,"beastmalechance":80,"monsterchance":50,"monsterhallucinations":"t","blackwolfmonster":0,"bestialitydisable":"f","swarmdisable":"f","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"f","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"f","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"f","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f","slugdisable":"f","waspdisable":"f","lurkerdisable":"f","beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":12,"bottomsizemax":8,"penissizemax":4,"penissizemin":-1,"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","numberify_enabled":1,"timestyle":"military","tipdisable":"f","debugdisable":"t","statdisable":"f","cheatdisabletoggle":"t","showCaptionText":true,"confirmSave":false,"confirmLoad":false,"confirmDelete":true,"newWardrobeStyle":false,"sidebarStats":"Disabled","sidebarTime":"Disabled","combatControls":"radio","reducedLineHeight":false},"npc":{"Avery":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Bailey":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Briar":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Charlie":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Darryl":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Doren":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Eden":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Gwylan":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Harper":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Jordan":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Kylar":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Landry":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Leighton":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Mason":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Morgan":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"River":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Robin":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Sam":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Sirris":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Whitney":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Winter":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Black Wolf":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Niki":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Quinn":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Remy":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Alex":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"f","gender_body":"a","ballsExist":false,"freckles":false,"breastsize":0,"penissize":1,"bottomsize":0},"skinColor":{"natural":"light","range":0},"bodysize":2,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"purple","hairselect":"red","hairlength":200,"awareselect":"innocent","background":"waif","gamemode":"normal","asphyxiaLvl":3,"blinkingdisable":"f","halfcloseddisable":"f","pbdisable":"t"}}'>>
+			<<set _preset to '{"general":{"options":{"showCaptionText":true,"sidebarStats":"disabled","sidebarTime":"disabled","combatControls":"radio","images":1,"silhouetteEnabled":true,"tanImgEnabled":true,"tanningEnabled":true,"sidebarAnimations":true,"blinkingEnabled":true,"combatAnimations":true},{"map":{"movement":true,"top":false,"markers":false},"malechance":50,"dgchance":0,"cbchance":0,"malevictimchance":50,"homochance":4,"breast_mod":0,"penis_mod":0,"whitechance":90,"blackchance":10,"straponchance":0,"alluremod":1,"beastmalechance":80,"monsterchance":50,"monsterhallucinations":"t","blackwolfmonster":0,"bestialitydisable":"f","swarmdisable":"f","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"f","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"f","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"f","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f","slugdisable":"f","waspdisable":"f","lurkerdisable":"f","beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":12,"bottomsizemax":8,"penissizemax":4,"penissizemin":-1,"numberify_enabled":1,"timestyle":"military","tipdisable":"f","debugdisable":"t","statdisable":"f","cheatdisabletoggle":"t","confirmSave":false,"confirmLoad":false,"confirmDelete":true,"reducedLineHeight":false},"npc":{"Avery":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Bailey":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Briar":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Charlie":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Darryl":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Doren":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Eden":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Gwylan":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Harper":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Jordan":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Kylar":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Landry":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Leighton":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Mason":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Morgan":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"River":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Robin":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Sam":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Sirris":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Whitney":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Winter":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Black Wolf":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Niki":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Quinn":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Remy":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Alex":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"f","gender_body":"a","ballsExist":false,"freckles":false,"breastsize":0,"penissize":1,"bottomsize":0},"skinColor":{"natural":"light","range":0},"bodysize":2,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"purple","hairselect":"red","hairlength":200,"awareselect":"innocent","background":"waif","gamemode":"normal","asphyxiaLvl":3,"pbdisable":"t"}}'>>
 		<<case "lollipopScythe">>
-			<<set _preset to '{"general":{"map":{"movement":true,"top":true,"markers":true},"skinColor":{"tanImgEnabled":"t","tanningEnabled":true},"malechance":75,"dgchance":25,"cbchance":0,"malevictimchance":90,"homochance":75,"breast_mod":0,"penis_mod":2,"whitechance":90,"blackchance":10,"straponchance":25,"alluremod":1,"beastmalechance":100,"monsterchance":0,"monsterhallucinations":"t","blackwolfmonster":0,"bestialitydisable":"f","swarmdisable":"f","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"t","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"t","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"f","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f", "slugdisable":"f", "waspdisable":"f", "lurkerdisable":"f", "beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":12,"bottomsizemax":8,"penissizemax":4,"penissizemin":-1,"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","numberify_enabled":1,"timestyle":"military","tipdisable":"t","debugdisable":"f","statdisable":"f","cheatdisabletoggle":"t","showCaptionText":true,"confirmSave":false,"confirmLoad":false,"confirmDelete":true,"newWardrobeStyle":true,"sidebarStats":"Disabled","sidebarTime":"Disabled","combatControls":"radio","reducedLineHeight":true},"npc":{"Avery":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Bailey":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Briar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Charlie":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Darryl":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Doren":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Eden":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Gwylan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":5},"Harper":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Jordan":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Kylar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Landry":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Leighton":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Mason":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Morgan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":5},"River":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Robin":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Sam":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Sirris":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Whitney":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Winter":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Black Wolf":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Niki":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Quinn":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Remy":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Alex":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"h","gender_body":"f","ballsExist":true,"freckles":false,"breastsize":4,"penissize":0,"bottomsize":0},"skinColor":{"natural":"light","range":40},"bodysize":0,"breastsensitivity":5,"genitalsensitivity":5,"eyeselect":"pink","hairselect":"platinumblond","hairlength":400,"awareselect":"innocent","background":"beautiful","gamemode":"hard","asphyxiaLvl":3,"blinkingdisable":"f","halfcloseddisable":"f","pbdisable":"t"}}'>>
+			<<set _preset to '{"general":{"options":{"showCaptionText":true,"sidebarStats":"disabled","sidebarTime":"disabled","combatControls":"radio","images":1,"silhouetteEnabled":true,"tanImgEnabled":true,"tanningEnabled":true,"sidebarAnimations":true,"blinkingEnabled":true,"combatAnimations":true},"map":{"movement":true,"top":true,"markers":true},"malechance":75,"dgchance":25,"cbchance":0,"malevictimchance":90,"homochance":75,"breast_mod":0,"penis_mod":2,"whitechance":90,"blackchance":10,"straponchance":25,"alluremod":1,"beastmalechance":100,"monsterchance":0,"monsterhallucinations":"t","blackwolfmonster":0,"bestialitydisable":"f","swarmdisable":"f","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"t","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"t","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"f","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f", "slugdisable":"f", "waspdisable":"f", "lurkerdisable":"f", "beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":12,"bottomsizemax":8,"penissizemax":4,"penissizemin":-1,"numberify_enabled":1,"timestyle":"military","tipdisable":"t","debugdisable":"f","statdisable":"f","cheatdisabletoggle":"t","confirmSave":false,"confirmLoad":false,"confirmDelete":true,"reducedLineHeight":true},"npc":{"Avery":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Bailey":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Briar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Charlie":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Darryl":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Doren":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Eden":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Gwylan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":5},"Harper":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Jordan":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Kylar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Landry":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Leighton":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Mason":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Morgan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":5},"River":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Robin":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Sam":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Sirris":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Whitney":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Winter":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Black Wolf":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Niki":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Quinn":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Remy":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Alex":{"pronoun":"m","gender":"m","penissize":4,"breastsize":0},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"h","gender_body":"f","ballsExist":true,"freckles":false,"breastsize":4,"penissize":0,"bottomsize":0},"skinColor":{"natural":"light","range":40},"bodysize":0,"breastsensitivity":5,"genitalsensitivity":5,"eyeselect":"pink","hairselect":"platinumblond","hairlength":400,"awareselect":"innocent","background":"beautiful","gamemode":"hard","asphyxiaLvl":3,"pbdisable":"t"}}'>>
 		<<case "purityGuy">>
-			<<set _preset to '{"general":{"map":{"movement":true,"top":false,"markers":true},"skinColor":{"tanImgEnabled":"t","tanningEnabled":true},"malechance":50,"dgchance":0,"cbchance":0,"malevictimchance":10,"homochance":10,"breast_mod":0,"penis_mod":0,"whitechance":100,"blackchance":0,"straponchance":0,"alluremod":1.2,"beastmalechance":50,"monsterchance":100,"monsterhallucinations":"f","blackwolfmonster":2,"bestialitydisable":"f","swarmdisable":"t","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"t","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"t","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"t","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f","slugdisable":"f","waspdisable":"f","lurkerdisable":"f","beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":6,"bottomsizemax":4,"penissizemax":4,"penissizemin":-1,"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","numberify_enabled":1,"timestyle":"ampm","tipdisable":"f","debugdisable":"f","statdisable":"f","cheatdisabletoggle":"t","showCaptionText":true,"confirmSave":true,"confirmLoad":true,"confirmDelete":true,"newWardrobeStyle":true,"sidebarStats":"All","sidebarTime":"top","combatControls":"radio","reducedLineHeight":false},"npc":{"Avery":{"pronoun":"f","gender":"f","penissize":1,"breastsize":4},"Bailey":{"pronoun":"m","gender":"m","penissize":3,"breastsize":2},"Briar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Charlie":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Darryl":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Doren":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Eden":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Gwylan":{"pronoun":"f","gender":"f","penissize":1,"breastsize":0},"Harper":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Jordan":{"pronoun":"f","gender":"f","penissize":3,"breastsize":5},"Kylar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Landry":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Leighton":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Mason":{"pronoun":"f","gender":"f","penissize":3,"breastsize":2},"Morgan":{"pronoun":"f","gender":"f","penissize":3,"breastsize":3},"River":{"pronoun":"f","gender":"f","penissize":3,"breastsize":0},"Robin":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Sam":{"pronoun":"f","gender":"f","penissize":1,"breastsize":3},"Sirris":{"pronoun":"f","gender":"f","penissize":3,"breastsize":0},"Whitney":{"pronoun":"f","gender":"f","penissize":4,"breastsize":0},"Winter":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Black Wolf":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Niki":{"pronoun":"f","gender":"f","penissize":3,"breastsize":2},"Quinn":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Remy":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Alex":{"pronoun":"f","gender":"f","penissize":1,"breastsize":0},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"f","gender_body":"f","ballsExist":false,"freckles":false,"breastsize":3,"penissize":1,"bottomsize":1},"skinColor":{"natural":"light","range":0},"bodysize":2,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"amber","hairselect":"blond","hairlength":400,"awareselect":"innocent","background":"beautiful","gamemode":"normal","asphyxiaLvl":3,"blinkingdisable":"f","halfcloseddisable":"f","pbdisable":"t"}}'>>
+			<<set _preset to '{"general":{"options":{"showCaptionText":true,"sidebarStats":"all","sidebarTime":"top","combatControls":"radio","images":1,"silhouetteEnabled":true,"tanImgEnabled":true,"tanningEnabled":true,"sidebarAnimations":true,"blinkingEnabled":true,"combatAnimations":true},"map":{"movement":true,"top":false,"markers":true},"malechance":50,"dgchance":0,"cbchance":0,"malevictimchance":10,"homochance":10,"breast_mod":0,"penis_mod":0,"whitechance":100,"blackchance":0,"straponchance":0,"alluremod":1.2,"beastmalechance":50,"monsterchance":100,"monsterhallucinations":"f","blackwolfmonster":2,"bestialitydisable":"f","swarmdisable":"t","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"t","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"t","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"t","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f","slugdisable":"f","waspdisable":"f","lurkerdisable":"f","beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":6,"bottomsizemax":4,"penissizemax":4,"penissizemin":-1,"numberify_enabled":1,"timestyle":"ampm","tipdisable":"f","debugdisable":"f","statdisable":"f","cheatdisabletoggle":"t","confirmSave":true,"confirmLoad":true,"confirmDelete":true,"reducedLineHeight":false},"npc":{"Avery":{"pronoun":"f","gender":"f","penissize":1,"breastsize":4},"Bailey":{"pronoun":"m","gender":"m","penissize":3,"breastsize":2},"Briar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Charlie":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Darryl":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Doren":{"pronoun":"m","gender":"m","penissize":1,"breastsize":0},"Eden":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Gwylan":{"pronoun":"f","gender":"f","penissize":1,"breastsize":0},"Harper":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Jordan":{"pronoun":"f","gender":"f","penissize":3,"breastsize":5},"Kylar":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Landry":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Leighton":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Mason":{"pronoun":"f","gender":"f","penissize":3,"breastsize":2},"Morgan":{"pronoun":"f","gender":"f","penissize":3,"breastsize":3},"River":{"pronoun":"f","gender":"f","penissize":3,"breastsize":0},"Robin":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Sam":{"pronoun":"f","gender":"f","penissize":1,"breastsize":3},"Sirris":{"pronoun":"f","gender":"f","penissize":3,"breastsize":0},"Whitney":{"pronoun":"f","gender":"f","penissize":4,"breastsize":0},"Winter":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Black Wolf":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Niki":{"pronoun":"f","gender":"f","penissize":3,"breastsize":2},"Quinn":{"pronoun":"m","gender":"m","penissize":3,"breastsize":0},"Remy":{"pronoun":"m","gender":"m","penissize":2,"breastsize":0},"Alex":{"pronoun":"f","gender":"f","penissize":1,"breastsize":0},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"f","gender_body":"f","ballsExist":false,"freckles":false,"breastsize":3,"penissize":1,"bottomsize":1},"skinColor":{"natural":"light","range":0},"bodysize":2,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"amber","hairselect":"blond","hairlength":400,"awareselect":"innocent","background":"beautiful","gamemode":"normal","asphyxiaLvl":3,"pbdisable":"t"}}'>>
 		<<case "fangi">>
-			<<set _preset to '{"general":{"map":{"movement":true,"top":false,"markers":false},"skinColor":{"tanImgEnabled":"t","tanningEnabled":true},"malechance":0,"dgchance":0,"cbchance":0,"malevictimchance":1,"homochance":75,"breast_mod":0,"penis_mod":0,"whitechance":90,"blackchance":10,"straponchance":0,"alluremod":1,"beastmalechance":0,"monsterchance":100,"monsterhallucinations":"f","blackwolfmonster":1,"bestialitydisable":"f","swarmdisable":"f","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"t","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"t","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"f","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f","slugdisable":"f","waspdisable":"f","lurkerdisable":"f","beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":12,"bottomsizemax":8,"penissizemax":4,"penissizemin":-1,"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","numberify_enabled":1,"timestyle":"military","tipdisable":"f","debugdisable":"f","statdisable":"f","cheatdisabletoggle":"f","showCaptionText":true,"confirmSave":false,"confirmLoad":false,"confirmDelete":true,"newWardrobeStyle":false,"sidebarStats":"Disabled","sidebarTime":"Disabled","combatControls":"radio","reducedLineHeight":false},"npc":{"Avery":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Bailey":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Briar":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Charlie":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Darryl":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Doren":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Eden":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Gwylan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Harper":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Jordan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Kylar":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Landry":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Leighton":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Mason":{"pronoun":"f","gender":"f","penissize":0,"breastsize":2},"Morgan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":5},"River":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Robin":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Sam":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Sirris":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Whitney":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Winter":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Black Wolf":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Niki":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Quinn":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Remy":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Alex":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"f","gender_body":"f","ballsExist":false,"freckles":false,"breastsize":3,"penissize":1,"bottomsize":0},"skinColor":{"natural":"light","range":0},"bodysize":3,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"purple","hairselect":"red","hairlength":200,"awareselect":"innocent","background":"waif","gamemode":"normal","asphyxiaLvl":3,"blinkingdisable":"f","halfcloseddisable":"f","pbdisable":"t"}}'>>
+			<<set _preset to '{"general":{"options":{"showCaptionText":true,"sidebarStats":"disabled","sidebarTime":"disabled","combatControls":"radio","images":1,"silhouetteEnabled":true,"tanImgEnabled":true,"tanningEnabled":true,"blinkingEnabled":true,"sidebarAnimations":true,"combatAnimations":true},"map":{"movement":true,"top":false,"markers":false},"malechance":0,"dgchance":0,"cbchance":0,"malevictimchance":1,"homochance":75,"breast_mod":0,"penis_mod":0,"whitechance":90,"blackchance":10,"straponchance":0,"alluremod":1,"beastmalechance":0,"monsterchance":100,"monsterhallucinations":"f","blackwolfmonster":1,"bestialitydisable":"f","swarmdisable":"f","slimedisable":"f","voredisable":"f","tentacledisable":"f","analdisable":"f","analdoubledisable":"t","footdisable":"f","analingusdisablegiving":"f","analingusdisablereceiving":"f","vaginaldoubledisable":"t","transformdisable":"f","transformdisabledivine":"f","breastfeedingdisable":"f","analpregdisable":"f","watersportsdisable":"f","facesitdisable":"f","spiderdisable":"f","bodywritingdisable":"f","parasitedisable":"f","slugdisable":"f","waspdisable":"f","lurkerdisable":"f","beedisable":"f","horsedisable":"f","pregnancyspeechdisable":"f","breastsizemax":12,"bottomsizemax":8,"penissizemax":4,"penissizemin":-1,"numberify_enabled":1,"timestyle":"military","tipdisable":"f","debugdisable":"f","statdisable":"f","cheatdisabletoggle":"f","confirmSave":false,"confirmLoad":false,"confirmDelete":true,"reducedLineHeight":false},"npc":{"Avery":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Bailey":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Briar":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Charlie":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Darryl":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Doren":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Eden":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Gwylan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Harper":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Jordan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Kylar":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Landry":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Leighton":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Mason":{"pronoun":"f","gender":"f","penissize":0,"breastsize":2},"Morgan":{"pronoun":"f","gender":"f","penissize":0,"breastsize":5},"River":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Robin":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Sam":{"pronoun":"f","gender":"f","penissize":0,"breastsize":4},"Sirris":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Whitney":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Winter":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Black Wolf":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Niki":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Quinn":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Remy":{"pronoun":"f","gender":"f","penissize":0,"breastsize":3},"Alex":{"pronoun":"f","gender":"f","penissize":0,"breastsize":1},"Great Hawk":{"pronoun":"none","gender":"none","penissize":0,"breastsize":0}},"starting":{"player":{"gender":"f","gender_body":"f","ballsExist":false,"freckles":false,"breastsize":3,"penissize":1,"bottomsize":0},"skinColor":{"natural":"light","range":0},"bodysize":3,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"purple","hairselect":"red","hairlength":200,"awareselect":"innocent","background":"waif","gamemode":"normal","asphyxiaLvl":3,"pbdisable":"t"}}'>>
 		<<case "femaleWaif">>
 			<<set _preset to '{"starting":{"player":{"gender":"f","gender_body":"f","ballsExist":false,"freckles":false,"breastsize":3,"penissize":1,"bottomsize":0},"skinColor":{"natural":"light","range":0},"bodysize":3,"breastsensitivity":1,"genitalsensitivity":1,"eyeselect":"purple","hairselect":"red","hairlength":200,"awareselect":"innocent","background":"waif"}}'>>
 		<<case "maleWaif">>
@@ -65,7 +65,7 @@
 		<<case "gameHard">>
 			<<set _preset to '{"general":{"alluremod":1,"cheatdisabletoggle":"t","checkstyle":"words","clothesPrice":2,"multipleWardrobes":"isolated"},"starting":{"gamemode":"hard"}}'>>
 		<<case "gameHardIronman">>
-			<<set _preset to '{"general":{"alluremod":1,"rentmod":1,"tending_yield_factor":5,"cheatdisabletoggle":"t","checkstyle":"words","clothesPrice":2,"multipleWardrobes":"isolated"},"starting":{"gamemode":"hard","ironmanmode":true,"maxStates":1}}'>>
+			<<set _preset to '{"general":{"options":{"maxStates":1},"alluremod":1,"rentmod":1,"tending_yield_factor":5,"cheatdisabletoggle":"t","checkstyle":"words","clothesPrice":2,"multipleWardrobes":"isolated"},"starting":{"gamemode":"hard","ironmanmode":true}}'>>
 		<<case "gameMasochist">>
 			<<set _preset to '{"general":{"alluremod":2,"cheatdisabletoggle":"t","statdisable":"t","checkstyle":"skillname","clothesPrice":10,"multipleWardrobes":"isolated"},"starting":{"gamemode":"hard"}}'>>
 		<<case "gameSoftCheats">>
@@ -77,23 +77,23 @@
 		<<case "gameMasochistCheats">>
 			<<set _preset to '{"general":{"alluremod":2,"cheatdisabletoggle":"f","statdisable":"t","checkstyle":"skillname","clothesPrice":10,"multipleWardrobes":"isolated"},"starting":{"gamemode":"hard"}}'>>
 		<<case "imagesdefault">>
-			<<set _preset to '{"general":{"skinColor":{"tanImgEnabled":"f","tanningEnabled":false},"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","blinkingdisable":"f","halfcloseddisable":"f","bodywritingImages":true}}'>>
+			<<set _preset to '{"general":{"options":{"tanImgEnabled":true,"tanningEnabled":true,"images":1,"bodywritingImages":true,"silhouetteEnabled":true,"sidebarAnimations":true,"blinkingEnabled":true,"combatAnimations":true}}}'>>
 		<<case "imagesHigh">>
-			<<set _preset to '{"general":{"skinColor":{"tanImgEnabled":"t","tanningEnabled":true},"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","blinkingdisable":"f","halfcloseddisable":"f","bodywritingImages":true}}'>>
+			<<set _preset to '{"general":{"options":{"tanImgEnabled":true,"tanningEnabled":true,"images":1,"bodywritingImages":true,"silhouetteEnabled":true,"sidebarAnimations":true,"blinkingEnabled":true,"combatAnimations":true}}}'>>
 		<<case "imagesLow">>
-			<<set _preset to '{"general":{"skinColor":{"tanImgEnabled":"f","tanningEnabled":false},"images":1,"sidebarAnimations":true,"combatAnimations":true,"silhouettedisable":"f","blinkingdisable":"f","halfcloseddisable":"f","bodywritingImages":false}}'>>
+			<<set _preset to '{"general":{"options":{"tanImgEnabled":false,"tanningEnabled":false,"images":1,"bodywritingImages":false,"silhouetteEnabled":true,"sidebarAnimations":true,"blinkingEnabled":true,"combatAnimations":true}}}'>>
 		<<case "imagesPerformance">>
-			<<set _preset to '{"general":{"skinColor":{"tanImgEnabled":"f","tanningEnabled":false},"images":1,"sidebarAnimations":false,"combatAnimations":true,"silhouettedisable":"t","blinkingdisable":"t","halfcloseddisable":"f","bodywritingImages":false}}'>>
+			<<set _preset to '{"general":{"options":{"tanImgEnabled":false,"tanningEnabled":false,"images":1,"bodywritingImages":false,"silhouetteEnabled":false,"sidebarAnimations":false,"blinkingEnabled":false,"combatAnimations":false}}}'>>
 		<<case "imagesDisable">>
-			<<set _preset to '{"general":{"skinColor":{"tanImgEnabled":"f","tanningEnabled":false},"images":0}}'>>
+			<<set _preset to '{"general":{"options":{"tanImgEnabled":false,"tanningEnabled":false,"images":0}}}'>>
 		<<case "settingPCTip">>
-			<<set _preset to '{"general":{"tipdisable":"f","sidebarStats":"Disabled","sidebarTime":"Disabled","combatControls":"radio"}}'>>
+			<<set _preset to '{"general":{"options":{"showCaptionText":true,"sidebarStats":"disabled","sidebarTime":"disabled","combatControls":"radio"},"tipdisable":"f"}}'>>
 		<<case "settingPCNoTip">>
-			<<set _preset to '{"general":{"tipdisable":"t","sidebarStats":"Disabled","sidebarTime":"Disabled","combatControls":"radio"}}'>>
+			<<set _preset to '{"options":{"showCaptionText":true,"sidebarStats":"disabled","sidebarTime":"disabled","combatControls":"radio"},"general":{"tipdisable":"t"}}'>>
 		<<case "settingMobileTips">>
-			<<set _preset to '{"general":{"tipdisable":"f","sidebarStats":"Limited","sidebarTime":"top","combatControls":"limitedLists"}}'>>
+			<<set _preset to '{"options":{"showCaptionText":true,"sidebarStats":"limited","sidebarTime":"top","combatControls":"limitedLists"},"general":{"tipdisable":"f"}}'>>
 		<<case "settingMobileNoTips">>
-			<<set _preset to '{"general":{"tipdisable":"t","sidebarStats":"Limited","sidebarTime":"top","combatControls":"limitedLists"}}'>>
+			<<set _preset to '{"options":{"showCaptionText":true,"sidebarStats":"limited","sidebarTime":"top","combatControls":"limitedLists"},"general":{"tipdisable":"t"}}'>>
 		<<case "randomize">>
 			<<set _preset to _args[1]>>
 	<</switch>>
diff --git a/game/04-Variables/variables-passageFooter.twee b/game/04-Variables/variables-passageFooter.twee
index 08b64d365b..9206151585 100644
--- a/game/04-Variables/variables-passageFooter.twee
+++ b/game/04-Variables/variables-passageFooter.twee
@@ -21,9 +21,11 @@
 		<<run delete $replayScene.startPassage>>
 	<</if>>
 <</if>>
-<div id="customOverlay" class="customOverlay hidden">
-	<div id="customOverlayTitle" class="fixedClose"></div>
-	<div id="customOverlayContent"></div>
+<div id="customOverlayContainer" class="customOverlayContainer no-numberify hidden" onclick="closeOverlay()">
+	<div id="customOverlay" class="customOverlay hidden" onclick="event.stopPropagation()">
+		<div id="customOverlayTitle"></div>
+		<div id="customOverlayContent"></div>
+	</div>
 </div>
 
 <<if $combat is 1>>
@@ -37,7 +39,7 @@
 <<if !Story.has($passage)>>
 	<br>
 	Please report this, and either reload a previous save or take the emergency exit at the bottom of the page to the last safe location you were in.
-	<<if $maxStates gt 1>>
+	<<if $options.maxStates gt 1>>
 		Alternatively, return to the previous passage using the history depth function.
 	<</if>>
 	<br>
@@ -56,7 +58,7 @@
 		unless you got here through the use of a cheat,
 	<</if>>
 	and either reload a previous save or take the emergency exit at the bottom of the page to the last safe location you were in.
-	<<if $maxStates gt 1>>
+	<<if $options.maxStates gt 1>>
 		Alternatively, return to the previous passage using the history depth function.
 	<</if>>
 	<br><br><br>
@@ -65,7 +67,7 @@
 <</if>>
 
 <!-- handle autosaves in the footer, so the description getter don't have to guess what happened in the passage -->
-<<if _autosavehere and !_preventUpdate and !$autosavedisabled>>
+<<if _autosavehere and !_preventUpdate and !$options.autosaveDisabled>>
 	<<run Save.autosave.save(null, {"saveId":$saveId, "saveName":$saveName})>>
 	<<run setSaveDetail("autosave",{"saveId":$saveId,"saveName":$saveName},Story.get($passage).description())>>
 <</if>>
diff --git a/game/04-Variables/variables-start.twee b/game/04-Variables/variables-start.twee
index c22d50533b..704d549434 100644
--- a/game/04-Variables/variables-start.twee
+++ b/game/04-Variables/variables-start.twee
@@ -9,12 +9,48 @@
 /* The following is only run when the widget is called, which is only on new game start. Add to this if you want something to be run when you start a new game. */
 <<widget "gameStartOnly">>
 
-<<if StartConfig.enableImages is true>>
-	<<set $images to 1>>
-	<<set $combatimages to 1>>
-<<else>>
-	<<set $images to 0>>
-	<<set $combatimages to 0>>
+<<set $options to {
+		neverNudeMenus: false,
+		autosaveDisabled: false,
+		showCaptionText: true, 
+		sidebarRenderer: "canvas",
+		sidebarStats: "disabled",
+		sidebarTime: "disabled",
+		combatControls: "radio",
+		targetYourself: false,
+		scrollRemember: false,
+		mapMovement: true,
+		mapLegacy: false,
+		mapMarkers: false,
+		mapTop: false,
+		images: 1,
+		combatImages: 1,
+		bodywritingImages: true,
+		silhouetteEnabled: true,
+		tanImgEnabled: true,
+		tanningEnabled: true,
+		sidebarAnimations: true,
+		blinkingEnabled: true,
+		combatAnimations: true,
+		halfClosedEnabled: false,
+		characterLightEnabled: true,
+		lightSpotlight: 0.2,
+		lightGradient: 0.1,
+		lightGlow: 0.1,
+		lightFlat: 0,
+		lightCombat: 0.2,
+		lightTFColor: 0.2,
+		maxStates: 1,
+		numpad: false,
+		newWardrobeStyle: true,
+		useNarrowMarket: false,
+		skipStatisticsConfirmation: false,
+		showDebugRenderer: false
+	}>>
+
+<<if StartConfig.enableImages is false>>
+	<<set $options.images to 0>>
+	<<set $options.combatImages to 0>>
 <</if>>
 
 <<if StartConfig.debug is true>>
@@ -44,7 +80,6 @@
 
 <<set $dev to 0>>
 <<set $numberify_enabled to 1>>
-<<set $sidebarRenderer to 'canvas'>>
 <<set $showDebugRenderer to !!StartConfig.debug>>
 <<set $lastWardrobeSlot to "head">>
 
@@ -777,7 +812,6 @@
 <<set $stealtarget to "">>
 <<set $stealdifficulty to 1>>
 
-<<set $showCaptionText to true>>
 <<set $confirmSave to false>>
 <<set $confirmLoad to false>>
 <<set $confirmDelete to true>>
diff --git a/game/04-Variables/variables-start2.twee b/game/04-Variables/variables-start2.twee
index c8868c68f8..45af6a6e35 100644
--- a/game/04-Variables/variables-start2.twee
+++ b/game/04-Variables/variables-start2.twee
@@ -17,10 +17,6 @@
 	<<case 3>><<set $devlevel to 16>>
 <</switch>>
 
-<<if $skinColor.tanImgEnabled is null>>
-	<<set $skinColor.tanImgEnabled to "f">>
-<</if>>
-
 <<clamp>>
 <!-- <<effects>> -->
 <<initnpcgender>>
@@ -221,8 +217,6 @@
 	<<set $semen_volume to 0>>
 <</if>>
 
-<<set $bodywritingImages to true>>
-
 <<if $dateCount is undefined>>
 	<<set $dateCount to {
 		Total: 0,
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index b1a8b1cabb..f02d82cca7 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -3645,6 +3645,47 @@
 		<<unset $crimemax>>
 	<</if>>
 
+	<!-- v0.3.11.4 options rework -->
+	<<if $options is undefined>>
+		<<set $options to {
+			neverNudeMenus: $neverNudeMenus !== undefined ? $neverNudeMenus : false,
+			autosaveDisabled: $autosaveDisabled !== undefined ? $autosaveDisabled : false,
+			showCaptionText: $showCaptionText !== undefined ? $showCaptionText : true,
+			sidebarRenderer: $sidebarRenderer !== undefined ? $sidebarRenderer : "canvas",
+			sidebarStats: $sidebarStats && ["disabled", "limited", "all"].includes($sidebarStats) ? $sidebarStats : "disabled",
+			sidebarTime: $sidebarTime && ["disabled", "top", "bottom"].includes($sidebarTime) ? $sidebarTime : "disabled",
+			combatControls: $combatControls !== undefined ? $combatControls : "radio",
+			targetYourself: $targetYourself !== undefined ? $targetYourself : false,
+			scrollRemember: $scroll_remember !== undefined ? $scroll_remember : false,
+			mapMovement: $map.movement !== undefined ? $map.movement : true,
+			mapLegacy: $map.legacy !== undefined ? $map.legacy : false,
+			mapMarkers: $map.markers !== undefined ? $map.markers : false,
+			mapTop: $map.top !== undefined ? $map.top : false,
+			images: $images !== undefined && StartConfig.enableImages !== false ? $images : 0,
+			combatImages: $combatimages !== undefined && StartConfig.enableImages !== false ? $combatimages : 0,
+			bodywritingImages: $bodywritingImages !== undefined ? $bodywritingImages : true,
+			silhouetteEnabled: $silhouettedisable !== undefined ? $silhouettedisable === "f" : true,
+			tanImgEnabled: $skinColor.tanImgEnabled !== undefined ? $skinColor.tanImgEnabled !== "f" : true,
+			tanningEnabled: $skinColor.tanningEnabled !== undefined ? $skinColor.tanningEnabled === "f" : true,
+			sidebarAnimations: $sidebarAnimations !== undefined ? $sidebarAnimations : true,
+			blinkingEnabled: $blinkingdisable !== undefined ? $blinkingdisable === "f" : true,
+			combatAnimations: $combatAnimations !== undefined ? $combatAnimations : true,
+			halfClosedEnabled: $halfcloseddisable !== undefined ? $halfcloseddisable === "f" : true,
+			characterLightEnabled: true,
+			lightSpotlight: $lightSpotlight !== undefined ? $lightSpotlight : 0.2,
+			lightGradient: $lightGradient !== undefined ? $lightGradient : 0.1,
+			lightGlow: $lightGlow !== undefined ? $lightGlow : 0.1,
+			lightFlat: $lightFlat !== undefined ? $lightFlat : 0,
+			lightCombat: $lightCombat !== undefined ? $lightCombat : 0.2,
+			lightTFColor: $lightTFColor !== undefined ? $lightTFColor : 0.2,
+			maxStates: $maxStates !== undefined ? $maxStates : 1,
+			numpad: $numpad !== undefined ? $numpad : false,
+			newWardrobeStyle: $newWardrobeStyle !== undefined ? $newWardrobeStyle : true,
+			useNarrowMarket: $useNarrowMarket !== undefined ? $useNarrowMarket : false,
+			skipStatisticsConfirmation: $skipStatisticsConfirmation !== undefined ? $skipStatisticsConfirmation : false,
+			showDebugRenderer: $showDebugRenderer !== undefined ? $showDebugRenderer : !!StartConfig.debug,
+		};>>
+
 	<!-- v0.3.11.4 creampie.npc.penis and tentacle fix -->
 	<!-- IMPORTANT NOTE: please REMOVE this section if these stats come back into use -->
 	<<if _version lte 31104>>
diff --git a/game/base-clothing/canvasmodel-img.twee b/game/base-clothing/canvasmodel-img.twee
index 1e78381497..38832c5f7f 100644
--- a/game/base-clothing/canvasmodel-img.twee
+++ b/game/base-clothing/canvasmodel-img.twee
@@ -8,7 +8,7 @@ Render full player image.
 	<<selectmodel "main" "sidebar">>
 	<<modelprepare-player-body>>
 	<<modelprepare-player-clothes>>
-	<<if $sidebarAnimations isnot false>>
+	<<if $options.sidebarAnimations isnot false>>
 		<<animatemodel _args[0]>>
 	<<else>>
 		<<rendermodel _args[0]>>
@@ -50,7 +50,7 @@ for (let i = 0; i < $skinColor.tanLoc.length; i++) {
 
 _modeloptions.skin_type = $skinColor.natural || "light";
 _modeloptions.skin_tone = tanValByName["body"];
-if ($skinColor.tanningEnabled is true){
+if ($options.tanningEnabled is true){
 	for (let loc in tanValByName) {
 		if (loc !== 'body') {
 			_modeloptions['skin_tone_'+loc] = tanValByName[loc];
@@ -240,7 +240,7 @@ if ($skinColor.tanningEnabled is true){
  -     ███ ███  ██   ██ ██    ██    ██ ██   ████  ██████  ███████
 -->
 
-<<if $bodywritingImages is true>>
+<<if $options.bodywritingImages is true>>
 	<<for _label, _value range $skin>>
 		<<if _value.writing>>
 			<<set _modeloptions["writing_"+_label] to setup.bodywriting_namebyindex[_value.index]>>
@@ -266,9 +266,9 @@ if ($skinColor.tanningEnabled is true){
 <<else>>
 	<<set _modeloptions.trauma to $trauma gte ($traumamax * 0.9)>>
 <</if>>
-<<set _modeloptions.blink to $blinkingdisable is "f">>
+<<set _modeloptions.blink to $options.blinkingEnabled>>
 <<set _modeloptions.eyes_bloodshot to $pain gte 100 and $willpowerpain is 0 or $tiredness >= C.tiredness.max>>
-<<set _modeloptions.eyes_half to $halfcloseddisable isnot "t" and ($arousal gte ($arousalmax / 5) * 4 or $orgasmdown gte 1) and $trauma lt ($traumamax * 0.9) and $pain lt 60 and $eyelidTEST is true or ($possessed or $tiredness >= C.tiredness.max * 0.75)>>
+<<set _modeloptions.eyes_half to $options.halfClosedEnabled and ($arousal gte ($arousalmax / 5) * 4 or $orgasmdown gte 1) and $trauma lt ($traumamax * 0.9) and $pain lt 60 and $eyelidTEST is true or ($possessed or $tiredness >= C.tiredness.max * 0.75)>>
 
 <!-- Brows -->
 <<if $trauma gte $traumamax or $possessed>>
@@ -565,7 +565,7 @@ Set model options & filters for player clothes
 	<<set _modeloptions.drip_anal to "">>
 	<<set _modeloptions.drip_mouth to "">>
 
-	<<if $neverNudeMenus>>
+	<<if $options.neverNudeMenus>>
 		<<set _modeloptions.crotch_visible to false>>
 		<<set _modeloptions.penis to "">>
 		<<if $player.gender_appearance neq "m" or $player.perceived_breastsize gte 3>>
@@ -584,7 +584,7 @@ Set model options & filters for player clothes
 		<<set _modeloptions.worn_under_lower_colour to ($worn.under_lower.colourCustom ? $worn.under_lower.colourCustom : $worn.under_lower.colour)>>
 	<</if>>
 
-	<<if $sidebarRenderer is 'both'>>
+	<<if $options.sidebarRenderer is 'both'>>
 		<<rendermodel 'canvasimg-both'>>
 	<<else>>
 		<<rendermodel>>
diff --git a/game/base-clothing/clothing-sets.twee b/game/base-clothing/clothing-sets.twee
index 39f99a8829..be517dc33e 100644
--- a/game/base-clothing/clothing-sets.twee
+++ b/game/base-clothing/clothing-sets.twee
@@ -526,8 +526,6 @@
 <</widget>>
 
 <<widget "outfitEditor">>
-<h3>Outfit Editor</h3>
-
 <<link "Filter Options">><<toggleclass "#outfitEditorFilter" "hidden">><</link>> |
 <<link "Help">><<toggleclass "#outfitEditorHelp" "hidden">><</link>>
 
diff --git a/game/base-clothing/images.twee b/game/base-clothing/images.twee
index 143835ed5f..e7ba6ff434 100644
--- a/game/base-clothing/images.twee
+++ b/game/base-clothing/images.twee
@@ -1,10 +1,10 @@
 :: Widgets Img [widget]
 <<widget "img">>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.sidebar[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.sidebar[($options.tanImgEnabled ? "t" : "f")]>>
 <<charLight "118px" "187px">>
-<div id="img" @class="limitedColourContainerClasses() + ($sidebarAnimations isnot false ? '':' noAnimations')">
-<<if $sidebarRenderer is 'canvas'>>
+<div id="img" @class="limitedColourContainerClasses() + ($options.sidebarAnimations isnot false ? '':' noAnimations')">
+<<if $options.sidebarRenderer is 'canvas'>>
 	<<for _i to 1; _i lte $spraymax; _i++>>
 		<<if $spray gte _i>>
 			<img @id="'spray'+_i" src="img/ui/pepperspray.png">
@@ -14,7 +14,7 @@
 	<</for>>
 	<<canvasimg>>
 <<else>>
-	<<if $sidebarRenderer is 'both'>>
+	<<if $options.sidebarRenderer is 'both'>>
 		<<canvasimg 'canvasimg-both'>>
 	<</if>>
 	/*Prep for image checks*/
@@ -77,7 +77,7 @@
 			<img @id="'spray'+_i" src="img/ui/emptyspray.png">
 		<</if>>
 	<</for>>
-	<<if $skinColor.tanImgEnabled is "t">>
+	<<if $options.tanImgEnabled>>
 		<<if $skinColor.tanValues[0] isnot $skinColor.tanValues[2]>>
 			<img class="layer-base anim-idle-2f" @src="_img.baseTanSwimshorts" @style="'filter: '+_filters.swimshorts">
 			<img class="layer-base anim-idle-2f" @src="_img.baseTanSwimsuit_UUpper" @style="'filter: '+_filters.swimsuitTop">
@@ -92,7 +92,7 @@
 		<<else>>
 			<img class="layer-breasts anim-idle-2f" @src="_img['breasts'+ _breastSize]" @style="'filter: '+_filters.breasts">
 		<</if>>
-		<<if $skinColor.tanImgEnabled is "t" and $skinColor.tanValues[0] isnot $skinColor.tanValues[1]>>
+		<<if $options.tanImgEnabled and $skinColor.tanValues[0] isnot $skinColor.tanValues[1]>>
 			<img class="layer-breasts anim-idle-2f" @src="_img.baseTanBikini_UUpper + _breastSize + '.png'" @style="'filter: '+_filters.bikiniTop">
 		<</if>>
 	<</if>>
@@ -253,7 +253,7 @@
 		<</if>>
 	<</if>>
 
-	<<if $bodywritingImages is true>>
+	<<if $options.bodywritingImages is true>>
 		<<if $skin.forehead.writing>>
 			<<if $skin.forehead.type is "text">>
 				<<if $skin.forehead.sprites and $skin.forehead.sprites.length > 0 and $skin.forehead.sprites.includes('forehead')>>
@@ -608,7 +608,7 @@
 	<<set _diagram = _args[0] ? 1 : 0>>
 	<<set _animIdle = _diagram ? "" : "anim-idle-2f">>
 
-	<<if $skinColor.tanImgEnabled is "t">>
+	<<if $options.tanImgEnabled>>
 		<<set _red = "/red">>
 	<<else>>
 		<<set _red = "">>
@@ -628,7 +628,7 @@
 		<<set _iris = "iris">>
 		<<set _trauma = "">>
 	<</if>>
-	<<if $blinkingdisable is "f" and _diagram is 0>>
+	<<if $options.blinkingEnabled and _diagram is 0>>
 		<<set _blink = "eyes-blink" + _trauma>>
 	<<else>>
 		<<set _blink = "">>
@@ -638,7 +638,7 @@
 	<<else>>
 		<<set _sclera = "sclera">>
 	<</if>>
-	<<if $halfcloseddisable isnot "t" and ($arousal gte ($arousalmax / 5) * 4 or $orgasmdown gte 1) and _trauma is "" and $pain lt 60 and _diagram is 0 and $eyelidTEST is true or $possessed>>
+	<<if $options.halfClosedEnabled and ($arousal gte ($arousalmax / 5) * 4 or $orgasmdown gte 1) and _trauma is "" and $pain lt 60 and _diagram is 0 and $eyelidTEST is true or $possessed>>
 		<<set _half = "_halfclosed">>
 	<<else>>
 		<<set _half = "">>
@@ -3224,13 +3224,13 @@
 
 <<widget "player-base-body">>
 	<<set _filters to $skinColor.current>>
-	<<set _img to setup.tanImg.sidebar[$skinColor.tanImgEnabled]>>
+	<<set _img to setup.tanImg.sidebar[($options.tanImgEnabled ? "t" : "f")]>>
 	<div id="img" @class="limitedColourContainerClasses() + ' noAnimations'">
 		<<charLight "118px" "187px" "limited">>
-		<<if $sidebarRenderer is 'canvas' or $sidebarRenderer is 'both'>> /* <img> renderer */
+		<<if $options.sidebarRenderer is 'canvas' or $options.sidebarRenderer is 'both'>> /* <img> renderer */
 			<<canvas-player-base-body>>
 		<</if>>
-		<<if $sidebarRenderer is 'img' or $sidebarRenderer is 'both'>> /* legacy renderer */
+		<<if $options.sidebarRenderer is 'img' or $options.sidebarRenderer is 'both'>> /* legacy renderer */
 		/*Prep for image checks*/
 		<<switch $player.perceived_breastsize>>
 		<<case 12>>
@@ -3254,7 +3254,7 @@
 		<img class="layer-base" @src="_img.basenoarms" @style="'filter: '+_filters.body">
 		<img class="layer-basehead" @src="_img.basehead" @style="'filter: '+_filters.body">
 
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<<if $skinColor.tanValues[0] isnot $skinColor.tanValues[2]>>
 				<img class="layer-base" @src="_img.baseTanSwimshorts" @style="'filter: '+_filters.swimshorts">
 				<img class="layer-base" @src="_img.baseTanSwimsuit_UUpper" @style="'filter: '+_filters.swimsuitTop">
@@ -3402,7 +3402,7 @@
 	<</if>>
 
 
-		<<if $neverNudeMenus>> /* If player doesn't want to see nude character in menus, render the default breifs or bra + panties on their body */
+		<<if $options.neverNudeMenus>> /* If player doesn't want to see nude character in menus, render the default breifs or bra + panties on their body */
 			<<if $player.gender_appearance neq "m" or $player.perceived_breastsize gte 3>>
 				<div class="clothes-div layer-under_upper">
 					<img class="clothes-pale-white" src="img/clothes/under_upper/plainbra/full.png" style="">
@@ -3421,7 +3421,7 @@
 			<</if>>
 		<<else>>
 			<img class="layer-breasts" @src="_img['breasts'+ _breastSize]" @style="'filter: '+_filters.breasts">
-			<<if $skinColor.tanImgEnabled is "t" and $skinColor.tanValues[0] isnot $skinColor.tanValues[1]>>
+			<<if $options.tanImgEnabled and $skinColor.tanValues[0] isnot $skinColor.tanValues[1]>>
 				<img class="layer-breasts" @src="_img.baseTanBikini_UUpper + _breastSize + '.png'" @style="'filter: '+_filters.bikiniTop">
 			<</if>>
 
@@ -3466,6 +3466,6 @@
 		<</if>>
 
 		<<faceimg 1>>
-		<</if>> /* $sidebarRenderer is img */
+		<</if>> /* $options.sidebarRenderer is img */
 	</div>
 <</widget>>
diff --git a/game/base-clothing/lighting.twee b/game/base-clothing/lighting.twee
index 41bfab22ba..08b26c61aa 100644
--- a/game/base-clothing/lighting.twee
+++ b/game/base-clothing/lighting.twee
@@ -1,48 +1,52 @@
 :: Character lighting widgets [widget]
 <<widget "charLight">>
-	/* Position glow and spotlight */
-	<<set _offsetX = _args[0]>>
-	<<set _offsetY = _args[1]>>
+	<<if $options.characterLightEnabled and $options.images is 1>>
+		/* Position glow and spotlight */
+		<<set _offsetX = _args[0]>>
+		<<set _offsetY = _args[1]>>
 
-	/* If _class == "limited" then only show spotlight and glow */
-	<<set _class = _args[2] || "">>
+		/* If _class == "limited" then only show spotlight and glow */
+		<<set _class = _args[2] || "">>
 
-	<<set _angelDemonBalance = ($angel / 6 - $demon / 6) * $lightTFColor>>
-	<<set _sliderMult = 0.5>>
+		<<set _angelDemonBalance = ($angel / 6 - $demon / 6) * $options.lightTFColor>>
+		<<set _sliderMult = 0.5>>
 
-	<div @class="'char-light ' + _class" @style="
-	'--offsetX: ' + _offsetX + 
-	'; --offsetY: ' + _offsetY + 
-	'; --spotlight: ' + ($lightSpotlight * _sliderMult) + 
-	'; --gradient: ' + ($lightGradient * _sliderMult) + 
-	'; --glow: ' + ($lightGlow * _sliderMult) + 
-	'; --flat: ' + ($lightFlat * _sliderMult)
-	">
-		<div class="angel" @style="'opacity: ' + _angelDemonBalance"></div>
-		<div class="demon" @style="'opacity: ' + -_angelDemonBalance"></div>
-	</div>
+		<div @class="'char-light ' + _class" @style="
+			'--offsetX: ' + _offsetX + 
+			'; --offsetY: ' + _offsetY + 
+			'; --spotlight: ' + ($options.lightSpotlight * _sliderMult) + 
+			'; --gradient: ' + ($options.lightGradient * _sliderMult) + 
+			'; --glow: ' + ($options.lightGlow * _sliderMult) + 
+			'; --flat: ' + ($options.lightFlat * _sliderMult)
+			">
+			<div class="angel" @style="'opacity: ' + _angelDemonBalance"></div>
+			<div class="demon" @style="'opacity: ' + -_angelDemonBalance"></div>
+		</div>
+	<</if>>
 <</widget>>
 
 <<widget "charLightCombat">>
-	<<set _position = _args[0] || "">>
-	<<set _props = _args[1] || []>>
-	<<if _position == "doggy">>
-		<<if _props.includes("haybale") or _props.includes("milk")>>
-			<<set _heightOffset = "225px">>
-		<<elseif _props.includes("bench")>>
-			<<set _heightOffset = "240px">>
-		<<elseif _props.includes("table")>>
-			<<set _heightOffset = "277px">>
-		<</if>>
-	<<elseif _position == "missionary">>
-		<<if _props.includes("haybale") or _props.includes("milk")>>
-			<<set _heightOffset = "225px">>
-		<<elseif _props.includes("bench")>>
-			<<set _heightOffset = "228px">>
-		<<elseif _props.includes("table")>>
-			<<set _heightOffset = "265px">>
+	<<if $options.characterLightEnabled and $options.images is 1 and $options.combatImages is 1>>
+		<<set _position = _args[0] || "">>
+		<<set _props = _args[1] || []>>
+		<<if _position == "doggy">>
+			<<if _props.includes("haybale") or _props.includes("milk")>>
+				<<set _heightOffset = "225px">>
+			<<elseif _props.includes("bench")>>
+				<<set _heightOffset = "240px">>
+			<<elseif _props.includes("table")>>
+				<<set _heightOffset = "277px">>
+			<</if>>
+		<<elseif _position == "missionary">>
+			<<if _props.includes("haybale") or _props.includes("milk")>>
+				<<set _heightOffset = "225px">>
+			<<elseif _props.includes("bench")>>
+				<<set _heightOffset = "228px">>
+			<<elseif _props.includes("table")>>
+				<<set _heightOffset = "265px">>
+			<</if>>
 		<</if>>
-	<</if>>
 
-	<div @class="'char-light-combat ' + _position" @style="'--lightIntensity: ' + $lightCombat + (_heightOffset ? '; --heightOffset: ' + _heightOffset : '')"></div>
+		<div @class="'char-light-combat ' + _position" @style="'--lightIntensity: ' + $options.lightCombat + (_heightOffset ? '; --heightOffset: ' + _heightOffset : '')"></div>
+	<</if>>
 <</widget>>
diff --git a/game/base-clothing/wardrobes.twee b/game/base-clothing/wardrobes.twee
index 3956435fda..29c25475d5 100644
--- a/game/base-clothing/wardrobes.twee
+++ b/game/base-clothing/wardrobes.twee
@@ -359,7 +359,7 @@ __Clothing sets__
 __Clothing__
 <br>
 
-<<if $newWardrobeStyle>>
+<<if $options.newWardrobeStyle>>
 	<<dynamic "wardrobeLinks" "wardrobeLinks">>
 	<<dynamic "wardrobeContents" "wardrobeList">>
 <<else>>
diff --git a/game/base-combat/actions-feet.twee b/game/base-combat/actions-feet.twee
index 5a4e3adb0b..1217c9b6e7 100644
--- a/game/base-combat/actions-feet.twee
+++ b/game/base-combat/actions-feet.twee
@@ -93,7 +93,7 @@
 <</widget>>
 
 <<widget "feetshoes">>
-<<if $feettarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $feettarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if !$worn.feet.type.includes("shackle") and !$worn.feet.type.includes("naked")>>
 		<<set _feetaction["Kick off your shoes"] to "feetshoes">>
 	<</if>>
@@ -101,7 +101,7 @@
 <</widget>>
 
 <<widget "feetsocks">>
-<<if $feettarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $feettarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if $worn.feet.type.includes("shackle") or $worn.feet.type.includes("naked")>>
 		<<if $worn.legs.state is "ankles">>
 			<<set _feetaction["Kick off your legwear"] to "feetsocks">>
diff --git a/game/base-combat/actions-hands.twee b/game/base-combat/actions-hands.twee
index 9e4768b5bb..9fd20eface 100644
--- a/game/base-combat/actions-hands.twee
+++ b/game/base-combat/actions-hands.twee
@@ -6,7 +6,7 @@
 		<<set _leftaction["Punch"] to "lefthit">>
 	<</if>>
 <</if>>
-<<if $lefttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<set _leftaction["Hold behind back"] to "behind">>
 	<<leftcoverface>>
 <</if>>
@@ -168,7 +168,7 @@
 */
 
 <<widget "leftclothesnew">>
-<<if $lefttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if $worn.over_upper.state is setup.clothes.over_upper[clothesIndex('over_upper', $worn.over_upper)].state_base and $worn.over_upper.state_top is setup.clothes.over_upper[clothesIndex('over_upper', $worn.over_upper)].state_top_base and !$worn.over_upper.type.includes("naked")>>
 		<<set _leftaction["Displace your "+$worn.over_upper.name] to "over_upper">>
 	<</if>>
@@ -314,7 +314,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<elseif $vaginause is 0>>
 			<<set _leftaction["Cover your pussy"] to "leftcovervaginameek">>
 		<</if>>
-	<<elseif $lefttarget is "self" or $targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
+	<<elseif $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
 		<<if $vaginause is "cover">>
 			<<set _leftaction["Keep covering your pussy"] to "leftcovervagina">>
 		<<elseif $vaginause is 0>>
@@ -334,7 +334,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 				<<set _leftaction["Cover your " + _penis] to "leftcoverpenismeek">>
 			<</if>>
 		<</if>>
-	<<elseif $lefttarget is "self" or $targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
+	<<elseif $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
 		<<if $penisuse is "cover">>
 			<<set _leftaction["Keep covering your " + _penis] to "leftcoverpenis">>
 		<<elseif $penisuse is 0>>
@@ -352,7 +352,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<else>>
 			<<set _leftaction["Cover your ass"] to "leftcoveranusmeek">>
 		<</if>>
-	<<elseif $lefttarget is "self" or $targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
+	<<elseif $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
 		<<if $anususe is "cover">>
 			<<set _leftaction["Keep covering your ass"] to "leftcoveranus">>
 		<<else>>
@@ -361,7 +361,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 	<</if>>
 <</if>>
 
-<<if $lefttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if $worn.under_lower.name isnot "naked">>
 		<<if $worn.under_lower.state is "thighs" or $worn.under_lower.state is "knees" or $worn.under_lower.state is "ankles">>
 			<<set _leftaction["Pull up your " + $worn.under_lower.name] to "leftunderpull">>
@@ -426,7 +426,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 <</widget>>
 
 <<widget "leftCondom">>
-<<if $lefttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if !["mouthEntrance","mouthImminent","mouthPenetration","pussyPenetration","anusPenetration"].includes($penisstate) and $player.penisExist>>
 		<<if !$player.condom and $condoms gt 0 and $parasite.penis.name is undefined>>
 			<<set _leftaction["Put on a condom (" + $condoms + ")"] to "peniscondom">>
@@ -470,7 +470,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<set _rightaction["Punch"] to "righthit">>
 	<</if>>
 <</if>>
-<<if $righttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<set _rightaction["Hold behind back"] to "behind">>
 	<<rightcoverface>>
 <</if>>
@@ -626,7 +626,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 */
 
 <<widget "rightclothesnew">>
-<<if $righttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if $worn.over_upper.state is setup.clothes.over_upper[clothesIndex('over_upper', $worn.over_upper)].state_base and $worn.over_upper.state_top is setup.clothes.over_upper[clothesIndex('over_upper', $worn.over_upper)].state_top_base and !$worn.over_upper.type.includes("naked")>>
 		<<set _rightaction["Displace your "+$worn.over_upper.name] to "over_upper">>
 	<</if>>
@@ -776,7 +776,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<elseif $vaginause is 0>>
 			<<set _rightaction["Cover your pussy"] to "rightcovervaginameek">>
 		<</if>>
-	<<elseif $righttarget is "self" or $targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
+	<<elseif $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
 		<<if $vaginause is "cover">>
 			<<set _rightaction["Keep covering your pussy"] to "rightcovervagina">>
 		<<elseif $vaginause is 0>>
@@ -796,7 +796,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 				<<set _rightaction["Cover your " + _penis] to "rightcoverpenismeek">>
 			<</if>>
 		<</if>>
-	<<elseif $righttarget is "self" or $targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
+	<<elseif $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
 		<<if $penisuse is "cover">>
 			<<set _rightaction["Keep covering your " + _penis] to "rightcoverpenis">>
 		<<elseif $penisuse is 0>>
@@ -814,7 +814,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<else>>
 			<<set _rightaction["Cover your ass"] to "rightcoveranusmeek">>
 		<</if>>
-	<<elseif $righttarget is "self" or $targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
+	<<elseif $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1 or $NPCList[0].state is "stalk">>
 		<<if $anususe is "cover">>
 			<<set _rightaction["Keep covering your ass"] to "rightcoveranus">>
 		<<else>>
@@ -822,7 +822,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<</if>>
 	<</if>>
 <</if>>
-<<if $righttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if $worn.under_lower.name isnot "naked">>
 		<<if $worn.under_lower.state is "thighs" or $worn.under_lower.state is "knees" or $worn.under_lower.state is "ankles">>
 			<<set _rightaction["Pull up your " + $worn.under_lower.name] to "rightunderpull">>
@@ -886,7 +886,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 <</widget>>
 
 <<widget "rightCondom">>
-<<if $lefttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+<<if $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 	<<if !["mouthEntrance","mouthImminent","mouthPenetration","pussyPenetration","anusPenetration"].includes($penisstate) and $player.penisExist>>
 		<<if !$player.condom and $condoms gt 0>>
 			<<set _rightaction["Put on a condom (" + $condoms + ")"] to "peniscondom">>
@@ -967,14 +967,14 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 <<widget "removeButtplug">>
 	<<if _args[0]>>
 		<<if _args[0] is "left">>
-			<<if $lefttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+			<<if $lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 				<<if $worn.lower.anus_exposed gte 1 and $worn.under_lower.anus_exposed gte 1 and !["othermouthImminent","othermouth","imminent","doubleimminent","penetrated","doublepenetrated"].includes($anusstate) and playerHasButtPlug()>>
 					<<set _leftaction["Remove your "+$worn.butt_plug.name] to "removebuttplug">>
 				<</if>>
 			<</if>>
 		<</if>>
 		<<if _args[0] is "right">>
-			<<if $righttarget is "self" or $targetYourself is false or _targetnumber is 1>>
+			<<if $righttarget is "self" or $options.targetYourself is false or _targetnumber is 1>>
 				<<if $worn.lower.anus_exposed gte 1 and $worn.under_lower.anus_exposed gte 1 and !["othermouthImminent","othermouth","imminent","doubleimminent","penetrated","doublepenetrated"].includes($anusstate) and playerHasButtPlug()>>
 					<<set _rightaction["Remove your "+$worn.butt_plug.name] to "removebuttplug">>
 				<</if>>
@@ -987,7 +987,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 	<<if _args[0] isnot undefined>>
 		<<if $worn.lower.state isnot setup.clothes.lower[clothesIndex('lower', $worn.lower)].state_base or setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1 or $worn.lower.type.includes("naked")>>
 			<<if _args[0] is "left">>
-				<<if $promiscuity gt 14 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+				<<if $promiscuity gt 14 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 					<<if $player.vaginaExist>>
 						<<set _leftaction["Play with your pussy"] to "leftmasturbatepussy">>
 					<</if>>
@@ -997,7 +997,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 				<</if>>
 			<</if>>
 			<<if _args[0] is "right">>
-				<<if $promiscuity gt 14 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+				<<if $promiscuity gt 14 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 					<<if $player.vaginaExist>>
 						<<set _rightaction["Play with your pussy"] to "rightmasturbatepussy">>
 					<</if>>
@@ -1011,7 +1011,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 <</widget>>
 
 <<widget "applyLube">>
-	<<if _args[0] is "left" and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _args[0] is "left" and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 
 		<<set _items to window.listUniqueCarriedSextoys()>>
 
@@ -1040,7 +1040,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<</if>>
 	<</if>>
 
-	<<if _args[0] is "right" and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _args[0] is "right" and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 
 		<<set _items to window.listUniqueCarriedSextoys()>>
 		<<for _i; _i < _items.length; _i++>>
@@ -1097,7 +1097,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 
 			/* Masturbate */
 			<<if $worn.lower.state isnot setup.clothes.lower[clothesIndex('lower', $worn.lower)].state_base or setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1 or $worn.lower.type.includes("naked")>>
-				<<if $promiscuity gt 34 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+				<<if $promiscuity gt 34 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 					<<if $player.vaginaExist and $currentSexToyLeft.type.includes("dildo")>>
 						<<set _leftaction["Move your "+$currentSexToyLeft.name+" to your pussy"] to "dildoSelfPussyEntrance">>
 					<</if>>
@@ -1136,7 +1136,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 
 				/* Masturbate */
 			<<if $worn.lower.state isnot setup.clothes.lower[clothesIndex('lower', $worn.lower)].state_base or setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1 or $worn.lower.type.includes("naked")>>
-				<<if $promiscuity gt 34 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+				<<if $promiscuity gt 34 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 					<<if $player.vaginaExist and $currentSexToyRight.type.includes("dildo")>>
 						<<set _rightaction["Move your "+$currentSexToyRight.name+" to your pussy"] to "dildoSelfPussyEntrance">>
 					<</if>>
@@ -1156,7 +1156,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 	<<if _args[0] isnot undefined>>
 		<<if _args[0] is "left">>
 			<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
-			<<if $promiscuity gt 34 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+			<<if $promiscuity gt 34 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 				<<if $_genitals_exposed and $vaginause is 0>>
 					<<set _leftaction["Push your " + $currentSexToyLeft.name + " in"] to "dildoSelfPussy">>
 				<</if>>
@@ -1170,7 +1170,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<</if>>
 		<<if _args[0] is "right">>
 			<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
-			<<if $promiscuity gt 34 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+			<<if $promiscuity gt 34 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 				<<if $_genitals_exposed and $vaginause is 0>>
 					<<set _rightaction["Push your " + $currentSexToyRight.name + " in"] to "dildoSelfPussy">>
 				<</if>>
@@ -1190,7 +1190,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<if _args[0] is "left">>
 			<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
 			<<set $_anus_exposed to $worn.over_lower.anus_exposed gte 1 and ($worn.lower.anus_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.anus_exposed gte 1 and $worn.genitals.anus_exposed gte 1>>
-			<<if $promiscuity gt 34 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+			<<if $promiscuity gt 34 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 				<<if $_anus_exposed and $anususe is 0>>
 					<<set _leftaction["Push your " + $currentSexToyLeft.name + " in"] to "dildoSelfAnus">>
 				<</if>>
@@ -1205,7 +1205,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 		<<if _args[0] is "right">>
 			<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
 			<<set $_anus_exposed to $worn.over_lower.anus_exposed gte 1 and ($worn.lower.anus_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.anus_exposed gte 1 and $worn.genitals.anus_exposed gte 1>>
-			<<if $promiscuity gt 34 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+			<<if $promiscuity gt 34 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 				<<if $_anus_exposed and $anususe is 0>>
 					<<set _rightaction["Push your " + $currentSexToyRight.name + " in"] to "dildoSelfAnus">>
 				<</if>>
@@ -1224,7 +1224,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 	<<if _args[0] isnot undefined>>
 		<<if _args[0] is "left">>
 			<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
-			<<if $promiscuity gt 34 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+			<<if $promiscuity gt 34 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 				<<if $_genitals_exposed and $penisuse is 0>>
 					<<set _leftaction["Penetrate your " + $currentSexToyLeft.name] to "strokerSelfPenis">>
 				<</if>>
@@ -1236,7 +1236,7 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 
 		<<if _args[0] is "right">>
 			<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
-			<<if $promiscuity gt 34 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+			<<if $promiscuity gt 34 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 				<<if $_genitals_exposed and $penisuse is 0>>
 					<<set _rightaction["Penetrate your " + $currentSexToyRight.name] to "strokerSelfPenis">>
 				<</if>>
diff --git a/game/base-combat/actions-speech.twee b/game/base-combat/actions-speech.twee
index 426f27cea3..40e39f9d7d 100644
--- a/game/base-combat/actions-speech.twee
+++ b/game/base-combat/actions-speech.twee
@@ -125,14 +125,14 @@
 <<widget "replaceAskColour">>
 <<switch $askAction>>
 	<<case "askchoke" "condoms" "damagedCondoms" "noCondoms">>
-		<<if $combatControls is "radio">>
+		<<if $options.combatControls is "radio">>
 			<<addclass "#askLabel" "sub">><<removeclass "#askLabel" "brat">>
 		<<else>>
 			<<addclass "#askDifficulty" "subList">><<removeclass "#askDifficulty" "bratList">>
 		<</if>>
 	<<case "askchoke">>
 	<<default>>
-		<<if $combatControls is "radio">>
+		<<if $options.combatControls is "radio">>
 			<<addclass "#askLabel" "brat">><<removeclass "#askLabel" "sub">>
 		<<else>>
 			<<addclass "#askDifficulty" "bratList">><<removeclass "#askDifficulty" "subList">>
diff --git a/game/base-combat/actions.twee b/game/base-combat/actions.twee
index 0d3272825e..aab8dea87a 100644
--- a/game/base-combat/actions.twee
+++ b/game/base-combat/actions.twee
@@ -29,7 +29,7 @@
 	<</if>>
 <</if>>
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<if $position isnot "stalk">>
 		<<timed 100ms>>
 			<<combatimg>>
@@ -65,7 +65,7 @@
 
 <<if $trance lte 0 and $panicparalysis is 0 and ($panicviolence is 0 or $position is "stalk")>>
 	<<if $dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and !$possessed>>
-		<<if $images is 1 and $combatimages is 1 and $consensual is 1 and $position_lock isnot 1>>
+		<<if $options.images is 1 and $options.combatImages is 1 and $consensual is 1 and $position_lock isnot 1>>
 			<<if $position is "doggy">>
 				| <label>Roll over <<radiobutton "$bodyaction" "missionary">></label>
 			<<elseif $position is "missionary">>
@@ -78,7 +78,7 @@
 		<</if>>
 	<</if>>
 
-	<<if $combatControls isnot "disabled">>
+	<<if $options.combatControls isnot "disabled">>
 		<<generateActionsMan>>
 	<</if>>
 	<br>
diff --git a/game/base-combat/actionsGeneration.twee b/game/base-combat/actionsGeneration.twee
index 8fe016eb74..6dcd3b11fc 100644
--- a/game/base-combat/actionsGeneration.twee
+++ b/game/base-combat/actionsGeneration.twee
@@ -5,7 +5,7 @@
 
 /*Sends the required variables to the chosen display type*/
 <<widget "generateCombatAction">>
-<<switch $combatControls>>
+<<switch $options.combatControls>>
 	<<case "radio">>
 		<<generateCombatActionRadio _args[0] _args[1] _args[3]>>
 	<<case "lists" "limitedLists">>
@@ -59,46 +59,46 @@
 <</if>>
 <<if !$stalk_end>>
 	<div id="listContainer">
-		<div id="leftaction" @class="$combatControls + 'Control'">
+		<div id="leftaction" @class="$options.combatControls + 'Control'">
 			<<leftActionInit>>
 		</div>
 
-		<div id="rightaction" @class="$combatControls + 'Control'">
+		<div id="rightaction" @class="$options.combatControls + 'Control'">
 			<<rightActionInit>>
 		</div>
 
-		<div id="feetaction" @class="$combatControls + 'Control'">
+		<div id="feetaction" @class="$options.combatControls + 'Control'">
 			<<feetActionInit>>
 		</div>
 
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInit>>
 		</div>
 
 		<<if $player.penisExist or $worn.genitals.type.includes("strap-on") or playerHasStrapon()>>
-			<div id="penisaction" @class="$combatControls + 'Control'">
+			<div id="penisaction" @class="$options.combatControls + 'Control'">
 				<<penisActionInit>>
 			</div>
 		<</if>>
 
 		<<if $player.vaginaExist>>
-			<div id="vaginaaction" @class="$combatControls + 'Control'">
+			<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 				<<vaginaActionInit>>
 			</div>
 		<</if>>
 
-		<div id="anusaction" @class="$combatControls + 'Control'">
+		<div id="anusaction" @class="$options.combatControls + 'Control'">
 			<<anusActionInit>>
 		</div>
 
 		<<if $chestuse isnot 0>>
-			<div id="chestaction" @class="$combatControls + 'Control'">
+			<div id="chestaction" @class="$options.combatControls + 'Control'">
 				<<chestActionInit>>
 			</div>
 		<</if>>
 
 		<<if $thighuse isnot 0>>
-			<div id="thighaction" @class="$combatControls + 'Control'">
+			<div id="thighaction" @class="$options.combatControls + 'Control'">
 				<<thighActionInit>>
 			</div>
 		<</if>>
@@ -245,7 +245,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1 and $stealstateleft is undefined>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1 and $stealstateleft is undefined>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -254,7 +254,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions or _leftGold is true ?'gold':'')">Your left hand is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and $stealstateleft is undefined>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and $stealstateleft is undefined>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -320,7 +320,7 @@
 	<<if _targetYourself is true and _targetnumber gt 1>>
 		<<set _targetlistarms["Yourself"] to "self">>
 	<</if>>
-	<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+	<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 		Target: <span onchange="actionsreplace('left')">
 		<<listbox "$lefttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -329,7 +329,7 @@
 	<</if>>
 	<<set _leftOptions to "heldSexToy">>
 	<span @class="($lastOptions.left isnot _leftOptions or _leftGold is true ?'gold':'')">Your left hand is holding the <<print $currentSexToyLeft.name>>.</span>
-	<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+	<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 		Target: <span onchange="actionsreplace('left')">
 		<<listbox "$lefttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -411,7 +411,7 @@
 		<<generateCombatAction _leftaction "leftaction" _textColor $leftaction>>
 
 		/*Checks/Difficulty*/
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="leftactionDifficulty">
 				<<leftactionDifficulty>>
 			</div>
@@ -610,7 +610,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1 and $stealstateright is undefined>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1 and $stealstateright is undefined>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -619,7 +619,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions or _rightGold is true ?'gold':'')">Your right hand is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and $stealstateright is undefined>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and $stealstateright is undefined>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -685,7 +685,7 @@
 	<<if _targetYourself is true and _targetnumber gt 1>>
 		<<set _targetlistarms["Yourself"] to "self">>
 	<</if>>
-	<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+	<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 		Target: <span onchange="actionsreplace('right')">
 		<<listbox "$righttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -694,7 +694,7 @@
 	<</if>>
 	<<set _rightOptions to "heldSexToy">>
 	<span @class="($lastOptions.right isnot _rightOptions or _rightGold is true ?'gold':'')">Your right hand is holding the $currentSexToyRight.name.</span>
-	<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+	<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 		Target: <span onchange="actionsreplace('right')">
 		<<listbox "$righttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -776,7 +776,7 @@
 		<<generateCombatAction _rightaction "rightaction" _textColor $rightaction>>
 
 		/*Checks/Difficulty*/
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="rightactionDifficulty">
 				<<rightactionDifficulty>>
 			</div>
@@ -966,7 +966,7 @@
 			<<if _targetYourself is true and _targetnumber gt 1>>
 				<<set _targetlistall["Yourself"] to "self">>
 			<</if>>
-			<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+			<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 				<<if !(($leftleg is "grappled" and $rightleg is "grappled") or ($leftleg is "bound" and $rightleg is "bound"))>>
 					Target: <span onchange="actionsreplace('feet')">
 					<<listbox "$feettarget" autoselect>>
@@ -994,7 +994,7 @@
 				<<set _feetOptions to "free">>
 				<span @class="($lastOptions.feet isnot _feetOptions or _feetGold is true ?'gold':'')">Your feet are free.</span>
 			<</if>>
-			<<if $combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
+			<<if $options.combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
 				Target: <span onchange="actionsreplace('feet')">
 				<<listbox "$feettarget" autoselect>>
 					<<optionsfrom _targetlistall>>
@@ -1059,7 +1059,7 @@
 			<<generateCombatAction _feetaction "feetaction" _textColor $feetaction>>
 
 			/*Checks/Difficulty*/
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="feetactionDifficulty">
 					<<feetactionDifficulty>>
 				</div>
@@ -1166,7 +1166,7 @@
 <<else>>
 	<<switch $mouthuse>>
 	<<case 0>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('mouth')">
 			<<listbox "$mouthtarget" autoselect>>
 				<<optionsfrom _targetlist>>
@@ -1175,7 +1175,7 @@
 		<</if>>
 		<<set _mouthOptions to "free">>
 		<span @class="($lastOptions.mouth isnot _mouthOptions or _mouthGold is true ?'gold':'')">Your mouth is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('mouth')">
 			<<listbox "$mouthtarget" autoselect>>
 				<<optionsfrom _targetlist>>
@@ -1283,7 +1283,7 @@
 		<<generateCombatAction _mouthaction "mouthaction" _textColor $mouthaction>>
 
 		/*Checks/Difficulty*/
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="mouthactionDifficulty">
 				<<mouthactionDifficulty>>
 			</div>
@@ -1327,7 +1327,7 @@
 			<<default>>
 				<<set $_label to "bratList">>
 		<</switch>>
-		<div id="askDifficulty" @class="($combatControls is 'radio' ? '' : $_label)" style="display:inline;">
+		<div id="askDifficulty" @class="($options.combatControls is 'radio' ? '' : $_label)" style="display:inline;">
 			<<listbox "$askAction" autoselect>>
 				<<optionsfrom _askActions>>
 			<</listbox>>
@@ -1418,7 +1418,7 @@
 <<if $dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and !$possessed>>
 	<<switch $penisstate>>
 	<<case 0>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('penis')">
 			<<listbox "$penistarget" autoselect>>
 				<<optionsfrom _targetlist>>
@@ -1427,7 +1427,7 @@
 		<</if>>
 		<<set _penisOptions to "free">>
 		<span @class="($lastOptions.penis isnot _penisOptions or _penisGold is true ?'gold':'')">Your <<penis>> is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('penis')">
 			<<listbox "$penistarget" autoselect>>
 				<<optionsfrom _targetlist>>
@@ -1531,7 +1531,7 @@
 			<<generateCombatAction _penisaction "penisaction" _textColor $penisaction>>
 
 			/*Checks/Difficulty*/
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="penisactionDifficulty">
 					<<penisactionDifficulty>>
 				</div>
@@ -1636,7 +1636,7 @@
 <<if $dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and !$possessed>>
 	<<switch $vaginastate>>
 	<<case 0>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('vagina')">
 			<<listbox "$vaginatarget" autoselect>>
 				<<optionsfrom _targetlist>>
@@ -1645,7 +1645,7 @@
 		<</if>>
 		<<set _vaginaOptions to "free">>
 		<span @class="($lastOptions.vagina isnot _vaginaOptions ?'gold':'')">Your <<pussy>> is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('vagina')">
 			<<listbox "$vaginatarget" autoselect>>
 				<<optionsfrom _targetlist>>
@@ -1671,7 +1671,7 @@
 			<<getDoubleTargetList>>
 		<</if>>
 		<<if _secondtarget is true>>
-			<<if $combatControls is "radio" and _targetnumber gt 1>><br><</if>>
+			<<if $options.combatControls is "radio" and _targetnumber gt 1>><br><</if>>
 			<<if $vaginadoubletarget is undefined>>
 				<<set $vaginadoubletarget to _firstdoubletarget>>
 			<</if>>
@@ -1688,7 +1688,7 @@
 			<<getDoubleTargetList>>
 		<</if>>
 		<<if _secondtarget is true>>
-			<<if $combatControls is "radio" and _targetnumber gt 1>><br><</if>>
+			<<if $options.combatControls is "radio" and _targetnumber gt 1>><br><</if>>
 			<<if $vaginadoubletarget is undefined>>
 				<<set $vaginadoubletarget to _firstdoubletarget>>
 			<</if>>
@@ -1705,7 +1705,7 @@
 			<<getDoubleTargetList>>
 		<</if>>
 		<<if _secondtarget is true>>
-			<<if $combatControls is "radio" and _targetnumber gt 1>><br><</if>>
+			<<if $options.combatControls is "radio" and _targetnumber gt 1>><br><</if>>
 			<<if $vaginadoubletarget is undefined>>
 				<<set $vaginadoubletarget to _firstdoubletarget>>
 			<</if>>
@@ -1805,7 +1805,7 @@
 			<<generateCombatAction _vaginaaction "vaginaaction" _textColor $vaginaaction>>
 
 			/*Checks/Difficulty*/
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="vaginaactionDifficulty">
 					<<vaginaactionDifficulty>>
 				</div>
@@ -1912,7 +1912,7 @@
 	<<else>>
 		<<switch $anusstate>>
 		<<case 0>>
-			<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+			<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 				Target: <span onchange="actionsreplace('anus')">
 				<<listbox "$anustarget" autoselect>>
 					<<optionsfrom _targetlist>>
@@ -1921,7 +1921,7 @@
 			<</if>>
 			<<set _anusOptions to "free">>
 			<span @class="($lastOptions.anus isnot _anusOptions or _anusGold ?'gold':'')">Your <<bottom>> is free.</span>
-			<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+			<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 				Target: <span onchange="actionsreplace('anus')">
 				<<listbox "$anustarget" autoselect>>
 					<<optionsfrom _targetlist>>
@@ -1953,7 +1953,7 @@
 				<<getDoubleTargetList>>
 			<</if>>
 			<<if _secondtarget is true>>
-				<<if $combatControls is "radio" and _targetnumber gt 1>><br><</if>>
+				<<if $options.combatControls is "radio" and _targetnumber gt 1>><br><</if>>
 				<<if $anusdoubletarget is undefined>>
 					<<set $anusdoubletarget to _firstdoubletarget>>
 				<</if>>
@@ -1973,7 +1973,7 @@
 				<<getDoubleTargetList>>
 			<</if>>
 			<<if _secondtarget is true>>
-				<<if $combatControls is "radio" and _targetnumber gt 1>><br><</if>>
+				<<if $options.combatControls is "radio" and _targetnumber gt 1>><br><</if>>
 				<<if $anusdoubletarget is undefined>>
 					<<set $anusdoubletarget to _firstdoubletarget>>
 				<</if>>
@@ -2044,7 +2044,7 @@
 			<<generateCombatAction _anusaction "anusaction" _textColor $anusaction>>
 
 			/*Checks/Difficulty*/
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="anusactionDifficulty">
 					<<anusactionDifficulty>>
 				</div>
@@ -2152,7 +2152,7 @@
 			<<generateCombatAction _chestaction "chestaction" _textColor $chestaction>>
 
 			/*Checks/Difficulty*/
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="chestactionDifficulty">
 					<<chestactionDifficulty>>
 				</div>
@@ -2214,7 +2214,7 @@
 			<<generateCombatAction _thighaction "thighaction" _textColor $thighaction>>
 
 			/*Checks/Difficulty*/
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="thighactionDifficulty">
 					<<thighactionDifficulty>>
 				</div>
@@ -2284,7 +2284,7 @@
 			<<if _firsttarget is undefined>>
 				<<set _firsttarget to _namecontroller>>
 			<</if>>
-			<<if $targetYourself is true>>
+			<<if $options.targetYourself is true>>
 				<<set _targetYourself to true>>
 			<</if>>
 			<<break>>
@@ -2304,7 +2304,7 @@
 			<<if _firsttarget is undefined>>
 				<<set _firsttarget to _namecontroller>>
 			<</if>>
-			<<if $targetYourself is true>>
+			<<if $options.targetYourself is true>>
 				<<set _targetYourself to true>>
 			<</if>>
 			<<if $_wraithbreak is true>>
@@ -2319,7 +2319,7 @@
 <</if>>
 <<if $swarm.type isnot 0>>
 	<<set _targetlistall[$swarm.type.toUpperFirst()] to "swarm">><<set _targetnumber += 1>>
-	<<if $targetYourself is true>>
+	<<if $options.targetYourself is true>>
 		<<set _targetYourself to true>>
 	<</if>>
 <</if>>
@@ -2417,7 +2417,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -2426,7 +2426,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions or _leftGold is true ?'gold':'')">Your left hand is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -2453,7 +2453,7 @@
 	<<if _targetYourself is true and _targetnumber gt 1>>
 		<<set _targetlistarms["Yourself"] to "self">>
 	<</if>>
-	<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+	<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 		Target: <span onchange="actionsreplace('left')">
 		<<listbox "$lefttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -2462,7 +2462,7 @@
 	<</if>>
 	<<set _leftOptions to "heldSexToy">>
 	<span @class="($lastOptions.left isnot _leftOptions or _leftGold is true ?'gold':'')">Your left hand is holding the <<print $currentSexToyLeft.name>>.</span>
-	<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+	<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 		Target: <span onchange="actionsreplace('left')">
 		<<listbox "$lefttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -2478,7 +2478,7 @@
 	<<set _leftGold to true>>
 <</if>>
 <<leftActionsSelf>>
-<<if Object.keys(_leftaction).length gt 0>><<if $combatControls is "radio">><br><</if>>
+<<if Object.keys(_leftaction).length gt 0>><<if $options.combatControls is "radio">><br><</if>>
 	<<if Object.values(_leftaction).includes($leftactiondefault) is false or _args[0] is true or $leftactiondefault is "rest">>
 		<<set _defaultsCombatAction to "leftaction">>
 		<<set _actionsSet = DefaultActions.get($defaultsCombatType, $defaultsType, _defaultsCombatAction)>>
@@ -2499,14 +2499,14 @@
 	<<set _textColor to combatListColor('leftaction', (Object.values(_leftaction).includes($leftaction) ? $leftaction : Object.values(_leftaction)[0]), "Self")>>
 	<<generateCombatActionOthers _leftaction "leftaction" _textColor $leftaction "Self">>
 
-	<<if $combatControls.includes("ists")>>
+	<<if $options.combatControls.includes("ists")>>
 		<div id="leftactionDifficulty">
 			<<leftactionDifficulty>>
 		</div>
 		<div id="leftactionDifficultySelf">
 			<<leftactionDifficultySelf>>
 		</div>
-	<</if>><<if $combatControls is "radio">><br><br><</if>>/* Seems to render no effect..? */
+	<</if>><<if $options.combatControls is "radio">><br><br><</if>>/* Seems to render no effect..? */
 <</if>>
 <<set $lastOptions.left to clone(_leftOptions)>>
 <</widget>>
@@ -2605,7 +2605,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -2614,7 +2614,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions or _rightGold is true ?'gold':'')">Your right hand is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -2641,7 +2641,7 @@
 	<<if _targetYourself is true and _targetnumber gt 1>>
 		<<set _targetlistarms["Yourself"] to "self">>
 	<</if>>
-	<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+	<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 		Target: <span onchange="actionsreplace('right')">
 		<<listbox "$righttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -2650,7 +2650,7 @@
 	<</if>>
 	<<set _rightOptions to "heldSexToy">>
 	<span @class="($lastOptions.right isnot _rightOptions or _rightGold is true ?'gold':'')">Your right hand is holding the $currentSexToyRight.name.</span>
-	<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+	<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 		Target: <span onchange="actionsreplace('right')">
 		<<listbox "$righttarget" autoselect>>
 			<<optionsfrom _targetlistarms>>
@@ -2665,7 +2665,7 @@
 	<<set _rightGold to true>>
 <</if>>
 <<rightActionsSelf>>
-<<if Object.keys(_rightaction).length gt 0>><<if $combatControls is "radio">><br><</if>>
+<<if Object.keys(_rightaction).length gt 0>><<if $options.combatControls is "radio">><br><</if>>
 	<<if Object.values(_rightaction).includes($rightactiondefault) is false or _args[0] is true or $rightactiondefault is "rest">>
 		<<set _defaultsCombatAction to "rightaction">>
 		<<set _actionsSet = DefaultActions.get($defaultsCombatType, $defaultsType, _defaultsCombatAction)>>
@@ -2686,14 +2686,14 @@
 	<<set _textColor to combatListColor('rightaction', (Object.values(_rightaction).includes($rightaction) ? $rightaction : Object.values(_rightaction)[0]), "Self")>>
 	<<generateCombatActionOthers _rightaction "rightaction" _textColor $rightaction "Self">>
 
-	<<if $combatControls.includes("ists")>>
+	<<if $options.combatControls.includes("ists")>>
 		<div id="rightactionDifficulty">
 			<<rightactionDifficulty>>
 		</div>
 		<div id="rightactionDifficultySelf">
 			<<rightactionDifficultySelf>>
 		</div>
-	<</if>><<if $combatControls is "radio">><br><br><</if>>/* Seems to render no effect..? */
+	<</if>><<if $options.combatControls is "radio">><br><br><</if>>/* Seems to render no effect..? */
 <</if>>
 <<set $lastOptions.right to clone(_rightOptions)>>
 <</widget>>
@@ -2782,7 +2782,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistall["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('feet')">
 			<<listbox "$feettarget" autoselect>>
 				<<optionsfrom _targetlistall>>
@@ -2791,7 +2791,7 @@
 		<</if>>
 		<<set _feetOptions to "free">>
 		<span @class="($lastOptions.feet isnot _feetOptions or _feetGold is true ?'gold':'')">Your feet are free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and _feetOptions is "free">><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and _feetOptions is "free">><br>
 			Target: <span onchange="actionsreplace('feet')">
 			<<listbox "$feettarget" autoselect>>
 				<<optionsfrom _targetlistall>>
@@ -2806,7 +2806,7 @@
 		<<set _feetGold to true>>
 	<</if>>
 	<<feetActionsSelf>>
-	<<if Object.keys(_feetaction).length gt 0>><<if $combatControls is "radio">><br><</if>>
+	<<if Object.keys(_feetaction).length gt 0>><<if $options.combatControls is "radio">><br><</if>>
 		<<if Object.values(_feetaction).includes($feetactiondefault) is false or _args[0] is true or $feetactiondefault is "rest">>
 			<<set _defaultsCombatAction to "feetaction">>
 			<<set _actionsSet = DefaultActions.get($defaultsCombatType, $defaultsType, _defaultsCombatAction)>>
@@ -2827,11 +2827,11 @@
 		<<set _textColor to combatListColor('feetaction', (Object.values(_feetaction).includes($feetaction) ? $feetaction : Object.values(_feetaction)[0]), "Self")>>
 		<<generateCombatActionOthers _feetaction "feetaction" _textColor $feetaction "Self">>
 
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="feetactionDifficulty">
 				<<feetactionDifficulty>>
 			</div>
-		<</if>><<if $combatControls is "radio">><br><</if>>/* Seems to render no effect..? */
+		<</if>><<if $options.combatControls is "radio">><br><</if>>/* Seems to render no effect..? */
 	<</if>>
 	<<set $lastOptions.feet to clone(_feetOptions)>>
 <<else>>
@@ -2863,7 +2863,7 @@
 <</widget>>
 
 <<widget "generateCombatActionOthers">>
-<<switch $combatControls>>
+<<switch $options.combatControls>>
 	<<case "radio">>
 		<<generateCombatActionOthersRadio _args[0] _args[1] _args[3] _args[4]>>
 	<<case "lists" "limitedLists">>
@@ -2925,7 +2925,7 @@
 	<</if>>
 <</if>>
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<if $position isnot "stalk">>
 		<<timed 100ms>>
 			<<combatimg>>
@@ -2963,7 +2963,7 @@
 
 <<if $trance lte 0 and $panicparalysis is 0 and ($panicviolence is 0 or $position is "stalk")>>
 	<<if $dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and ["man", "plant", "beast"].includes($enemytype)>>
-		<<if $images is 1 and $combatimages is 1 and $consensual is 1 and $position_lock isnot 1>>
+		<<if $options.images is 1 and $options.combatImages is 1 and $consensual is 1 and $position_lock isnot 1>>
 			<<if $position is "doggy">>
 				| <label>Roll over <<radiobutton "$bodyaction" "missionary">></label>
 			<<elseif $position is "missionary">>
@@ -2997,7 +2997,7 @@
 <</if>>
 <<if _targetnumber gte 1>>
 	<div id="listContainer">
-		<div id="leftaction" @class="$combatControls + 'Control'">
+		<div id="leftaction" @class="$options.combatControls + 'Control'">
 			<<switch $lefttarget>>
 			<<case "self">>
 				<<leftActionInitSelf>>
@@ -3028,7 +3028,7 @@
 			<</switch>>
 		</div>
 
-		<div id="rightaction" @class="$combatControls + 'Control'">
+		<div id="rightaction" @class="$options.combatControls + 'Control'">
 			<<switch $righttarget>>
 			<<case "self">>
 				<<rightActionInitSelf>>
@@ -3060,7 +3060,7 @@
 		</div>
 
 		<<if Object.values(_targetlistall).length gte 1>>
-			<div id="feetaction" @class="$combatControls + 'Control'">
+			<div id="feetaction" @class="$options.combatControls + 'Control'">
 				<<switch $feettarget>>
 				<<case "self">>
 					<<feetActionInitSelf>>
@@ -3091,29 +3091,29 @@
 		<<if Object.values(_targetlist).length gte 1>>
 			<<switch $mouthtarget>>
 			<<case "tentacles">>
-				<div id="mouthaction" @class="$combatControls + 'Control'">
+				<div id="mouthaction" @class="$options.combatControls + 'Control'">
 					<<mouthActionInitTentacle>>
 				</div>
 			<<case "struggle">>
-				<div id="mouthaction" @class="$combatControls + 'Control'">
+				<div id="mouthaction" @class="$options.combatControls + 'Control'">
 					<<mouthActionInitStruggle>>
 				</div>
 			<<default>>
 				<<if !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined))>>
-					<div id="mouthaction" @class="$combatControls + 'Control'">
+					<div id="mouthaction" @class="$options.combatControls + 'Control'">
 						<<mouthActionInit>>
 					</div>
 				<<elseif Object.values(_targetlist)[0] isnot "tentacles" and Object.values(_targetlist)[0] isnot "struggle">>
-					<div id="mouthaction" @class="$combatControls + 'Control'">
+					<div id="mouthaction" @class="$options.combatControls + 'Control'">
 						<<mouthActionInit>>
 					</div>
 				<<else>>
 					<<if $mouthuse is "struggle" and $struggle.mouth.creature>>
-						<div id="mouthaction" @class="$combatControls + 'Control'">
+						<div id="mouthaction" @class="$options.combatControls + 'Control'">
 							<<mouthActionInitStruggle>>
 						</div>
 					<<elseif $mouthstate isnot 0>>
-						<div id="mouthaction" @class="$combatControls + 'Control'">
+						<div id="mouthaction" @class="$options.combatControls + 'Control'">
 							<<mouthActionInitTentacle>>
 						</div>
 					<</if>>
@@ -3123,25 +3123,25 @@
 			<<if $player.penisExist or $worn.genitals.type.includes("strap-on") or playerHasStrapon()>>
 				<<switch $penistarget>>
 				<<case "tentacles">>
-					<div id="penisaction" @class="$combatControls + 'Control'">
+					<div id="penisaction" @class="$options.combatControls + 'Control'">
 						<<penisActionInitTentacle>>
 					</div>
 				<<case "struggle">>
-					<div id="penisaction" @class="$combatControls + 'Control'">
+					<div id="penisaction" @class="$options.combatControls + 'Control'">
 						<<penisActionInitStruggle>>
 					</div>
 				<<default>>
 					<<if Object.values(_targetlist)[0] isnot "tentacles" and Object.values(_targetlist)[0] isnot "struggle">>
-						<div id="penisaction" @class="$combatControls + 'Control'">
+						<div id="penisaction" @class="$options.combatControls + 'Control'">
 							<<penisActionInit>>
 						</div>
 					<<else>>
 						<<if $penisuse is "struggle">>
-							<div id="penisaction" @class="$combatControls + 'Control'">
+							<div id="penisaction" @class="$options.combatControls + 'Control'">
 								<<penisActionInitStruggle>>
 							</div>
 						<<elseif $penisstate isnot 0>>
-							<div id="penisaction" @class="$combatControls + 'Control'">
+							<div id="penisaction" @class="$options.combatControls + 'Control'">
 								<<penisActionInitTentacle>>
 							</div>
 						<</if>>
@@ -3152,25 +3152,25 @@
 			<<if $player.vaginaExist>>
 				<<switch $vaginatarget>>
 				<<case "tentacles">>
-					<div id="vaginaaction" @class="$combatControls + 'Control'">
+					<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 						<<vaginaActionInitTentacle>>
 					</div>
 				<<case "struggle">>
-					<div id="vaginaaction" @class="$combatControls + 'Control'">
+					<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 						<<vaginaActionInitStruggle>>
 					</div>
 				<<default>>
 					<<if Object.values(_targetlist)[0] isnot "tentacles" and Object.values(_targetlist)[0] isnot "struggle">>
-						<div id="vaginaaction" @class="$combatControls + 'Control'">
+						<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 							<<vaginaActionInit>>
 						</div>
 					<<else>>
 						<<if $vaginause is "struggle">>
-							<div id="vaginaaction" @class="$combatControls + 'Control'">
+							<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 								<<vaginaActionInitStruggle>>
 							</div>
 						<<elseif $vaginastate isnot 0>>
-							<div id="vaginaaction" @class="$combatControls + 'Control'">
+							<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 								<<vaginaActionInitTentacle>>
 							</div>
 						<</if>>
@@ -3180,25 +3180,25 @@
 
 			<<switch $anustarget>>
 			<<case "tentacles">>
-				<div id="anusaction" @class="$combatControls + 'Control'">
+				<div id="anusaction" @class="$options.combatControls + 'Control'">
 					<<anusActionInitTentacle>>
 				</div>
 			<<case "struggle">>
-				<div id="anusaction" @class="$combatControls + 'Control'">
+				<div id="anusaction" @class="$options.combatControls + 'Control'">
 					<<anusActionInitStruggle>>
 				</div>
 			<<default>>
 				<<if Object.values(_targetlist)[0] isnot "tentacles" and Object.values(_targetlist)[0] isnot "struggle">>
-					<div id="anusaction" @class="$combatControls + 'Control'">
+					<div id="anusaction" @class="$options.combatControls + 'Control'">
 						<<anusActionInit>>
 					</div>
 				<<else>>
 					<<if $anususe is "struggle">>
-						<div id="anusaction" @class="$combatControls + 'Control'">
+						<div id="anusaction" @class="$options.combatControls + 'Control'">
 							<<anusActionInitStruggle>>
 						</div>
 					<<elseif $anusstate isnot 0>>
-						<div id="anusaction" @class="$combatControls + 'Control'">
+						<div id="anusaction" @class="$options.combatControls + 'Control'">
 							<<anusActionInitTentacle>>
 						</div>
 					<</if>>
@@ -3206,21 +3206,21 @@
 			<</switch>>
 
 			<<if $chestuse isnot "struggle">>
-				<div id="chestaction" @class="$combatControls + 'Control'">
+				<div id="chestaction" @class="$options.combatControls + 'Control'">
 					<<chestActionInitStruggle>>
 				</div>
 			<<elseif $chestuse is "tentaclerub">>
-				<div id="chestaction" @class="$combatControls + 'Control'">
+				<div id="chestaction" @class="$options.combatControls + 'Control'">
 					<<chestActionInitTentacle>>
 				</div>
 			<<elseif $chestuse is "penis">>
-				<div id="chestaction" @class="$combatControls + 'Control'">
+				<div id="chestaction" @class="$options.combatControls + 'Control'">
 					<<chestActionInit>>
 				</div>
 			<</if>>
 
 			<<if $thighuse isnot 0>>
-				<div id="thighaction" @class="$combatControls + 'Control'">
+				<div id="thighaction" @class="$options.combatControls + 'Control'">
 					<<thighActionInit>>
 				</div>
 			<</if>>
diff --git a/game/base-combat/beast-images.twee b/game/base-combat/beast-images.twee
index bc7028b462..3d8fe7dcbf 100644
--- a/game/base-combat/beast-images.twee
+++ b/game/base-combat/beast-images.twee
@@ -469,7 +469,7 @@
 <<set _na to $active_enemy>>
 
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.doggy[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.doggy[($options.tanImgEnabled ? "t" : "f")]>>
 <<if $NPCList[_na].type is "dolphin" and $enemytype is "beast">>
 	<<if $NPCList[_na].penis is "anusentrance" and $position isnot "missionary">>
 		<img @class="'layer-beastback anim-doggy-4f-'+_animspeed" src="img/sex/doggy/beast/dolphin/activedolphinanusentrance.png">
@@ -512,14 +512,14 @@
 	<</if>>
 
 	<<if $NPCList[_na].penis is "leftarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activedolphinlefthandpenis">
 		<</if>>
 		<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activedolphinlefthand" @style="'filter: '+_filters.body">
 	<</if>>
 
 	<<if $NPCList[_na].penis is "rightarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activedolphinrighthandpenis">
 		<</if>>
 		<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activedolphinrighthand" @style="'filter: '+_filters.body">
@@ -567,14 +567,14 @@
 	<</if>>
 
 	<<if $NPCList[_na].penis is "leftarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activebearlefthandpenis">
 		<</if>>
 		<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activebearlefthand" @style="'filter: '+_filters.body">
 	<</if>>
 
 	<<if $NPCList[_na].penis is "rightarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activebearrighthandpenis">
 		<</if>>
 		<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activebearrighthand" @style="'filter: '+_filters.body">
@@ -622,14 +622,14 @@
 	<</if>>
 
 	<<if $NPCList[_na].penis is "leftarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activebearrighthandpenis">
 		<</if>>
 		<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activecatlefthand" @style="'filter: '+_filters.body">
 	<</if>>
 
 	<<if $NPCList[_na].penis is "rightarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activebearrighthandpenis">
 		<</if>>
 		<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activecatrighthand" @style="'filter: '+_filters.body">
@@ -805,14 +805,14 @@
 	<</if>>
 
 	<<if $NPCList[_na].penis is "leftarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activebeastlefthandpenis">
 		<</if>>
 		<img @class="'layer-sexbasefront anim-doggy-4f-'+_animspeed" @src="_img.activebeastlefthand" @style="'filter: '+_filters.body">
 	<</if>>
 
 	<<if $NPCList[_na].penis is "rightarm">>
-		<<if $skinColor.tanImgEnabled is "t">>
+		<<if $options.tanImgEnabled>>
 			<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activebeastrighthandpenis">
 		<</if>>
 		<img @class="'layer-sexbaseback anim-doggy-4f-'+_animspeed" @src="_img.activebeastrighthand" @style="'filter: '+_filters.body">
diff --git a/game/base-combat/close-images.twee b/game/base-combat/close-images.twee
index d285e9af8e..041b364ab1 100644
--- a/game/base-combat/close-images.twee
+++ b/game/base-combat/close-images.twee
@@ -5,10 +5,10 @@
     <<imgOpacity>>
 
     <<if $position is "wall">>
-        <<set _img to setup.tanImg.close["doggy"][$skinColor.tanImgEnabled]>>
+        <<set _img to setup.tanImg.close["doggy"][($options.tanImgEnabled ? "t" : "f")]>>
         <<set _position to "doggy">>
     <<else>>
-        <<set _img to setup.tanImg.close[$position][$skinColor.tanImgEnabled]>>
+        <<set _img to setup.tanImg.close[$position][($options.tanImgEnabled ? "t" : "f")]>>
         <<set _position to $position>>
     <</if>>
 
diff --git a/game/base-combat/doggy-images.twee b/game/base-combat/doggy-images.twee
index 68ecb4b552..24ee598e66 100644
--- a/game/base-combat/doggy-images.twee
+++ b/game/base-combat/doggy-images.twee
@@ -3,7 +3,7 @@
 <<voreimg>>
 <<closeimg>>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.doggy[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.doggy[($options.tanImgEnabled ? "t" : "f")]>>
 <<set _disabled to ["disabled","hidden"]>>
 <<set _xx to $enemynomax-1>>
 <<if _xx is -1>>
@@ -157,7 +157,7 @@
 		<img class="layer-sexpenis anim-idle-2f-slow" src="img/sex/machine/vaginal/doggy/entrance.png">
 	<<elseif $enemytype isnot "beast">>
 	<img class="layer-sexpenis anim-idle-2f-slow" src="img/sex/doggy/doggyvaginalimminent.png">
-		<<if $silhouettedisable is "f" and $anususe isnot "penis">>
+		<<if $options.silhouetteEnabled and $anususe isnot "penis">>
 		<img class="layer-shadowmanbackground anim-idle-2f-slow" src="img/sex/doggy/shadow/vaginalimminent.png">
 		<</if>>
 	<</if>>
@@ -183,7 +183,7 @@
 		<img class="layer-sexpenis anim-idle-2f-slow" src="img/sex/machine/anal/doggy/entrance.png">
 	<<elseif $enemytype isnot "beast">>
 <img class="layer-sexpenis anim-idle-2f-slow" src="img/sex/doggy/doggyanalimminent.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 		<img class="layer-shadowmanbackground anim-idle-2f-slow" src="img/sex/doggy/shadow/analimminent.png">
 		<</if>>
 	<</if>>
@@ -197,7 +197,7 @@
 		<img class="layer-sexpenis anim-idle-2f-slow" src="img/sex/machine/anal/doggy/entrance.png">
 	<<elseif $enemytype isnot "beast">>
 <img class="layer-sexpenis anim-idle-1f-slow" src="img/sex/doggy/doggyanalentrance.png">
-		<<if $silhouettedisable is "f" and $debug is 1>>
+		<<if $options.silhouetteEnabled and $debug is 1>>
 		<img class="layer-shadowmanbackground" src="img/sex/doggy/shadow/analentrance.png">
 		<</if>>
 	<</if>>
@@ -211,7 +211,7 @@
 		<img class="layer-sexpenis anim-idle-2f-slow" src="img/sex/machine/vaginal/doggy/entrance.png">
 	<<elseif $enemytype isnot "beast">>
 		<img class="layer-sexpenis anim-idle-1f-slow" src="img/sex/doggy/doggyvaginalentrance.png">
-		<<if $silhouettedisable is "f" and $anususe isnot "penis" and $debug is 1>>
+		<<if $options.silhouetteEnabled and $anususe isnot "penis" and $debug is 1>>
 		<img class="layer-shadowmanbackground" src="img/sex/doggy/shadow/vaginalentrance.png">
 		<</if>>
 	<</if>>
@@ -223,7 +223,7 @@
 <<if $mouthstate is "imminent">>
 	<<if $enemytype isnot "beast">>
 <img class="layer-parasite anim-idle-4f-mid" src="img/sex/doggy/doggyoralimminent.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 		<img class="layer-shadowmanforeground anim-idle-2f-slow" src="img/sex/doggy/shadow/oralimminent.png">
 		<</if>>
 	<</if>>
@@ -235,7 +235,7 @@
 <<if $mouthstate is "entrance">>
 	<<if $enemytype isnot "beast">>
 			<img class="layer-parasite anim-idle-4f-mid" src="img/sex/doggy/doggyoralentrance.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<img class="layer-shadowmanforeground anim-idle-2f-slow" src="img/sex/doggy/shadow/oralentrance.png">
 		<</if>>
 	<</if>>
@@ -533,7 +533,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 	<img class="layer-sexbaseoverlay" src="img/sex/doggy/active/body/doggyactivegoldchastitybelt.png">
 <</if>>
 
-<<if $bodywritingImages is true>>
+<<if $options.bodywritingImages is true>>
 	<<if $skin.left_cheek.writing>>
 		<<if $skin.left_cheek.type is "text">>
 			<img class="layer-sexskin anim-idle-2f" src="img/sex/doggy/bodywriting/left_cheek.png">
@@ -819,7 +819,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 <<if $mouthstate is "penetrated">>
 	<<if $enemytype isnot "beast">>
 <img @class="'layer-parasite anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactiveoral.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 		<img @class="'layer-shadowmanforeground anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activeoral.png">
 		<</if>>
 	<</if>>
@@ -838,7 +838,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 	<<elseif $enemytype isnot "beast">>
 		<<if $anusstate is "penetrated" or $anusstate is "doublepenetrated">>
 			<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactivevaginaldp.png">
-			<<if $silhouettedisable is "f">>
+			<<if $options.silhouetteEnabled>>
 				<<if $rightarm is "bound" or $rightarm is "grappled" or $rightarm is "behind">>
 					<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activevaginaldpbound.png">
 				<<else>>
@@ -847,7 +847,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 			<</if>>
 		<<else>>
 			<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactivevaginal.png">
-			<<if $silhouettedisable is "f">>
+			<<if $options.silhouetteEnabled>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activevaginal.png">
 			<</if>>
 		<</if>>
@@ -873,7 +873,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 		<<else>>
 			<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactiveanal.png">
 		<</if>>
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<<if $vaginastate is "doublepenetrated">>
 				<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activevaginaldoggydpp.png">
 			<<else>>
@@ -893,7 +893,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 	<<if $NPCList[$anustarget].penis is "anusdouble" and $NPCList[$anusdoubletarget].penis is "anusdouble">>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactiveanaldap.png">
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactiveanaldpp.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activeanal.png">
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activevaginaldoggydpp.png">
 		<</if>>
@@ -904,7 +904,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 	<<if $NPCList[$vaginatarget].penis is "vaginadouble" and $NPCList[$vaginadoubletarget].penis is "vaginadouble">>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactivevaginal.png">
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactivevaginaldp.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 
 			<<if $rightarm is "bound" or $rightarm is "grappled" or $rightarm is "behind">>
 				<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/doggy/shadow/activevaginal.png">
@@ -1021,7 +1021,7 @@ Lashes held in place during idle frames, and 4-frame hair overlay that didn't an
 <img @class="'layer-sexbaseoverlay anim-doggy-4f-'+_animspeed" src="img/sex/doggy/active/body/doggyactivegoldchastitybelt.png">
 <</if>>
 
-<<if $bodywritingImages is true>>
+<<if $options.bodywritingImages is true>>
 	<<if $skin.left_cheek.writing>>
 		<<if $skin.left_cheek.type is "text">>
 			<img @class="'layer-sexskin anim-doggy-4f-'+_animspeed" src="img/sex/doggy/bodywriting/left_cheek.png">
diff --git a/game/base-combat/ejaculation.twee b/game/base-combat/ejaculation.twee
index b93f83416a..5b8e3c69b1 100644
--- a/game/base-combat/ejaculation.twee
+++ b/game/base-combat/ejaculation.twee
@@ -2292,7 +2292,7 @@
 	<</if>>
 <</if>>
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<if $position isnot "stalk">>
 		<br>
 		<<combatimg>>
@@ -2755,7 +2755,7 @@
 <</if>>
 <br><br><br>
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<combatimg>>
 	<br>
 <</if>>
diff --git a/game/base-combat/images.twee b/game/base-combat/images.twee
index dab1bcf651..ecd5abbf78 100644
--- a/game/base-combat/images.twee
+++ b/game/base-combat/images.twee
@@ -22,7 +22,7 @@
 		<</if>>
 	<</if>>
 	<<if window.document.body.clientWidth lt 650>>
-		<div id="divandroidsex" @class="colourContainerClasses() + ($combatAnimations isnot false ? '':' noAnimations')">
+		<div id="divandroidsex" @class="colourContainerClasses() + ($options.combatAnimations isnot false ? '':' noAnimations')">
 			<<charLightCombat $position $prop>>
 			<<if $position is "missionary">>
 				<<missionaryimg>>
@@ -36,7 +36,7 @@
 			<<xrayimg>>
 		<</if>>
 	<<else>>
-		<div id="divsex" @class="colourContainerClasses() + ($combatAnimations isnot false ? '':' noAnimations')">
+		<div id="divsex" @class="colourContainerClasses() + ($options.combatAnimations isnot false ? '':' noAnimations')">
 			<<charLightCombat $position $prop>>
 			<<if $position is "missionary">>
 				<<missionaryimg>>
diff --git a/game/base-combat/init.twee b/game/base-combat/init.twee
index fb018c2ce2..83f591c969 100644
--- a/game/base-combat/init.twee
+++ b/game/base-combat/init.twee
@@ -1253,21 +1253,21 @@ otherwise there's no easy way of stopping NPC from shoving their stuff in PC's f
 		<hr>
 		<label class="cbtOption">
 			<p>Control types</p>
-			<<listbox "$combatControls" autoselect>>
+			<<listbox "$options.combatControls" autoselect>>
 				<<optionsfrom $_combatTypes>>
 			<</listbox>>
 		</label>
 		<label class="cbtOption">
 			<p>Scroll lock</p>
-			<<checkbox "$scroll_remember" false true autocheck>>
+			<<checkbox "$options.scrollRemember" false true autocheck>>
 		</label>
 		<label class="cbtOption">
 			<p>Target yourself</p>
-			<<checkbox "$targetYourself" false true autocheck>>
+			<<checkbox "$options.targetYourself" false true autocheck>>
 		</label>
 		<label class="cbtOption">
 			<p>Combat images</p>
-			<<checkbox "$combatimages" 0 1 autocheck>>
+			<<checkbox "$options.combatImages" 0 1 autocheck>>
 		</label>
 	</div>
 <</widget>>
diff --git a/game/base-combat/machine/actions.twee b/game/base-combat/machine/actions.twee
index fccdaca62e..59b06b0768 100644
--- a/game/base-combat/machine/actions.twee
+++ b/game/base-combat/machine/actions.twee
@@ -5,20 +5,20 @@
 	<<getTargetList>>
 <</if>>
 <div id="listContainer">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<leftActionInitMachine>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<rightActionInitMachine>>
 	</div>
 
-	<div id="feetaction" @class="$combatControls + 'Control'">
+	<div id="feetaction" @class="$options.combatControls + 'Control'">
 		<<feetActionInitMachine>>
 	</div>
 
 	<<if ($mouthuse is 0 and !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined)))>>
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInit>>
 		</div>
 	<</if>>
@@ -42,7 +42,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -51,7 +51,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -88,7 +88,7 @@
 	<<else>>
 		<<set _leftOptions to "bound">>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is bound and helpless.</span>
-	<</if>><<if $combatControls is "radio">><br><</if>>
+	<</if>><<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set $_changetype to true>><<leftActionInitVore>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
@@ -109,7 +109,7 @@
 		<div class="extraMargin">
 			<<generateCombatActionOthers _leftaction "leftaction" _textColor $leftaction "Machine">>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="leftactionDifficulty">
 				<<leftactionDifficulty>>
 			</div>
@@ -185,7 +185,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -194,7 +194,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -231,7 +231,7 @@
 	<<else>>
 		<<set _rightOptions to "bound">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is bound and helpless.</span>
-	<</if>><<if $combatControls is "radio">><br><</if>>
+	<</if>><<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set $_changetype to true>><<rightActionInitVore>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
@@ -252,7 +252,7 @@
 		<div class="extraMargin">
 			<<generateCombatActionOthers _rightaction "rightaction" _textColor $rightaction "Machine">>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="rightactionDifficulty">
 				<<rightactionDifficulty>>
 			</div>
@@ -319,7 +319,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistall["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			<<if ($leftleg is "grappled" and $rightleg is "grappled") or ($leftleg is "bound" and $rightleg is "bound")>>
 			<<else>>
 				Target: <span onchange="actionsreplace('feet')">
@@ -340,7 +340,7 @@
 			<<set _feetOptions to "free">>
 			<span @class="($lastOptions.feet isnot _feetOptions or _feetGold is true ?'gold':'')">Your legs are free.</span>
 		<</if>>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
 			Target: <span onchange="actionsreplace('feet')">
 			<<listbox "$feettarget" autoselect>>
 				<<optionsfrom _targetlistall>>
@@ -372,7 +372,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionOthers _feetaction "feetaction" _textColor $feetaction "Machine">>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="feetactionDifficulty">
 					<<feetactionDifficulty>>
 				</div>
@@ -438,12 +438,12 @@
 <<combatstate>>
 <<carryblock>>
 
-<<if $trance lte 0 and $panicparalysis is 0 and $panicviolence is 0 and $combatControls isnot "disabled">>
+<<if $trance lte 0 and $panicparalysis is 0 and $panicviolence is 0 and $options.combatControls isnot "disabled">>
 	<<generateActionsMachine>>
 <</if>>
 
 <<if $trance lte 0 and $dissociation lte 1 and $panicparalysis is 0 and $panicviolence is 0
-and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $combatControls is "disabled">>
+and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $options.combatControls is "disabled">>
 
 <<if $leftarm is 0>>
 	<br>
@@ -681,7 +681,7 @@ and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $com
 <</if>>
 
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<br><br>
 	<<timed 100ms>>
 		<<combatimg>>
diff --git a/game/base-combat/missionary-images.twee b/game/base-combat/missionary-images.twee
index 1e06c33fc8..e7ecdacfe9 100644
--- a/game/base-combat/missionary-images.twee
+++ b/game/base-combat/missionary-images.twee
@@ -2,7 +2,7 @@
 <<widget "missionaryimg">>
 <<closeimg>>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.missionary[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.missionary[($options.tanImgEnabled ? "t" : "f")]>>
 <<set _disabled to ["disabled","hidden"]>>
 <<set _xx to $enemynomax-1>>
 <<if _xx is -1>>
@@ -374,7 +374,7 @@ Same as above, but with eyelashes.
 	<img class="layer-sexbaseoverlay" src="img/sex/missionary/active/body/activegoldchastitybelt.png">
 <</if>>
 
-<<if $bodywritingImages is true>>
+<<if $options.bodywritingImages is true>>
 	<<if $skin.right_cheek.writing>>
 		<<if $skin.right_cheek.type is "text">>
 			<<if $skin.right_cheek.arrow is 1>>
@@ -666,7 +666,7 @@ Same as above, but with eyelashes.
 
 <<if $mouthstate is "penetrated">>
 	<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activeoral.png">
-		<<if $silhouettedisable is "f" and $enemytype isnot "beast">>
+		<<if $options.silhouetteEnabled and $enemytype isnot "beast">>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activeoral.png">
 		<</if>>
 	<<if $enemyarousal gte $enemyarousalmax>>
@@ -683,7 +683,7 @@ Same as above, but with eyelashes.
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/machine/vaginal/missionary/penetrated.png">
 	<<elseif $enemytype isnot "beast">>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activevaginal.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<<if ($penisstate is "penetrated" or $penisstate is "otheranus" or $mouthstate is "penetrated") and $anusstate isnot "doublepenetrated">>
 				<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activevaginalalt.png">
 			<<else>>
@@ -707,7 +707,7 @@ Same as above, but with eyelashes.
 	<<if $enemytype is "machine">>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/machine/anal/missionary/penetrated.png">
 	<<elseif $enemytype isnot "beast">>
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activeanal.png">
 		<<else>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activeanal.png">
@@ -725,12 +725,12 @@ Same as above, but with eyelashes.
 <<if $anusstate is "doublepenetrated">>
 	<<if $NPCList[$anustarget].penis is "anusdouble" and $NPCList[$anusdoubletarget].penis is "anusdouble">>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activeanaldoublemissionary.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activeanal.png">
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activemissionarydouble.png">
 		<</if>>
 	<<else>>
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activeanal.png">
 		<<else>>
 			<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activeanal.png">
@@ -747,13 +747,13 @@ Same as above, but with eyelashes.
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activevaginal.png">
 	<<if $NPCList[$vaginatarget].penis is "vaginadouble" and $NPCList[$vaginadoubletarget].penis is "vaginadouble">>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activevaginaldouble.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activevaginaldouble.png">
 			<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activemissionarydouble.png">
 		<</if>>
 	<<else>>
 		<img @class="'layer-sextears anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activevaginal.png">
-		<<if $silhouettedisable is "f">>
+		<<if $options.silhouetteEnabled>>
 			<<if $penisstate is "penetrated" or $penisstate is "otheranus" or $mouthstate is "penetrated">>
 				<img @class="'layer-shadowman anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activevaginalalt.png">
 			<<else>>
@@ -778,7 +778,7 @@ Same as above, but with eyelashes.
 <</if>>
 
 <<if $penisstate is "penetrated" and $enemytype isnot "beast" or $penisstate is "otheranus" and $enemytype isnot "beast">>
-	<<if $silhouettedisable is "f" and $NPCList[_na].type isnot "horse" and $NPCList[_na].type isnot "centaur">>
+	<<if $options.silhouetteEnabled and $NPCList[_na].type isnot "horse" and $NPCList[_na].type isnot "centaur">>
 		<img @class="'layer-foreground anim-doggy-4f-'+_animspeed" src="img/sex/missionary/shadow/activepenile.png">
 	<</if>>
 	<<if $orgasmdown gte 1 and $orgasmcount lte 24 and $femaleclimax isnot 1 and $condomPlayerPenisImg isnot true and !playerHasStrapon()>>
@@ -877,7 +877,7 @@ Same as above, but with eyelashes.
 	<img @class="'layer-sexbaseoverlay anim-doggy-4f-'+_animspeed" src="img/sex/missionary/active/body/activegoldchastitybelt.png">
 <</if>>
 
-<<if $bodywritingImages is true>>
+<<if $options.bodywritingImages is true>>
 	<<if $skin.right_cheek.writing>>
 		<<if $skin.right_cheek.type is "text">>
 			<<if $skin.right_cheek.arrow is 1>>
diff --git a/game/base-combat/stalk/stalk.twee b/game/base-combat/stalk/stalk.twee
index 09101c6c8c..0d6a347fb8 100644
--- a/game/base-combat/stalk/stalk.twee
+++ b/game/base-combat/stalk/stalk.twee
@@ -1060,7 +1060,7 @@
 <</widget>>
 
 <<widget "stalk_img">>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<br><br>
 	<div class="div_stalk">
 	<<for _i to 0; _i lt 8; _i++>>
diff --git a/game/base-combat/state.twee b/game/base-combat/state.twee
index 0ccd8b82f7..65df0cc228 100644
--- a/game/base-combat/state.twee
+++ b/game/base-combat/state.twee
@@ -157,7 +157,7 @@
 		<span class="pink">Your body pulses and spasms with orgasmic waves, preventing you from acting normally.</span>
 		<br>
 		<<disable>>
-		<<if $combatControls is "disabled" and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
+		<<if $options.combatControls is "disabled" and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
 			<<actionsorgasm>>
 		<</if>>
 	<</if>>
@@ -174,7 +174,7 @@
 			<span class="red">You are in too much pain to act normally.</span>
 			<br>
 			<<disable>>
-			<<if $combatControls is "disabled" and $orgasmdown lte 0 and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
+			<<if $options.combatControls is "disabled" and $orgasmdown lte 0 and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
 				<<actionspain>>
 			<</if>>
 		<</if>>
@@ -207,7 +207,7 @@
 		You feel disconnected from yourself, as if in a dream.
 		<br>
 		<<disable>>
-		<<if $combatControls is "disabled" and $orgasmdown lte 0 and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
+		<<if $options.combatControls is "disabled" and $orgasmdown lte 0 and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
 			<<if $pain lt 100 or $willpowerpain is undefined>>
 				<<actionsdissociation>>
 			<</if>>
@@ -227,7 +227,7 @@
 			<br>
 		<</if>>
 		<<disable>>
-		<<if $combatControls is "disabled" and $dissociation lte 1 and $orgasmdown lte 0 and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
+		<<if $options.combatControls is "disabled" and $dissociation lte 1 and $orgasmdown lte 0 and $panicviolence lte 0 and $panicparalysis lte 0 and $trance lte 0>>
 			<<actionspossessed>>
 		<</if>>
 		/* Updates the control caption at the top of the screen to include any control gained through the rest of the passage */
diff --git a/game/base-combat/struggle.twee b/game/base-combat/struggle.twee
index df791b66ec..66a99b4e12 100644
--- a/game/base-combat/struggle.twee
+++ b/game/base-combat/struggle.twee
@@ -193,15 +193,15 @@
 <hr>
 
 <div id="listContainer" style="margin-bottom:0px">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<leftActionInitStruggle>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<rightActionInitStruggle>>
 	</div>
 	<<if $dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined)>>
-		<div id="feetaction" @class="$combatControls + 'Control'">
+		<div id="feetaction" @class="$options.combatControls + 'Control'">
 			<<feetActionInitStruggle>>
 		</div>
 	<</if>>
@@ -210,7 +210,7 @@
 <<if ($mouthuse is "struggle" and $struggle.mouth.creature) or ($mouthuse is 0 and !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined)))>>
 	<hr>
 	<div id="listContainer" style="margin-bottom:0px">
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInitStruggle>>
 		</div>
 	</div>
@@ -220,7 +220,7 @@
 	<<if $vaginastate isnot 0 and $player.vaginaExist>>
 		<hr>
 		<div id="listContainer" style="margin-bottom:0px">
-			<div id="vaginaaction" @class="$combatControls + 'Control'">
+			<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 				<<vaginaActionInitStruggle>>
 			</div>
 		</div>
@@ -229,7 +229,7 @@
 	<<if $penisstate isnot 0 and $player.penisExist>>
 		<hr>
 		<div id="listContainer" style="margin-bottom:0px">
-			<div id="penisaction" @class="$combatControls + 'Control'">
+			<div id="penisaction" @class="$options.combatControls + 'Control'">
 				<<penisActionInitStruggle>>
 			</div>
 		</div>
@@ -238,7 +238,7 @@
 	<<if $anusstate isnot 0>>
 		<hr>
 		<div id="listContainer" style="margin-bottom:0px">
-			<div id="anusaction" @class="$combatControls + 'Control'">
+			<div id="anusaction" @class="$options.combatControls + 'Control'">
 				<<anusActionInitStruggle>>
 			</div>
 		</div>
@@ -247,7 +247,7 @@
 	<<if $chestuse isnot 0 and $chestuse isnot "squeezed">>
 		<hr>
 		<div id="listContainer" style="margin-bottom:0px">
-			<div id="chestaction" @class="$combatControls + 'Control'">
+			<div id="chestaction" @class="$options.combatControls + 'Control'">
 				<<chestActionInitStruggle>>
 			</div>
 		</div>
@@ -272,7 +272,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -281,7 +281,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions ? 'gold' : '')">Your left arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -289,7 +289,7 @@
 			</span><br>
 		<</if>>
 	<</if>>
-	<<if $combatControls is "radio">><br><</if>>
+	<<if $options.combatControls is "radio">><br><</if>>
 <<case "struggle">>
 	<<if $orgasmdown gte 1>>
 		<<set _leftOptions to "orgasm">>
@@ -315,7 +315,7 @@
 			<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm grips the $struggle.chest.creature over your chest.</span>
 		<</switch>>
 	<</if>>
-	<<if $combatControls is "radio">><br><</if>>
+	<<if $options.combatControls is "radio">><br><</if>>
 <<case "bound">>
 	<<set _leftOptions to "bound">>
 	<<if $orgasmdown gte 1>>
@@ -327,7 +327,7 @@
 	<<else>>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is bound.</span>
 	<</if>>
-	<<if $combatControls is "radio">><br><</if>>
+	<<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set $_changetype to true>><<leftActionInitVore>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
@@ -347,7 +347,7 @@
 		<</if>>
 		<<set _textColor to combatListColor('leftaction', (Object.values(_leftaction).includes($leftaction) ? $leftaction : Object.values(_leftaction)[0]), "Struggle")>>
 		<<generateCombatActionOthers _leftaction "leftaction" _textColor $leftaction "Struggle">>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="leftactionDifficulty">
 				<<leftactionDifficulty>>
 			</div>
@@ -371,7 +371,7 @@
 	<<set _leftaction["Guard"] to "guard">>
 	<<leftclothesnew>>
 
-	<<if $combatControls isnot "radio">>
+	<<if $options.combatControls isnot "radio">>
 		<<for $_part range ["mouth", "vagina", "penis", "anus", "chest"]>>
 			<<if V[$_part + 'use'] is "struggle" and $struggle[$_part].creature>>
 				<<set $_desc to ($leftactiondefault.includes($_part) ? '' : ' (' + $_part + ')')>>
@@ -421,7 +421,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -430,7 +430,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -438,7 +438,7 @@
 			</span><br>
 		<</if>>
 	<</if>>
-	<<if $combatControls is "radio">><br><</if>>
+	<<if $options.combatControls is "radio">><br><</if>>
 <<case "struggle">>
 	<<if $orgasmdown gte 1>>
 		<<set _rightOptions to "orgasm">>
@@ -464,7 +464,7 @@
 			<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm grips the $struggle.chest.creature over your chest.</span>
 		<</switch>>
 	<</if>>
-	<<if $combatControls is "radio">><br><</if>>
+	<<if $options.combatControls is "radio">><br><</if>>
 <<case "bound">>
 	<<set _rightOptions to "bound">>
 	<<if $orgasmdown gte 1>>
@@ -476,7 +476,7 @@
 	<<else>>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is bound.</span>
 	<</if>>
-	<<if $combatControls is "radio">><br><</if>>
+	<<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set $_changetype to true>><<rightActionInitVore>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
@@ -496,7 +496,7 @@
 		<</if>>
 		<<set _textColor to combatListColor('rightaction', (Object.values(_rightaction).includes($rightaction) ? $rightaction : Object.values(_rightaction)[0]), "Struggle")>>
 		<<generateCombatActionOthers _rightaction "rightaction" _textColor $rightaction "Struggle">>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="rightactionDifficulty">
 				<<rightactionDifficulty>>
 			</div>
@@ -521,7 +521,7 @@
 	<<set _rightaction["Guard"] to "guard">>
 	<<rightclothesnew>>
 
-	<<if $combatControls isnot "radio">>
+	<<if $options.combatControls isnot "radio">>
 		<<for $_part range ["mouth", "vagina", "penis", "anus", "chest"]>>
 			<<if V[$_part + 'use'] is "struggle" and $struggle[$_part].creature>>
 				<<set $_desc to ($rightactiondefault.includes($_part) ? '' : ' (' + $_part + ')')>>
@@ -561,7 +561,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistall["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			<<if ($leftleg is "grappled" and $rightleg is "grappled") or ($leftleg is "bound" and $rightleg is "bound")>>
 			<<else>>
 				Target: <span onchange="actionsreplace('feet')">
@@ -588,7 +588,7 @@
 			<<set _feetOptions to "free">>
 			<span @class="($lastOptions.feet isnot _feetOptions or _feetGold is true ?'gold':'')">Your feet are free.</span>
 		<</if>>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
 			Target: <span onchange="actionsreplace('feet')">
 			<<listbox "$feettarget" autoselect>>
 				<<optionsfrom _targetlistall>>
@@ -598,7 +598,7 @@
 		<<if _targetnumber is 1>>
 			<<set $feettarget to _firsttarget>>
 		<</if>>
-		<<if $combatControls is "radio">><br><</if>>
+		<<if $options.combatControls is "radio">><br><</if>>
 	<<case "penis" "othervagina" "bound" "walk" "run" "none">>
 		<<set $_changetype to true>><<feetActionInit>>
 	<<case "mechgrappled">>
@@ -615,7 +615,7 @@
 			<<set $feetaction to $feetactiondefault>>
 			<<set _textColor to combatListColor('feetaction', (Object.values(_feetaction).includes($feetaction) ? $feetaction : Object.values(_feetaction)[0]), "Struggle")>>
 			<<generateCombatActionOthers _feetaction "feetaction" _textColor $feetaction "Struggle">>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="feetactionDifficulty">
 					<<feetactionDifficulty>>
 				</div>
@@ -654,7 +654,7 @@
 		<<elseif $rightarmstate is "mouth_struggle">>
 			You clutch it with your right hand.
 		<</if>>
-		<<if $combatControls is "radio">><br><</if>>
+		<<if $options.combatControls is "radio">><br><</if>>
 	<<case "tentacle">>
 		<<set $_changetype to true>><<mouthActionInitTentacle>>
 	<<default>>
@@ -682,15 +682,15 @@
 			<</if>>
 			<<set $mouthaction to $mouthactiondefault>>
 			<<set _textColor to combatListColor('mouthaction', (Object.values(_mouthaction).includes($mouthaction) ? $mouthaction : Object.values(_mouthaction)[0]), "Struggle")>>
-			<<if $combatControls is "radio">> Mouth:<</if>>
+			<<if $options.combatControls is "radio">> Mouth:<</if>>
 			<<generateCombatActionOthers _mouthaction "mouthaction" _textColor $mouthaction "Struggle">>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="mouthactionDifficulty">
 					<<mouthactionDifficulty>>
 				</div>
 			<</if>>
 		<</if>>
-		<<if $combatControls is "radio">>
+		<<if $options.combatControls is "radio">>
 			<<handsActionsStruggleRadio "mouth">>
 		<</if>>
 		<<set $lastOptions.mouth to clone(_mouthOptions)>>
@@ -719,7 +719,7 @@
 	<<default>>
 		<<set $_changetype to true>><<penisActionInit>>
 	<</switch>>
-	<<if $_changetype isnot true and $combatControls is "radio">>
+	<<if $_changetype isnot true and $options.combatControls is "radio">>
 		<<handsActionsStruggleRadio penis>>
 	<</if>>
 <</if>>
@@ -742,7 +742,7 @@
 	<<default>>
 		<<set $_changetype to true>><<vaginaActionInit>>
 	<</switch>>
-	<<if $_changetype isnot true and $combatControls is "radio">>
+	<<if $_changetype isnot true and $options.combatControls is "radio">>
 		<<handsActionsStruggleRadio "vagina">>
 	<</if>>
 <</widget>>
@@ -768,7 +768,7 @@
 			<<set $_changetype to true>><<anusActionInit>>
 		<</switch>>
 	<</if>>
-	<<if $_changetype isnot true and $combatControls is "radio">>
+	<<if $_changetype isnot true and $options.combatControls is "radio">>
 		<<handsActionsStruggleRadio "anus">>
 	<</if>>
 <</widget>>
@@ -789,7 +789,7 @@
 	<<case "penis">>
 		<<set $_changetype to true>><<chestActionInit>>
 	<</switch>>
-	<<if $_changetype isnot true and $combatControls is "radio">>
+	<<if $_changetype isnot true and $options.combatControls is "radio">>
 		<<handsActionsStruggleRadio "chest">>
 	<</if>>
 <</widget>>
@@ -807,9 +807,9 @@
 <<combatstate>>
 <<carryblock>>
 
-<<if $trance lte 0 and $panicparalysis is 0 and $panicviolence is 0 and $combatControls isnot "radio_old">>
+<<if $trance lte 0 and $panicparalysis is 0 and $panicviolence is 0 and $options.combatControls isnot "radio_old">>
 	<<struggle_difficulty_set>>
-	<<if $combatControls is "radio">>
+	<<if $options.combatControls is "radio">>
 		<<set $leftaction to $leftactiondefault>>
 		<<set $rightaction to $rightactiondefault>>
 	<</if>>
@@ -817,7 +817,7 @@
 <</if>>
 
 <<if $trance lte 0 and $dissociation lte 1 and $panicparalysis is 0 and $panicviolence is 0
-and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $combatControls is "radio_old">>
+and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $options.combatControls is "radio_old">>
 	<<struggle_difficulty_set>>
 	<!-- arms bound set -->
 	<<if $leftarm is "bound" and $rightarm is "bound">>
diff --git a/game/base-combat/swarm-effects.twee b/game/base-combat/swarm-effects.twee
index e95dba6fc5..f34b31e5cb 100644
--- a/game/base-combat/swarm-effects.twee
+++ b/game/base-combat/swarm-effects.twee
@@ -5,7 +5,7 @@
 	<<getTargetList>>
 <</if>>
 <div id="listContainer">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<if $lefttarget is "self">>
 			<<leftActionInitSelf>>
 		<<else>>
@@ -13,7 +13,7 @@
 		<</if>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<if $righttarget is "self">>
 			<<rightActionInitSelf>>
 		<<else>>
@@ -21,12 +21,12 @@
 		<</if>>
 	</div>
 
-	<div id="feetaction" @class="$combatControls + 'Control'">
+	<div id="feetaction" @class="$options.combatControls + 'Control'">
 		<<feetActionInitSwarm>>
 	</div>
 
 	<<if ($mouthuse is 0 and !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined)))>>
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInit>>
 		</div>
 	<</if>>
@@ -50,7 +50,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -59,7 +59,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -69,7 +69,7 @@
 	<</if>>
 <<case "swarmgrappled">>
 	<<set _leftOptions to "unable">>
-	<span class="purple">The $swarm["type"] are constricting your left arm!</span><<if $combatControls is "radio">><br><</if>>
+	<span class="purple">The $swarm["type"] are constricting your left arm!</span><<if $options.combatControls is "radio">><br><</if>>
 <<case "bound">>
 	<<if $orgasmdown gte 1>>
 		<<set _leftOptions to "unable">>
@@ -83,7 +83,7 @@
 	<<else>>
 		<<set _leftOptions to "bound">>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is bound and helpless.</span>
-	<</if>><<if $combatControls is "radio">><br><</if>>
+	<</if>><<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set $_changetype to true>><<leftActionInitVore>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
@@ -106,7 +106,7 @@
 		<div class="extraMargin">
 			<<generateCombatActionOthers _leftaction "leftaction" _textColor $leftaction "Swarm">>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="leftactionDifficulty">
 				<<leftactionDifficulty>>
 			</div>
@@ -123,20 +123,20 @@
 <<set _leftaction to {}>>
 <<switch _leftOptions>>
 <<case "free">>
-	<<if $rightarm is "swarmgrappled" and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if $rightarm is "swarmgrappled" and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _leftaction["Free your right arm"] to "leftfree">>
 	<<elseif _swarmamounts.active[2] gte 1 and $lefttarget isnot "self">>
 		<<silently>><<swarmName>><</silently>>
 		<<set _leftaction[_swarmsteady + " one of the " + _swarmname] to "leftswarm">>
 	<</if>>
-	<<if _swarmamounts.genital[0] lte 0 and _swarmamounts.genital[1] lte 0 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _swarmamounts.genital[0] lte 0 and _swarmamounts.genital[1] lte 0 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<silently>><<genitals>><</silently>>
 		<<set _leftaction["Cover your "+ _text_output] to "frontcoverleft">>
 	<</if>>
-	<<if _swarmamounts.butt[0] lte 0 and _swarmamounts.butt[1] lte 0 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _swarmamounts.butt[0] lte 0 and _swarmamounts.butt[1] lte 0 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _leftaction["Cover your butt"] to "backcoverleft">>
 	<</if>>
-	<<if _swarmamounts.chest lte 0 and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _swarmamounts.chest lte 0 and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _leftaction["Cover your chest"] to "chestcoverleft">>
 	<</if>>
 	<<if $lefttarget isnot "self">>
@@ -158,7 +158,7 @@
 			<<set _leftaction["Clear the "+ $swarm["type"] + " off of your chest"] to "chestclearleft">>
 		<</if>>
 	<</if>>
-	<<if $water is 1 and $vorecreature is 0 and ($consensual isnot 1 or $gamemode is "soft") and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if $water is 1 and $vorecreature is 0 and ($consensual isnot 1 or $gamemode is "soft") and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _leftaction["Swim to safety"] to "swim">>
 	<</if>>
 	<<if $vorecreature is 0>>
@@ -198,7 +198,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -207,7 +207,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -217,7 +217,7 @@
 	<</if>>
 <<case "swarmgrappled">>
 	<<set _rightOptions to "unable">>
-	<span class="purple">The $swarm["type"] are constricting your right arm!</span><<if $combatControls is "radio">><br><</if>>
+	<span class="purple">The $swarm["type"] are constricting your right arm!</span><<if $options.combatControls is "radio">><br><</if>>
 <<case "bound">>
 	<<if $orgasmdown gte 1>>
 		<<set _rightOptions to "unable">>
@@ -231,7 +231,7 @@
 	<<else>>
 		<<set _rightOptions to "bound">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is bound and helpless.</span>
-	<</if>><<if $combatControls is "radio">><br><</if>>
+	<</if>><<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set $_changetype to true>><<rightActionInitVore>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
@@ -254,7 +254,7 @@
 		<div class="extraMargin">
 			<<generateCombatActionOthers _rightaction "rightaction" _textColor $rightaction "Swarm">>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="rightactionDifficulty">
 				<<rightactionDifficulty>>
 			</div>
@@ -271,20 +271,20 @@
 <<set _rightaction to {}>>
 <<switch _rightOptions>>
 <<case "free">>
-	<<if $leftarm is "swarmgrappled" and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if $leftarm is "swarmgrappled" and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _rightaction["Free your left arm"] to "rightfree">>
 	<<elseif _swarmamounts.active[2] gte 1 and $righttarget isnot "self">>
 		<<silently>><<swarmName>><</silently>>
 		<<set _rightaction[_swarmsteady + " one of the " + _swarmname] to "rightswarm">>
 	<</if>>
-	<<if _swarmamounts.genital[0] lte 0 and _swarmamounts.genital[1] lte 0 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _swarmamounts.genital[0] lte 0 and _swarmamounts.genital[1] lte 0 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<silently>><<genitals>><</silently>>
 		<<set _rightaction["Cover your "+ _text_output] to "frontcoverright">>
 	<</if>>
-	<<if _swarmamounts.butt[0] lte 0 and _swarmamounts.butt[1] lte 0 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _swarmamounts.butt[0] lte 0 and _swarmamounts.butt[1] lte 0 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _rightaction["Cover your butt"] to "backcoverright">>
 	<</if>>
-	<<if _swarmamounts.chest lte 0 and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if _swarmamounts.chest lte 0 and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _rightaction["Cover your chest"] to "chestcoverright">>
 	<</if>>
 	<<if $righttarget isnot "self">>
@@ -306,7 +306,7 @@
 			<<set _rightaction["Clear the "+ $swarm["type"] + " off of your chest"] to "chestclearright">>
 		<</if>>
 	<</if>>
-	<<if $water is 1 and $vorecreature is 0 and ($consensual isnot 1 or $gamemode is "soft") and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if $water is 1 and $vorecreature is 0 and ($consensual isnot 1 or $gamemode is "soft") and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _rightaction["Swim to safety"] to "swim">>
 	<</if>>
 	<<if $vorecreature is 0>>
@@ -338,7 +338,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistall["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			<<if ($leftleg is "grappled" and $rightleg is "grappled") or ($leftleg is "bound" and $rightleg is "bound")>>
 			<<else>>
 				Target: <span onchange="actionsreplace('feet')">
@@ -365,7 +365,7 @@
 			<<set _feetOptions to "free">>
 			<span @class="($lastOptions.feet isnot _feetOptions or _feetGold is true ?'gold':'')">Your feet are free.</span>
 		<</if>>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
 			Target: <span onchange="actionsreplace('feet')">
 			<<listbox "$feettarget" autoselect>>
 				<<optionsfrom _targetlistall>>
@@ -396,7 +396,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionOthers _feetaction "feetaction" _textColor $feetaction "Swarm">>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="feetactionDifficulty">
 					<<feetactionDifficulty>>
 				</div>
@@ -421,7 +421,7 @@
 	<<set _feetaction[_swarmsteady + " one of the " + _swarmname] to "feetswarm">>
 <</if>>
 <<if _feetOptions is "free">>
-	<<if $water is 1 and $vorecreature is 0 and currentSkillValue('swimmingskill') gt 700 and $consensual isnot 1 and ($feettarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+	<<if $water is 1 and $vorecreature is 0 and currentSkillValue('swimmingskill') gt 700 and $consensual isnot 1 and ($feettarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 		<<set _feetaction["Swim to safety"] to "swim">>
 	<</if>>
 <</if>>
@@ -437,7 +437,7 @@
 	<<set $front to 0>>
 	<<set $back to 0>>
 	<<if $vorecreature is 0>>
-		<<if $images is 1 and $combatimages is 1>>
+		<<if $options.images is 1 and $options.combatImages is 1>>
 			<<if $swarm.amount.active>>
 				<<set _swarmactive to $swarm.amount.active[0]>>
 			<<else>>
@@ -457,12 +457,12 @@
 	<<combatstate>>
 	<<carryblock>>
 
-	<<if $trance lte 0 and $panicparalysis is 0 and $panicviolence is 0 and $combatControls isnot "disabled">>
+	<<if $trance lte 0 and $panicparalysis is 0 and $panicviolence is 0 and $options.combatControls isnot "disabled">>
 		<<set _swarmsteady to $swarm["steady"].toUpperFirst()>>
 		<<set _swarmamounts to $swarm.amount>>
 		<<generateActionsSwarm>>
 	<</if>>
-	<<if $trance lte 0 and $dissociation lte 1 and $panicparalysis is 0 and $panicviolence is 0 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $combatControls is "disabled">>
+	<<if $trance lte 0 and $dissociation lte 1 and $panicparalysis is 0 and $panicviolence is 0 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $options.combatControls is "disabled">>
 		<<set _swarmsteady to $swarm["steady"].toUpperFirst()>>
 		<<set _swarmamounts to $swarm.amount>>
 
diff --git a/game/base-combat/tentacles/abomination.twee b/game/base-combat/tentacles/abomination.twee
index 1d029e55dc..9d6bce3888 100644
--- a/game/base-combat/tentacles/abomination.twee
+++ b/game/base-combat/tentacles/abomination.twee
@@ -78,7 +78,7 @@
 	<</if>>
 <</if>>
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<if $position isnot "stalk">>
 		<<timed 100ms>>
 			<<combatimg>>
@@ -114,7 +114,7 @@
 
 <<if $trance lte 0 and $panicparalysis is 0 and ($panicviolence is 0 or $position is "stalk")>>
 	<<if $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined) and $dissociation lte 1>>
-		<<if $images is 1 and $combatimages is 1 and $consensual is 1 and $position_lock isnot 1>>
+		<<if $options.images is 1 and $options.combatImages is 1 and $consensual is 1 and $position_lock isnot 1>>
 			<<if $position is "doggy">>
 				| <label>Roll over <<radiobutton "$bodyaction" "missionary">></label>
 			<<elseif $position is "missionary">>
@@ -127,7 +127,7 @@
 		<</if>>
 	<</if>>
 
-	<<if $combatControls isnot "disabled">>
+	<<if $options.combatControls isnot "disabled">>
 		<<generateActionsAbomination>>
 	<</if>>
 	<br>
@@ -167,7 +167,7 @@
 	<<getTargetList>>
 <</if>>
 <div id="listContainer">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<if $lefttarget is "self">>
 			<<leftActionInitSelf>>
 		<<elseif $lefttarget is "tentacles" and Object.values(_targetlistarms).includes("tentacles")>>
@@ -177,7 +177,7 @@
 		<</if>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<if $righttarget is "self">>
 			<<rightActionInitSelf>>
 		<<elseif $righttarget is "tentacles" and Object.values(_targetlistarms).includes("tentacles")>>
@@ -187,7 +187,7 @@
 		<</if>>
 	</div>
 
-	<div id="feetaction" @class="$combatControls + 'Control'">
+	<div id="feetaction" @class="$options.combatControls + 'Control'">
 		<<if $feettarget is "self">>
 			<<feetActionInitSelf>>
 		<<elseif $feettarget is "tentacles" and Object.values(_targetlistall).includes("tentacles")>>
@@ -197,7 +197,7 @@
 		<</if>>
 	</div>
 
-	<div id="mouthaction" @class="$combatControls + 'Control'">
+	<div id="mouthaction" @class="$options.combatControls + 'Control'">
 		<<if $mouthtarget is "tentacles" and Object.values(_targetlistall).includes("tentacles")>>
 			<<mouthActionInitTentacle>>
 		<<else>>
@@ -206,7 +206,7 @@
 	</div>
 
 	<<if $player.penisExist>>
-		<div id="penisaction" @class="$combatControls + 'Control'">
+		<div id="penisaction" @class="$options.combatControls + 'Control'">
 			<<if $penistarget is "tentacles" and Object.values(_targetlistall).includes("tentacles")>>
 				<<penisActionInitTentacle>>
 			<<else>>
@@ -216,7 +216,7 @@
 	<</if>>
 
 	<<if $player.vaginaExist>>
-		<div id="vaginaaction" @class="$combatControls + 'Control'">
+		<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 			<<if $vaginatarget is "tentacles" and Object.values(_targetlistall).includes("tentacles")>>
 				<<vaginaActionInitTentacle>>
 			<<else>>
@@ -225,7 +225,7 @@
 		</div>
 	<</if>>
 
-	<div id="anusaction" @class="$combatControls + 'Control'">
+	<div id="anusaction" @class="$options.combatControls + 'Control'">
 		<<if $anustarget is "tentacles" and Object.values(_targetlistall).includes("tentacles")>>
 			<<anusActionInitTentacle>>
 		<<else>>
@@ -234,17 +234,17 @@
 	</div>
 
 	<<if $chestuse is "tentaclerub">>
-		<div id="chestaction" @class="$combatControls + 'Control'">
+		<div id="chestaction" @class="$options.combatControls + 'Control'">
 			<<chestActionInitTentacle>>
 		</div>
 	<<elseif $chestuse is "penis">>
-		<div id="chestaction" @class="$combatControls + 'Control'">
+		<div id="chestaction" @class="$options.combatControls + 'Control'">
 			<<chestActionInit>>
 		</div>
 	<</if>>
 
 	<<if $thighuse isnot 0>>
-		<div id="thighaction" @class="$combatControls + 'Control'">
+		<div id="thighaction" @class="$options.combatControls + 'Control'">
 			<<thighActionInit>>
 		</div>
 	<</if>>
diff --git a/game/base-combat/tentacles/tentacle-images.twee b/game/base-combat/tentacles/tentacle-images.twee
index 133a27cbc7..6064d385cf 100644
--- a/game/base-combat/tentacles/tentacle-images.twee
+++ b/game/base-combat/tentacles/tentacle-images.twee
@@ -2,7 +2,7 @@
 
 <<widget "tentacleimg">>
 	<<set _filters to $skinColor.current>>
-	<<set _img to setup.tanImg.doggy[$skinColor.tanImgEnabled]>>
+	<<set _img to setup.tanImg.doggy[($options.tanImgEnabled ? "t" : "f")]>>
 	<<getTentacleColour>>
 
 	<<if $vaginastate is "tentacleentrance">>
@@ -84,7 +84,7 @@
 
 <<widget "tentacleimgmiss">>
 	<<set _filters to $skinColor.current>>
-	<<set _img to setup.tanImg.missionary[$skinColor.tanImgEnabled]>>
+	<<set _img to setup.tanImg.missionary[($options.tanImgEnabled ? "t" : "f")]>>
 	<<getTentacleColour>>
 	<<if $vaginastate is "tentacleentrance">>
 		<img @class="'layer-shadowman '+_tentacleColour+' anim-doggy-4f-'+_animspeed" src="img/sex/missionary/tentacles/tentaclevaginalentrance.png">
diff --git a/game/base-combat/tentacles/tentacleActionsGeneration.twee b/game/base-combat/tentacles/tentacleActionsGeneration.twee
index 55566b0c5c..269a5344b9 100644
--- a/game/base-combat/tentacles/tentacleActionsGeneration.twee
+++ b/game/base-combat/tentacles/tentacleActionsGeneration.twee
@@ -2,7 +2,7 @@
 
 /*Sends the required variables to the chosen display type*/
 <<widget "generateCombatActionTentacle">>
-<<switch $combatControls>>
+<<switch $options.combatControls>>
 	<<case "radio">>
 		<<generateCombatActionTentacleRadio _args[0] _args[1] _args[3]>>
 	<<case "lists" "limitedLists">>
@@ -48,44 +48,44 @@
 <<set _the to ($abomination is 1 ? "<<his>>" : "the")>>
 
 <div id="listContainer">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<leftActionInitTentacle>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<rightActionInitTentacle>>
 	</div>
 
-	<div id="feetaction" @class="$combatControls + 'Control'">
+	<div id="feetaction" @class="$options.combatControls + 'Control'">
 		<<feetActionInitTentacle>>
 	</div>
 
 	<<if $mouthstate isnot 0 or !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined))>>
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $penisstate isnot 0 and $player.penisExist>>
-		<div id="penisaction" @class="$combatControls + 'Control'">
+		<div id="penisaction" @class="$options.combatControls + 'Control'">
 			<<penisActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $vaginastate isnot 0 and $player.vaginaExist>>
-		<div id="vaginaaction" @class="$combatControls + 'Control'">
+		<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 			<<vaginaActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $anusstate isnot 0>>
-		<div id="anusaction" @class="$combatControls + 'Control'">
+		<div id="anusaction" @class="$options.combatControls + 'Control'">
 			<<anusActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $chestuse isnot 0 and $chestuse isnot "squeezed">>
-		<div id="chestaction" @class="$combatControls + 'Control'">
+		<div id="chestaction" @class="$options.combatControls + 'Control'">
 			<<chestActionInitTentacle>>
 		</div>
 	<</if>>
@@ -106,7 +106,7 @@
 		<<set _leftOptions to "unreal">>
 		<span class="pink">Your left arm is free, but doesn't feel real.</span>
 	<<else>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -115,7 +115,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -224,7 +224,7 @@
 		<<set $leftaction to $leftactiondefault>>
 		<<set _textColor to combatListColor('leftaction', (Object.values(_leftaction).includes($leftaction) ? $leftaction : Object.values(_leftaction)[0]), "Tentacle")>>
 		<div class="extraMargin">
-			<<if $combatControls isnot "radio" and _leftOptions is "free">>
+			<<if $options.combatControls isnot "radio" and _leftOptions is "free">>
 				<<set _reducedWidths to true>>
 			<<else>>
 				<<set _reducedWidths to false>>
@@ -236,7 +236,7 @@
 				<<leftactionBoundBanish>>
 			<</if>>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="leftactionDifficulty">
 				<<leftactionDifficultyTentacle>>
 			</div>
@@ -247,7 +247,7 @@
 <</widget>>
 
 <<widget "leftactionSetupTentacle">>
-<<if $combatControls is "radio">>
+<<if $options.combatControls is "radio">>
 	<br><br>
 	<<set _first to true>>
 	<<if $regrab>>
@@ -298,7 +298,7 @@
 <</widget>>
 
 <<widget "leftactionBoundBanish">>
-<<if $combatControls is "radio">>
+<<if $options.combatControls is "radio">>
 	<br>
 	<label>
 		<<print '<<radiobutton "$leftactionTarget" "'+_banishTarget.id+'">>'>>
@@ -407,7 +407,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -416,7 +416,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -528,7 +528,7 @@
 		<<set $rightaction to $rightactiondefault>>
 		<<set _textColor to combatListColor('rightaction', (Object.values(_rightaction).includes($rightaction) ? $rightaction : Object.values(_rightaction)[0]), "Tentacle")>>
 		<div class="extraMargin">
-			<<if $combatControls isnot "radio" and _rightOptions is "free">>
+			<<if $options.combatControls isnot "radio" and _rightOptions is "free">>
 				<<set _reducedWidths to true>>
 			<<else>>
 				<<set _reducedWidths to false>>
@@ -540,7 +540,7 @@
 				<<rightactionBoundBanish>>
 			<</if>>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="rightactionDifficulty">
 				<<rightactionDifficultyTentacle>>
 			</div>
@@ -551,7 +551,7 @@
 <</widget>>
 
 <<widget "rightactionSetupTentacle">>
-<<if $combatControls is "radio">>
+<<if $options.combatControls is "radio">>
 	<br><br>
 	<<set _first to true>>
 	<<if $regrab>>
@@ -602,7 +602,7 @@
 <</widget>>
 
 <<widget "rightactionBoundBanish">>
-<<if $combatControls is "radio">>
+<<if $options.combatControls is "radio">>
 	<br>
 	<label>
 		<<print '<<radiobutton "$rightactionTarget" "'+_banishTarget.id+'">>'>>
@@ -706,7 +706,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistall["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			<<if !(($leftleg is "grappled" and $rightleg is "grappled") or ($leftleg is "bound" and $rightleg is "bound"))>>
 				Target: <span onchange="actionsreplace('feet')">
 				<<listbox "$feettarget" autoselect>>
@@ -740,7 +740,7 @@
 				<</if>>
 			<</for>>
 		<</if>>
-		<<if $combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1 and _feetOptions.toLowerCase().includes("free")>><br>
 			Target: <span onchange="actionsreplace('feet')">
 			<<listbox "$feettarget" autoselect>>
 				<<optionsfrom _targetlistall>>
@@ -796,7 +796,7 @@
 			<<set _textColor to combatListColor('feetaction', (Object.values(_feetaction).includes($feetaction) ? $feetaction : Object.values(_feetaction)[0]), "Tentacle")>>
 			<div class="extraMargin">
 				<<set _availableContext to ["free","leftFree","rightFree"]>>
-				<<if $combatControls isnot "radio" and _availableContext.includes(_feetOptions)>>
+				<<if $options.combatControls isnot "radio" and _availableContext.includes(_feetOptions)>>
 					<<set _reducedWidths to true>>
 				<<else>>
 					<<set _reducedWidths to false>>
@@ -806,7 +806,7 @@
 					<<feetactionSetupTentacle>>
 				<</if>>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="feetactionDifficulty">
 					<<feetactionDifficultyTentacle>>
 				</div>
@@ -822,7 +822,7 @@
 <</widget>>
 
 <<widget "feetactionSetupTentacle">>
-<<if $combatControls is "radio">>
+<<if $options.combatControls is "radio">>
 	<br><br>
 	<<set _first to true>>
 	<<if $regrab>>
@@ -1009,7 +1009,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionTentacle _mouthaction "mouthaction" _textColor $mouthaction>>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="mouthactionDifficulty">
 					<<mouthactionDifficultyTentacle>>
 				</div>
@@ -1139,7 +1139,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionTentacle _penisaction "penisaction" _textColor $penisaction>>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="penisactionDifficulty">
 					<<penisactionDifficultyTentacle>>
 				</div>
@@ -1263,7 +1263,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionTentacle _vaginaaction "vaginaaction" _textColor $vaginaaction>>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="vaginaactionDifficulty">
 					<<vaginaactionDifficultyTentacle>>
 				</div>
@@ -1391,7 +1391,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionTentacle _anusaction "anusaction" _textColor $anusaction>>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="anusactionDifficulty">
 					<<anusactionDifficultyTentacle>>
 				</div>
@@ -1467,7 +1467,7 @@
 			<div class="extraMargin">
 				<<generateCombatActionTentacle _chestaction "chestaction" _textColor $chestaction>>
 			</div>
-			<<if $combatControls.includes("ists")>>
+			<<if $options.combatControls.includes("ists")>>
 				<div id="chestactionDifficulty">
 					<<chestactionDifficultyTentacle>>
 				</div>
@@ -1506,7 +1506,7 @@
 <</widget>>
 
 <<widget "actionsvorentacles">>
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<timed 100ms>>
 		<<combatimg>>
 		<br>
@@ -1532,7 +1532,7 @@
 	<<getTargetList>>
 <</if>>
 <div id="listContainer">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<if $lefttarget is "vore" or $tentacles.active is 0>>
 			<<leftActionInitVore>>
 		<<else>>
@@ -1540,7 +1540,7 @@
 		<</if>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<if $righttarget is "vore" or $tentacles.active is 0>>
 			<<rightActionInitVore>>
 		<<else>>
@@ -1548,36 +1548,36 @@
 		<</if>>
 	</div>
 
-	<div id="feetaction" @class="$combatControls + 'Control'">
+	<div id="feetaction" @class="$options.combatControls + 'Control'">
 		<<feetActionInitTentacle>>
 	</div>
 
 	<<if $mouthstate isnot 0 or !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined))>>
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $penisstate isnot 0 and $player.penisExist>>
-		<div id="penisaction" @class="$combatControls + 'Control'">
+		<div id="penisaction" @class="$options.combatControls + 'Control'">
 			<<penisActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $vaginastate isnot 0 and $player.vaginaExist>>
-		<div id="vaginaaction" @class="$combatControls + 'Control'">
+		<div id="vaginaaction" @class="$options.combatControls + 'Control'">
 			<<vaginaActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $anusstate isnot 0>>
-		<div id="anusaction" @class="$combatControls + 'Control'">
+		<div id="anusaction" @class="$options.combatControls + 'Control'">
 			<<anusActionInitTentacle>>
 		</div>
 	<</if>>
 
 	<<if $chestuse isnot 0 and $chestuse isnot "squeezed">>
-		<div id="chestaction" @class="$combatControls + 'Control'">
+		<div id="chestaction" @class="$options.combatControls + 'Control'">
 			<<chestActionInitTentacle>>
 		</div>
 	<</if>>
diff --git a/game/base-combat/tentacles/tentacles.twee b/game/base-combat/tentacles/tentacles.twee
index 811a86b3dc..17eaace3a6 100644
--- a/game/base-combat/tentacles/tentacles.twee
+++ b/game/base-combat/tentacles/tentacles.twee
@@ -207,7 +207,7 @@
 <div @class="($debugLines ? 'debugLines-actionstentacles' : '')">
 <<set $enemyarousal to $arousal>>
 <<if $vorecreature is 0 and _swarmcreature is undefined>>
-	<<if $images is 1 and $combatimages is 1>>
+	<<if $options.images is 1 and $options.combatImages is 1>>
 		<<timed 100ms>>
 			<br>
 			<<combatimg>>
diff --git a/game/base-combat/vore.twee b/game/base-combat/vore.twee
index 5d32ae6ff1..5e67f71e7f 100644
--- a/game/base-combat/vore.twee
+++ b/game/base-combat/vore.twee
@@ -5,16 +5,16 @@
 	<<getTargetList>>
 <</if>>
 <div id="listContainer">
-	<div id="leftaction" @class="$combatControls + 'Control'">
+	<div id="leftaction" @class="$options.combatControls + 'Control'">
 		<<leftActionInitVore>>
 	</div>
 
-	<div id="rightaction" @class="$combatControls + 'Control'">
+	<div id="rightaction" @class="$options.combatControls + 'Control'">
 		<<rightActionInitVore>>
 	</div>
 
 	<<if ($mouthuse is 0 and !($dissociation lte 1 and $orgasmdown lte 0 and ($pain lt 100 or $willpowerpain is undefined)))>>
-		<div id="mouthaction" @class="$combatControls + 'Control'">
+		<div id="mouthaction" @class="$options.combatControls + 'Control'">
 			<<mouthActionInit>>
 		</div>
 	<</if>>
@@ -39,7 +39,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -48,7 +48,7 @@
 		<</if>>
 		<<set _leftOptions to "free">>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('left')">
 			<<listbox "$lefttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -66,10 +66,10 @@
 		<span class="pink">Your left arm lies limp in its bonds.</span>
 	<<else>>
 		<span @class="($lastOptions.left isnot _leftOptions ?'gold':'')">Your left arm is bound.</span>
-	<</if>><<if $combatControls is "radio">><br><</if>>
+	<</if>><<if $options.combatControls is "radio">><br><</if>>
 <<case "trapped">>
 	<<set _leftOptions to "trapped">>
-	<span @class="($lastOptions.left isnot _leftOptions ?'gold':'purple')">Your left arm is trapped by the $vorecreature.</span><<if $combatControls is "radio">><br><</if>>
+	<span @class="($lastOptions.left isnot _leftOptions ?'gold':'purple')">Your left arm is trapped by the $vorecreature.</span><<if $options.combatControls is "radio">><br><</if>>
 <<case "grappled" "penis" "othervagina" "vagina" "coverpenis" "anus" "behind">>
 	<<set $_changetype to true>><<leftActionInit>>
 <<case "struggle">>
@@ -92,7 +92,7 @@
 		<div class="extraMargin">
 			<<generateCombatActionOthers _leftaction "leftaction" _textColor $leftaction "Vore">>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="leftactionDifficulty">
 				<<leftactionDifficulty>>
 			</div>
@@ -149,7 +149,7 @@
 		<<if _targetYourself is true and _targetnumber gt 1>>
 			<<set _targetlistarms["Yourself"] to "self">>
 		<</if>>
-		<<if $combatControls isnot "radio" and _targetnumber gt 1>>
+		<<if $options.combatControls isnot "radio" and _targetnumber gt 1>>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -158,7 +158,7 @@
 		<</if>>
 		<<set _rightOptions to "free">>
 		<span @class="($lastOptions.right isnot _rightOptions ?'gold':'')">Your right arm is free.</span>
-		<<if $combatControls is "radio" and _targetnumber gt 1>><br>
+		<<if $options.combatControls is "radio" and _targetnumber gt 1>><br>
 			Target: <span onchange="actionsreplace('right')">
 			<<listbox "$righttarget" autoselect>>
 				<<optionsfrom _targetlistarms>>
@@ -202,7 +202,7 @@
 		<div class="extraMargin">
 			<<generateCombatActionOthers _rightaction "rightaction" _textColor $rightaction "Vore">>
 		</div>
-		<<if $combatControls.includes("ists")>>
+		<<if $options.combatControls.includes("ists")>>
 			<div id="rightactionDifficulty">
 				<<rightactionDifficulty>>
 			</div>
@@ -643,7 +643,7 @@
 <</widget>>
 :: Widgets Vore Actions [widget]
 <<widget "voreactions">>
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<timed 100ms>>
 		<<combatimg>>
 		<br>
diff --git a/game/base-combat/widgets.twee b/game/base-combat/widgets.twee
index a1ea781c20..cdf0d8d08d 100644
--- a/game/base-combat/widgets.twee
+++ b/game/base-combat/widgets.twee
@@ -434,7 +434,7 @@
 		<<set $_hand to _args[0]>>
 		<<set $_items to window.listUniqueCarriedSextoys()>>
 
-		<<if $_hand is "left" and ($lefttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+		<<if $_hand is "left" and ($lefttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 			<<if $_items.length gt 0>>
 				<<set _itemsLeft to {}>>
 
@@ -449,7 +449,7 @@
 			<</if>>
 		<</if>>
 
-		<<if $_hand is "right" and ($righttarget is "self" or $targetYourself is false or _targetnumber is 1)>>
+		<<if $_hand is "right" and ($righttarget is "self" or $options.targetYourself is false or _targetnumber is 1)>>
 			<<if $_items>>
 				<<set _itemsRight to {}>>
 
diff --git a/game/base-debug/clothesTesting.twee b/game/base-debug/clothesTesting.twee
index a8f56c98d0..bf50c40c0e 100644
--- a/game/base-debug/clothesTesting.twee
+++ b/game/base-debug/clothesTesting.twee
@@ -1,6 +1,6 @@
 :: Clothes Testing [exitCheckBypass]
 <h3>Character Viewer</h3>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<if $debugClothesEquipped is undefined>>
 		<<set $debugClothesEquipped to {
 			head:0,
@@ -122,7 +122,7 @@
 <<link [[Return|$lastPassage]]>>
 	<<unset $lastPassage>>
 	<<removeclass "#passages" "debugPassages">>
-	<<set $skinColor.tanImgEnabled to clone($gameTanImgSetting)>>
+	<<set $options.tanImgEnabled to clone($gameTanImgSetting)>>
 	<<unset $gameTanImgSetting>>
 	<<tanned 0 "ignoreCoverage">>
 <</link>>
@@ -130,8 +130,8 @@
 :: clothesTestingImageGenerate [widget]
 <<widget "clothesTestingImageUpdate">>
 <<set $debugSkinColor.style to {
-	body:skinColor($skinColor.tanImgEnabled, $debugSkinColor.range,setup.skinColor[$debugSkinColor.type]),
-	mouth:skinColor($skinColor.tanImgEnabled, $debugSkinColor.range,setup.skinColor[$debugSkinColor.type])
+	body:skinColor($options.tanImgEnabled, $debugSkinColor.range,setup.skinColor[$debugSkinColor.type]),
+	mouth:skinColor($options.tanImgEnabled, $debugSkinColor.range,setup.skinColor[$debugSkinColor.type])
 }>>
 <<replace #images>>
 	<<clothesTestingImageGenerateAll>>
@@ -175,7 +175,7 @@
 <</widget>>
 
 <<widget "clothesTestingImageGenerate">>
-<<set _img to setup.tanImg.sidebar[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.sidebar[($options.tanImgEnabled ? "t" : "f")]>>
 <<set _filters to $debugSkinColor.style>>
 <div @class="`debug-images hideImageOverflow ` + debugColourContainerClasses(_args[0])">
 	<img class="layer-base anim-idle-2f" @src="_img.basenoarms" @style="'filter: '+_filters.body">
@@ -438,8 +438,8 @@
 <br><br>
 
 <span class="gold">Skin Colour</span>
-<label>Enable <<print '<<radiobutton "$skinColor.tanImgEnabled" "t" ' + ($skinColor.tanImgEnabled is "t" ? "checked" : "") + '>>'>></label> |
-<label>Disable <<print '<<radiobutton "$skinColor.tanImgEnabled" "f" ' + ($skinColor.tanImgEnabled is "f" ? "checked" : "") + '>>'>></label> |
+<label>Enable <<print '<<radiobutton "$options.tanImgEnabled" true ' + ($options.tanImgEnabled ? "checked" : "") + '>>'>></label> |
+<label>Disable <<print '<<radiobutton "$options.tanImgEnabled" false' + (!$options.tanImgEnabled ? "checked" : "") + '>>'>></label> |
 <br>
 Skin colour:
 <br>
diff --git a/game/base-debug/test demon.twee b/game/base-debug/test demon.twee
index 485ef4df3b..27291aa67a 100644
--- a/game/base-debug/test demon.twee	
+++ b/game/base-debug/test demon.twee	
@@ -102,7 +102,7 @@ You consider your options...
 You pass out from exertion, completely spent, <span class="blue">while the <<person>> roars and continues to work away on your limp body.</span>
 <br><br>
 
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<combatimg>>
 	<br>
 <</if>>
diff --git a/game/base-debug/testing-skinColor.twee b/game/base-debug/testing-skinColor.twee
index ea3ad65318..305a66098c 100644
--- a/game/base-debug/testing-skinColor.twee
+++ b/game/base-debug/testing-skinColor.twee
@@ -6,57 +6,57 @@
 Skin Range:
 <<numberslider "$skinColor.range" $skinColor.range 0 100 1>>
 <<link "test">>
-	<<set $skinColor.current.test to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.test to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #skinColorDiv>><<testing-skinColorWidget>><</replace>>
 <</link>> |
 <<link "All">>
-	<<set $skinColor.current.body to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.mouth to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.breasts to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.penis to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.swimshorts to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.swimsuitTop to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.swimsuitBottom to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.bikiniTop to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.bikiniBottom to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.tshirt to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.body to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.mouth to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.breasts to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.penis to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.swimshorts to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.swimsuitTop to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.swimsuitBottom to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.bikiniTop to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.bikiniBottom to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.tshirt to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "body">>
-	<<set $skinColor.current.body to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
-	<<set $skinColor.current.mouth to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.body to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.mouth to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "breasts">>
-	<<set $skinColor.current.breasts to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.breasts to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "penis">>
-	<<set $skinColor.current.penis to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.penis to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "swimshorts">>
-	<<set $skinColor.current.swimshorts to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.swimshorts to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "swimsuitTop">>
-	<<set $skinColor.current.swimsuitTop to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.swimsuitTop to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "swimsuitBottom">>
-	<<set $skinColor.current.swimsuitBottom to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.swimsuitBottom to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "bikiniTop">>
-	<<set $skinColor.current.bikiniTop to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.bikiniTop to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "bikiniBottom">>
-	<<set $skinColor.current.bikiniBottom to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.bikiniBottom to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>> |
 <<link "tshirt">>
-	<<set $skinColor.current.tshirt to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+	<<set $skinColor.current.tshirt to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 	<<replace #imageHolder>><<img>><</replace>>
 <</link>>
 <br><br>
diff --git a/game/base-system/caption.twee b/game/base-system/caption.twee
index e22cc44b6e..c3fee2381e 100644
--- a/game/base-system/caption.twee
+++ b/game/base-system/caption.twee
@@ -9,7 +9,7 @@
 	<<if $gamemode is "soft">>
 		<<set $pain to 0>>
 	<</if>>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<addclass body has-images>>
 		<<removeclass body no-images>>
 		<div id="sidebar-img-container">
@@ -23,13 +23,13 @@
 	<div id="storyCaptionDiv" @class="($extendedStats ? 'statsExtended' : '')">
 
 	<div id="debugWindow"></div>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<div id="stats" onclick="extendStats()">
 			<<statsCaption>>
 		</div>
 	<</if>>
 	<div id="storyCaptionContent">
-		<<if $numpad is true>>
+		<<if $options.numpad is true>>
 			<style>
 				.mob-btn-group>div{
 				padding: 10px;background-color: rgb(34, 34, 34);color: #fff;border: 1px solid rgb(68, 68, 68);border-radius: 5px 0 0;
@@ -53,7 +53,7 @@
 		<</if>>
 		<<if $endeventerror isnot undefined>>
 			<<if $debugdisable is "f">>
-				<<if $images is 1>><img class="layer-sexmouth" src="img/ui/sym_awareness.png"><</if>><span class="red"><<print StartConfig.version>> Error: An NPC generated on the "$endeventerror" passage broke free. Please inform Vrelnir. <<if $cheatdisable is "f">>Disregard this if you've just used a cheat.<</if>></span>
+				<<if $options.images is 1>><img class="layer-sexmouth" src="img/ui/sym_awareness.png"><</if>><span class="red"><<print StartConfig.version>> Error: An NPC generated on the "$endeventerror" passage broke free. Please inform Vrelnir. <<if $cheatdisable is "f">>Disregard this if you've just used a cheat.<</if>></span>
 				<br><br>
 			<</if>>
 			<<unset $endeventerror>>
@@ -84,7 +84,7 @@
 			<<set $lessonmissedtext to 0>>
 			<br>
 		<</if>>
-		<<if $images is 0>>
+		<<if $options.images is 0>>
 			<div id="money-noimg">
 				<<statsMoneyNoImg>>
 			</div>
@@ -209,13 +209,13 @@
 		</div>
 		<br>
 		<<if $passage isnot "Start" and $passage isnot "Start2">>
-			<<if $sidebarTime is "top">>
+			<<if $options.sidebarTime is "top">>
 				<<append #mobileStats>><<mobileStatsTime>><</append>>
 			<</if>>
-			<<if $sidebarStats isnot "Disabled">>
+			<<if $options.sidebarStats isnot "disabled">>
 				<<append #mobileStats>><<mobileStats>><</append>>
 			<</if>>
-			<<if $sidebarTime is "bottom">>
+			<<if $options.sidebarTime is "bottom">>
 				<<append #mobileStats>><<mobileStatsTime>><</append>>
 			<</if>>
 		<</if>>
@@ -225,64 +225,70 @@
 			<br><br>
 		<</if>>
 
-		<<button CHARACTERISTICS>>
-			<<overlayReplace "characteristics">>
-		<</button>>
-		<<button SOCIAL>>
-			<<overlayReplace "social">>
-		<</button>>
-		<div class="sidebarButtonSplit">
-			<<button TRAITS>>
-				<<overlayReplace "traits">>
-			<</button>>
-			<<button JOURNAL>>
-				<<overlayReplace "journal">>
-			<</button>>
-		</div>
-		<div class="sidebarButtonSplit">
-			<<button STATS>>
-				<<overlayReplace "statistics">>
+		<<script>>
+			T.buttons = new window.Tab("overlayButtons", "macro-button-selected");
+		<</script>>
+
+		<div id="overlayButtons">
+			<<button CHARACTERISTICS>>
+				<<overlayReplace "characteristics">>
 			<</button>>
-			<<button FEATS>>
-				<<overlayReplace "gameFeats">>
+			<<button SOCIAL>>
+				<<overlayReplace "social">>
 			<</button>>
-		</div>
-		<br>
-		<div class="sidebarButtonSplit">
-			<<if $dancing is 0 and $combat is 0 and $passage isnot "Start2" and $cheatdisable is "f" or $debug is 1>>
-				<<button CHEATS>>
-					<<overlayReplace "cheats">>
+			<div class="sidebarButtonSplit">
+				<<button TRAITS>>
+					<<overlayReplace "traits">>
 				<</button>>
+				<<button JOURNAL>>
+					<<overlayReplace "journal">>
+				<</button>>
+			</div>
+			<div class="sidebarButtonSplit">
+				<<button STATS>>
+					<<overlayReplace "statistics">>
+				<</button>>
+				<<button FEATS>>
+					<<overlayReplace "gameFeats">>
+				<</button>>
+			</div>
+			<br>
+			<div class="sidebarButtonSplit">
+				<<if $dancing is 0 and $combat is 0 and $passage isnot "Start2" and $cheatdisable is "f" or $debug is 1>>
+					<<button CHEATS>>
+						<<overlayReplace "cheats">>
+					<</button>>
+				<</if>>
+				<<if $debug is 1>>
+					<<debug>>
+				<</if>>
+			</div>
+			<!-- Event debug button - Shows an overlay stored in debug-events.twee. -->
+			<<if $event isnot undefined and $debugdisable is "f">>
+				<<set _temp to "<span class='yellow'>SHOW EVENT INFO</span>">>
+				<<if EventSystem.Get(0).area[0] is $passage>>
+					<<set _eventalertmajorarea to false>>
+					<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
+				<<elseif setup.majorAreas.includes($passage)>>
+					<<set _eventalertmajorarea to true>>
+					<<set _temp to "<span class='red'>EVENT ACTIVE</span>">>
+				<<elseif $event.buffer.map(e => e.area[0]).length is 1 and ["Forest Cabin", "Eden Cabin", "Eden Clearing"].includes(EventSystem.Get(0).area[0])>>
+					<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
+				<</if>>
+				<<button _temp>><<overlayReplace "eventExtraInfo">><</button>>
+				<<unset _temp>>
 			<</if>>
-			<<if $debug is 1>>
-				<<debug>>
-			<</if>>
-		</div>
-		<!-- Event debug button - Shows an overlay stored in debug-events.twee. -->
-		<<if $event isnot undefined and $debugdisable is "f">>
-			<<set _temp to "<span class='yellow'>SHOW EVENT INFO</span>">>
-			<<if EventSystem.Get(0).area[0] is $passage>>
-				<<set _eventalertmajorarea to false>>
-				<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
-			<<elseif setup.majorAreas.includes($passage)>>
-				<<set _eventalertmajorarea to true>>
-				<<set _temp to "<span class='red'>EVENT ACTIVE</span>">>
-			<<elseif $event.buffer.map(e => e.area[0]).length is 1 and ["Forest Cabin", "Eden Cabin", "Eden Clearing"].includes(EventSystem.Get(0).area[0])>>
-				<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
+			<<if $options.showDebugRenderer>>
+				<<button "DEBUG RENDERER">><<overlayReplace "canvasModel">><</button>>
 			<</if>>
-			<<button _temp>><<overlayReplace "eventExtraInfo">><</button>>
-			<<unset _temp>>
-		<</if>>
-		<<if $showDebugRenderer>>
-			<<button "DEBUG RENDERER">><<overlayReplace "canvasModel">><</button>>
-		<</if>>
-		<div class="sidebarButtonSplit">
-			<<button OPTIONS>>
-				<<overlayReplace "options">>
-			<</button>>
-			<<button SAVES>>
-				<<overlayReplace "saves">>
-			<</button>>
+			<div class="sidebarButtonSplit">
+				<<button OPTIONS>>
+					<<overlayReplace "options">>
+				<</button>>
+				<<button SAVES>>
+					<<overlayReplace "saves">>
+				<</button>>
+			</div>
 		</div>
 	</div>
 </div>
@@ -936,10 +942,10 @@ Your $worn.under_upper.name <<underupperhas>> been pulled to your $worn.under_up
 	<</if>>
 	<<set _disabled to ["disabled","hidden"]>>
 
-	<<if $sidebarRenderer is undefined>>
-		<<set $sidebarRenderer to 'canvas'>>
+	<<if $options.sidebarRenderer is undefined>>
+		<<set $options.sidebarRenderer to 'canvas'>>
 	<</if>>
-	<<if $sidebarRenderer isnot 'img'>>
+	<<if $options.sidebarRenderer isnot 'img'>>
 		<<selectmodel "main" "sidebar">> <!-- reuse sidebar cache slot -->
 		<<twinescript>>
 			_modeloptions.breast_size = _breastSize;
@@ -1000,14 +1006,14 @@ Your $worn.under_upper.name <<underupperhas>> been pulled to your $worn.under_up
 			}
 			_modeloptions.crotch_visible = !_showClothes && !_showUnderwear;
 		<</twinescript>>
-		<<rendermodel `($sidebarRenderer is 'both' ? 'canvasimg-both' : '')`>>
+		<<rendermodel `($options.sidebarRenderer is 'both' ? 'canvasimg-both' : '')`>>
 	<</if>>
-	<<if $sidebarRenderer isnot 'canvas'>>
+	<<if $options.sidebarRenderer isnot 'canvas'>>
 	<img class="layer-base" @src="_img.basenoarms" @style="'filter: '+_filters.body">
 	<img class="layer-basehead" @src="_img.basehead" @style="'filter: '+_filters.body">
 
 	<img class="layer-breasts" @src="_img['breasts'+ _breastSize]" @style="'filter: '+_filters.breasts">
-	<<if $skinColor.tanImgEnabled is "t" and $skinColor.tanValues[0] isnot $skinColor.tanValues[1]>>
+	<<if $options.tanImgEnabled and $skinColor.tanValues[0] isnot $skinColor.tanValues[1]>>
 		<img class="layer-breasts" @src="_img.baseTanBikini_UUpper + _breastSize + '.png'" @style="'filter: '+_filters.bikiniTop">
 	<</if>>
 
@@ -1050,13 +1056,13 @@ Your $worn.under_upper.name <<underupperhas>> been pulled to your $worn.under_up
 			<img class="layer-penis" @src="_img['penis' + ($player.ballsExist ? '':'noballs') + _penisSize]" @style="'filter: '+_filters.penis">
 		<</if>>
 	<</if>>
-	<<if $skinColor.tanImgEnabled is "f">>
-		<<set $skinColor.tanImgEnabled to "t">>
+	<<if !$options.tanImgEnabled>>
+		<<set $options.tanImgEnabled to true>>
 		<<set _tanReset to true>>
 	<</if>>
 	<<faceimg 1>>
 	<<if _tanReset>>
-		<<set $skinColor.tanImgEnabled to "f">>
+		<<set $options.tanImgEnabled to false>>
 		<<unset _tanReset>>
 	<</if>>
 	<<if _clothesType is "male">>
diff --git a/game/base-system/images.twee b/game/base-system/images.twee
index 4077e791b3..404237c6b6 100644
--- a/game/base-system/images.twee
+++ b/game/base-system/images.twee
@@ -1,7 +1,7 @@
 :: Widgets Breasts Img [widget]
 <<widget "breastsidle">>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.doggy[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.doggy[($options.tanImgEnabled ? "t" : "f")]>>
 <<if $worn.upper.exposed gte 2>>
 	<<if $player.perceived_breastsize is 0>>
 	<<elseif $player.perceived_breastsize is 1 or $player.perceived_breastsize is 2>>
@@ -18,7 +18,7 @@
 
 <<widget "breastsactive">>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.doggy[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.doggy[($options.tanImgEnabled ? "t" : "f")]>>
 <<if $worn.upper.exposed gte 2>>
 	<<if $player.perceived_breastsize is 0>>
 	<<elseif $player.perceived_breastsize is 1 or $player.perceived_breastsize is 2>>
@@ -35,7 +35,7 @@
 
 <<widget "breastsidlemissionary">>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.missionary[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.missionary[($options.tanImgEnabled ? "t" : "f")]>>
 <<if $player.perceived_breastsize is 0>>
 <<elseif $player.perceived_breastsize is 1 or $player.perceived_breastsize is 2>>
 	<img class="layer-sexmouth" @src="_img.breastsTiny" @style="'filter: ' + _filters.body">
@@ -51,7 +51,7 @@
 
 <<widget "breastsactivemissionary">>
 <<set _filters to $skinColor.current>>
-<<set _img to setup.tanImg.missionary[$skinColor.tanImgEnabled]>>
+<<set _img to setup.tanImg.missionary[($options.tanImgEnabled ? "t" : "f")]>>
 <<if $player.perceived_breastsize is 0>>
 <<elseif $player.perceived_breastsize is 1 or $player.perceived_breastsize is 2>>
 	<img @class="'layer-sexmouth anim-doggy-4f-'+_animspeed" @src="_img.breastsTiny" @style="'filter: ' + _filters.body">
@@ -843,7 +843,7 @@
 <</widget>>
 
 <<widget "bedroomtablechairicon">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<set $_table to Furniture.get('table')>>
 		<<set $_chair to Furniture.get('chair')>>
 		<span>
@@ -1038,7 +1038,7 @@
 <</widget>>
 
 <<widget "demonicon">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img class="icon" src="img/ui/sym_demon_purity.png">
 	<</if>>
 <</widget>>
@@ -1060,7 +1060,7 @@
 <</widget>>
 
 <<widget "clothingicon">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<set $_item to setup.clothes[_args[1]][clothesIndex(_args[1],_args[0])]>>
 		<<if $_item.iconFile>>
 			<<if typeof($_item.iconFile) === 'string'>>
@@ -1092,7 +1092,7 @@
 <</widget>>
 
 <<widget "science_star">>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<if $science_star gte 3>>
 		<img class="icon" src="img/ui/gold_star.png">
 	<<elseif $science_star is 2>>
@@ -1109,7 +1109,7 @@
 
 <<widget "g_science_star">>
 	<<if $statdisable is "f">>
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<<if $science_star + 1 is 3>>
 				<img class="icon" src="img/ui/gold_star.png">
 			<<elseif $science_star + 1 is 2>>
@@ -1130,7 +1130,7 @@
 <</widget>>
 
 <<widget "maths_star">>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<if $maths_star gte 3>>
 		<img class="icon" src="img/ui/gold_star.png">
 	<<elseif $maths_star is 2>>
@@ -1147,7 +1147,7 @@
 
 <<widget "g_maths_star">>
 	<<if $statdisable is "f">>
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<<if $maths_star + 1 is 3>>
 				<img class="icon" src="img/ui/gold_star.png">
 			<<elseif $maths_star + 1 is 2>>
@@ -1168,7 +1168,7 @@
 <</widget>>
 
 <<widget "english_star">>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<if $english_star gte 3>>
 		<img class="icon" src="img/ui/gold_star.png">
 	<<elseif $english_star is 2>>
@@ -1185,7 +1185,7 @@
 
 <<widget "g_english_star">>
 	<<if $statdisable is "f">>
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<<if $english_star + 1 is 3>>
 				<img class="icon" src="img/ui/gold_star.png">
 			<<elseif $english_star + 1 is 2>>
@@ -1206,7 +1206,7 @@
 <</widget>>
 
 <<widget "history_star">>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<if $history_star gte 3>>
 		<img class="icon" src="img/ui/gold_star.png">
 	<<elseif $history_star is 2>>
@@ -1223,7 +1223,7 @@
 
 <<widget "g_history_star">>
 	<<if $statdisable is "f">>
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<<if $history_star + 1 is 3>>
 				<img class="icon" src="img/ui/gold_star.png">
 			<<elseif $history_star + 1 is 2>>
diff --git a/game/base-system/mobileStats.twee b/game/base-system/mobileStats.twee
index 28abd6e796..a27b022984 100644
--- a/game/base-system/mobileStats.twee
+++ b/game/base-system/mobileStats.twee
@@ -1,41 +1,42 @@
 :: mobileStats [widget]
 <<widget "mobileStats">>
-<<if $sidebarStats is "All" or $pain gt 50>>
+<<if $options.sidebarStats is "all" or $pain gt 50>>
 	<<mobileStatsColor "pain">>
 	<div @class="'stat ' + _mobileColor">
 		P
 	</div>
 <</if>>
-<<if $sidebarStats is "All" or $arousal gt $arousalmax / 2>>
+<<if $options.sidebarStats is "all" or $arousal gt $arousalmax / 2>>
 	<<mobileStatsColor "arousal">>
 	<div @class="'stat ' + _mobileColor">
 		Ar
 	</div>
 <</if>>
-<<if $sidebarStats is "All" or $tiredness gt C.tiredness.max / 2>>
+
+<<if $options.sidebarStats is "all" or $tiredness gt C.tiredness.max / 2>>
 	<<mobileStatsColor "fatigue">>
 	<div @class="'stat ' + _mobileColor">
 		F
 	</div>
 <</if>>
-<<if $sidebarStats is "All" or $stress gt $stressmax / 2>>
+<<if $options.sidebarStats is "all" or $stress gt $stressmax / 2>>
 	<<mobileStatsColor "stress">>
 	<div @class="'stat ' + _mobileColor">
 		S
 	</div>
 <</if>>
-<<if $innocencestate is 1 and ($sidebarStats is "All" or $awareness gt -100)>>
+<<if $innocencestate is 1 and ($options.sidebarStats is "all" or $awareness gt -100)>>
 	<<mobileStatsColor "innocence">>
 	<div @class="'stat ' + _mobileColor">
 		I
 	</div>
-<<elseif $sidebarStats is "All" or $trauma gt $traumamax / 2>>
+<<elseif $options.sidebarStats is "all" or $trauma gt $traumamax / 2>>
 	<<mobileStatsColor "trauma">>
 	<div @class="'stat ' + _mobileColor">
 		T
 	</div>
 <</if>>
-<<if $sidebarStats is "All" or $control gt $controlmax / 2>>
+<<if $options.sidebarStats is "all" or $control gt $controlmax / 2>>
 	<<mobileStatsColor "control">>
 	<div @class="'stat ' + _mobileColor">
 		C
diff --git a/game/base-system/overlays/characteristics.twee b/game/base-system/overlays/characteristics.twee
index 70bead3e6c..7b6a3ca861 100644
--- a/game/base-system/overlays/characteristics.twee
+++ b/game/base-system/overlays/characteristics.twee
@@ -227,7 +227,9 @@ You have a <<bottom>>.
 <br>
 <<bodywriting>>
 <div id="characteristics-display">
-	<h4>Core Characteristics</h4>
+
+	<br>
+	<span class="gold">Core Characteristics</span>
 	<div id="base-characteristics" class="characteristic-box-list">
 		<!--Core skill configurations-->
 		<<silently>>
@@ -417,7 +419,8 @@ You have a <<bottom>>.
 		]>>
 	<</silently>>
 
-	<h4>Skills</h4>
+	<br>
+	<span class="gold">Skills</span>
 	<div id="base-skills" class="characteristic-box-list" @style="($parasite.left_ear.name == 'slime' || $parasite.right_ear.name == 'slime') ? '--min-width: 30%;' : ''">
 		<!--Additional skills configurations-->
 		<<silently>>
@@ -535,7 +538,8 @@ You have a <<bottom>>.
 		<<characteristic-box _tendingConfig>>
 	</div>
 
-	<h4>Sex Skills</h4>
+	<br>
+	<span class="gold">Sex Skills</span>
 	<!--Sex skills configurations-->
 	<<silently>>
 		<<set _seductionConfig =	{ name : "Seduction",	displayType : "grade",	currentValue : $seductionskill, modifier: 100, modTypes: { good: [], bad: [] },		states : _basicSkillGrades}>>
@@ -556,7 +560,7 @@ You have a <<bottom>>.
 			<<set _vaginalConfig =	{ name : "Vaginal",		displayType : "grade",	currentValue : $vaginalskill,	modifier: 100, modTypes: { good: [], bad: [] },		states : _basicSkillGrades}>>
 		<</if>>
 	<</silently>>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<div id="player-body">
 			<<player-base-body>>
 		</div>
@@ -647,7 +651,8 @@ You have a <<bottom>>.
 		</div>
 	<</if>>
 
-	<h4>School Performance</h4>
+	<br>
+	<span class="gold">School Performance</span>
 	<div id="school-grades" class="characteristic-box-list">
 		<!--School grade configurations-->
 		<<silently>>
@@ -696,7 +701,8 @@ You have a <<bottom>>.
 		<br>
 	</div>
 
-<h4>Weapon skills</h4>
+	<br>
+	<span class="gold">Weapon skills</span>
 	<div id="prof" class="characteristic-box-list">
 		<<silently>>
 			<<set _sprayConfig =		{ name : "Sprays",		displayType : "grade",	currentValue : $prof.spray,		modifier: 100, modTypes: { good: [], bad: [] },		states : _basicSkillGrades}>>
@@ -713,7 +719,10 @@ You have a <<bottom>>.
 </div>
 <br><br>
 
-__Insecurities__ - <i>Scrutiny becomes harder to take as insecurity increases, inflicting more stress and damaging control. Acceptance renders you immune to the effect.</i><br><br>
+<br>
+<span class="gold">Insecurities</span>
+<div class="description">Scrutiny becomes harder to take as insecurity increases, inflicting more stress and damaging control. Acceptance renders you immune to the effect.</div>
+<br><br>
 <<if $insecurity_penis_tiny gte 1 and $player.penissize lte 0 and $acceptance_penis_tiny lte 999>>
 	<span class="red">Insecurity: Tiny Penis</span>
 	<div class="meter">
diff --git a/game/base-system/overlays/cheats.twee b/game/base-system/overlays/cheats.twee
index 6cc40f9dec..d66604a3ea 100644
--- a/game/base-system/overlays/cheats.twee
+++ b/game/base-system/overlays/cheats.twee
@@ -1,25 +1,7 @@
 :: Cheats [widget]
 <<widget "cheats">>
-
-<<button "Character Stats">>
-	<<replace #cheatsShown>><<cheats-characterStats>><</replace>>
-<</button>>
-<<button "Character Visual">>
-	<<replace #cheatsShown>><<cheats-characterVisual>><</replace>>
-<</button>>
-<<button "NPCs">>
-	<<replace #cheatsShown>><<cheats-npcs>><</replace>>
-<</button>>
-<<if !$statFreeze>>
-	<<button "Teleport">>
-		<<replace #cheatsShown>><<cheats-teleport>><</replace>>
-	<</button>>
-<</if>>
-<<button "Other">>
-	<<replace #cheatsShown>><<cheats-other>><</replace>>
-<</button>>
-
-<br><br>
+<h3>Cheats</h3>
+<br>
 <<link [[Confirm|$passage]]>><</link>>
 <br>
 Can cause problems if confirmed during events, or with NPCs around.
@@ -30,8 +12,7 @@ Can cause problems if confirmed during events, or with NPCs around.
 
 <<link "Top of Page">>
 	<<script>>
-		var div = document.getElementById("customOverlay");
-		div.scrollTop = 0;
+		$("#customOverlayContent").scrollTop(0);
 	<</script>>
 <</link>>
 <br><br>
@@ -40,7 +21,7 @@ Can cause problems if confirmed during events, or with NPCs around.
 
 <<widget "cheats-characterStats">>
 
-<u>Miscellaneous</u>
+<span class="gold">Miscellaneous</span>
 <br>
 
 <<link "<<<">><<set $money -= 100000>><<clamp>><<replace "#statsmoney">><<print Math.trunc($money)>><</replace>><</link>> |
@@ -89,7 +70,7 @@ Infinite spray: <span id="statsinfinitespray">$infinitespray</span> |
 <</if>>
 <br>
 
-<u>Player Body:</u>
+<span class="gold">Player Body</span>
 <br>
 <<if ["Wardrobe","Changing Room","Eden Wardrobe","Asylum Wardrobe","Strip Club Dressing Room","Brothel Dressing Room","School Boy Wardrobe","School Girl Wardrobe"].includes($passage)>>
 	/*passage change is intentional to allow the players to quickly see the visual differences*/
@@ -332,7 +313,7 @@ First kiss: <span id="statskissvirginity"><<print ($player.virginity.kiss is tru
 <</link>>
 <br><br>
 
-<u>State</u>
+<span class="gold">State</span>
 <br>
 <<link "Refresh">><<set $pain = 0>><<clamp>><<replace "#statspain">><<print Math.trunc($pain)>><</replace>>
 <<set $arousal = 0>><<clamp>><<replace "#statsarousal">><<print Math.trunc($arousal)>><</replace>>
@@ -437,7 +418,7 @@ Hallucinogens: <span id="statshallucinogen"><<print Math.trunc($hallucinogen)>><
 | <<link ">>>">><<set $hallucinogen += 1000>><<clamp>><<replace "#statshallucinogen">><<print Math.trunc($hallucinogen)>><</replace>> <<updatesidebarimg>><</link>>
 <br><br>
 
-<u>Characteristics</u>
+<span class="gold">Characteristics</span>
 <br>
 <<link "<<<">><<set $purity -= 1000>><<clamp>><<replace "#statspurity">><<print Math.trunc($purity)>><</replace>> <<updatesidebarimg>><</link>> |
 <<link "<<">><<set $purity -= 100>><<clamp>><<replace "#statspurity">><<print Math.trunc($purity)>><</replace>> <<updatesidebarimg>><</link>> |
@@ -592,7 +573,9 @@ Milk volume: <span id="statsmilk_volume"><<print Math.trunc($milk_volume)>></spa
  | <<link ">>>">><<set $milk_volume += 1000>><<clamp>><<replace "#statsmilk_volume">><<print Math.trunc($milk_volume)>><</replace>> <<updatesidebarimg>><</link>>
 <br><br>
 
-<u>Clothes</u> - <i>If clothing health is set to zero or lower, it will break. Leaving the cheats menu will destroy it, and you will not be able to get it back.</i>
+<span class="gold">Clothes</span>
+<br>
+<span class="description">If clothing health is set to zero or lower, it will break. Leaving the cheats menu will destroy it, and you will not be able to get it back.</span>
 <br>
 <<if $worn.over_upper.integrity gte 1>>
 	<<link "<<<">><<set $worn.over_upper.integrity -= 100>><<clamp>><<replace "#statsoverupperintegrity">><<print Math.trunc($worn.over_upper.integrity)>><</replace>> <<updatesidebarimg>><</link>> |
@@ -739,10 +722,9 @@ Milk volume: <span id="statsmilk_volume"><<print Math.trunc($milk_volume)>></spa
 	<i>You are not wearing a mask or gag.</i>
 	<br>
 <</if>>
-
 <br>
 
-<u>Skills</u>
+<span class="gold">Skills</span>
 <br>
 <<link "<<<">><<set $skulduggery -= 1000>><<set $skulduggeryday to $skulduggery>><<clamp>><<replace "#statsskulduggery">><<print Math.trunc($skulduggery)>><</replace>> <<updatesidebarimg>><</link>> |
 <<link "<<">><<set $skulduggery -= 100>><<set $skulduggeryday to $skulduggery>><<clamp>><<replace "#statsskulduggery">><<print Math.trunc($skulduggery)>><</replace>> <<updatesidebarimg>><</link>> |
@@ -787,11 +769,9 @@ Tending: <span id="statstending"><<print Math.trunc($tending)>></span>
  | <<link ">">><<set $tending += 10>><<clamp>><<replace "#statstending">><<print Math.trunc($tending)>><</replace>> <<updatesidebarimg>><</link>>
  | <<link ">>">><<set $tending += 100>><<clamp>><<replace "#statstending">><<print Math.trunc($tending)>><</replace>> <<updatesidebarimg>><</link>>
  | <<link ">>>">><<set $tending += 1000>><<clamp>><<replace "#statstending">><<print Math.trunc($tending)>><</replace>> <<updatesidebarimg>><</link>>
-<br>
-
 <br><br>
 
-<u>Sex skills</u>
+<span class="gold">Sex skills</span>
 <br>
 <<link "<<<">><<set $seductionskill -= 1000>><<clamp>><<replace "#statsseductionskill">><<print Math.trunc($seductionskill)>><</replace>> <<updatesidebarimg>><</link>> |
 <<link "<<">><<set $seductionskill -= 100>><<clamp>><<replace "#statsseductionskill">><<print Math.trunc($seductionskill)>><</replace>> <<updatesidebarimg>><</link>> |
@@ -883,9 +863,8 @@ Chest: <span id="statschestskill"><<print Math.trunc($chestskill)>></span>
  | <<link ">>>">><<set $chestskill += 1000>><<clamp>><<replace "#statschestskill">><<print Math.trunc($chestskill)>><</replace>> <<updatesidebarimg>><</link>>
 <br><br>
 
-<u>School</u>
+<span class="gold">School</span>
 <br>
-
 <<link "<<<">><<set $science -= 1000>><<set $school -= 4000>><<adjust_school_traits>><<clamp>><<replace "#statsscience">><<print Math.trunc($science)>><</replace>> <<updatesidebarimg>><</link>> |
 <<link "<<">><<set $science -= 100>><<set $school -= 400>><<adjust_school_traits>><<clamp>><<replace "#statsscience">><<print Math.trunc($science)>><</replace>> <<updatesidebarimg>><</link>> |
 <<link "<">><<set $science -= 10>><<set $school -= 40>><<adjust_school_traits>><<clamp>><<replace "#statsscience">><<print Math.trunc($science)>><</replace>> <<updatesidebarimg>><</link>> |
@@ -922,9 +901,10 @@ History: <span id="statshistory"><<print Math.trunc($history)>></span>
  | <<link ">>>">><<set $history += 1000>><<set $school += 4000>><<adjust_school_traits>><<clamp>><<replace "#statshistory">><<print Math.trunc($history)>><</replace>> <<updatesidebarimg>><</link>>
 <br><br>
 
-<u>Traits</u> -<i> 0 = Off, 1 = On, -1 = Disabled</i>
+<span class="gold">Traits</span>
+<br>
+<span class="description">0 = Off, 1 = On, -1 = Disabled</span>
 <br>
-
 Orgasm Addict: <span id="statsorgasmtrait">$orgasmtrait</span> |
 <<link "Change">>
 <<set $orgasmtrait += 1>>
@@ -1067,7 +1047,7 @@ Plant Lover: <span id="statsplantlover"><<print $backgroundTraits.includes("plan
 
 <<widget "cheats-characterVisual">>
 
-<u>Character Hair</u>
+<span class="gold">Character Hair</span>
 <br>
 
 <<link "<<<">><<set $hairlength -= 1000>><<clamp>><<replace "#statshairlength">><<print Math.trunc($hairlength)>><</replace>><<calchairlengthstage>> <<updatesidebarimg>><</link>> |
@@ -1112,9 +1092,8 @@ Hair dye
 <</for>>
 <br><br>
 
-<u>Eye Colour</u>
+<span class="gold">Eye Colour</span>
 <br>
-
 Eye colour<br>
 <<set _bar to false>>
 <<for _i = 0; _i < setup.colours.eyes.length; _i++>>
@@ -1130,7 +1109,7 @@ Eye colour<br>
 <</for>>
 <br><br>
 
-<u>Freckles</u>
+<span class="gold">Freckles</span>
 	<br>
 	<<if $player.freckles>>
 		<label>Enabled <<radiobutton "$player.freckles" true checked>></label>
@@ -1141,9 +1120,8 @@ Eye colour<br>
 	<</if>>
 <br><br>
 
-<u>Body part sizes and sensitivity</u>
+<span class="gold">Body part sizes and sensitivity</span>
 <br>
-
 <<link "<<">><<set $player.breastsize -= 3>><<clamp>><<replace "#statsbreastsize">><<print Math.trunc($player.breastsize)>><</replace>><<replace "#statsbreasts">><<breasts>><</replace>> <<updatesidebarimg>><</link>> |
 <<link "<">><<set $player.breastsize -= 1>><<clamp>><<replace "#statsbreastsize">><<print Math.trunc($player.breastsize)>><</replace>><<replace "#statsbreasts">><<breasts>><</replace>> <<updatesidebarimg>><</link>> |
 Breast size: <span id="statsbreastsize"><<print Math.trunc($player.breastsize)>></span>
@@ -1191,9 +1169,8 @@ Between your legs is your: <span id="statsgenitals"><<genitals>></span>
 <br>
 
 <<if $parasitedisable is "f">>
-<u>Parasites</u>
+<span class="gold">Parasites</span>
 <br>
-
 Nipple parasites: <span id="statsnippleparasite"><<if $parasite.nipples.name>>$parasite.nipples.name<<else>>None<</if>></span> |
 <<link "Change">>
 <<if !$parasite.nipples.name>>
@@ -1345,7 +1322,7 @@ Right ear parasite: <span id="statsright_earparasite"><<if $parasite.right_ear.n
 <br><br>
 <</if>>
 
-<u>Semen</u>
+<span class="gold">Semen</span>
 <br>
 <<link "Add all semen">>
 <!-- todosemen -->
@@ -1448,10 +1425,9 @@ Anus semen: <span id="statsanussemen"><<print Math.trunc($player.bodyliquid.anus
 Mouth semen: <span id="statsmouthsemen"><<print Math.trunc($player.bodyliquid.mouth.semen )>></span>
  <<link ">">><<bodyliquid "mouth" "semen" 1>><<replace "#statsmouthsemen">><<print Math.trunc($player.bodyliquid.mouth.semen )>><</replace>> <<updatesidebarimg>><</link>>
 |
-
 <br><br>
 
-<u>Slime</u>
+<span class="gold">Slime</span>
 <br>
 <<link "Add all slime">>
 <<bodyliquid "neck" "goo" 5>><<replace "#statsneckgoo">><<print Math.trunc($player.bodyliquid.neck.goo)>><</replace>>
@@ -1555,7 +1531,7 @@ Mouth slime: <span id="statsmouthgoo"><<print Math.trunc($player.bodyliquid.mout
 |
 <br><br>
 
-<u>Nectar</u>
+<span class="gold">Nectar</span>
 <br>
 <<link "Add all nectar">>
 <<bodyliquid "neck" "nectar" 5>><<replace "#statsnecknectar">><<print Math.trunc($player.bodyliquid.neck.nectar)>><</replace>>
@@ -1659,10 +1635,10 @@ Mouth nectar: <span id="statsmouthnectar"><<print Math.trunc($player.bodyliquid.
 |
 <br><br>
 
-<u>Transformations</u> - <i>Only one animal and one divine transformation at a time.</i>
+<span class="gold">Transformations</span>
+<br>
+<span class="description">Only one animal and one divine transformation at a time.</span>
 <br>
-
-
 Angel Transform: <<link "Set">><<angelTransform>><<updatesidebarimg>><</link>> / <<link "Clear">><<angelTransform 99>><<updatesidebarimg>><</link>><br>
 Demon Transform: <<link "Set">><<demonTransform>><<updatesidebarimg>><</link>> / <<link "Clear">><<demonTransform 99>><<updatesidebarimg>><</link>><br>
 Wolf Transform: <<link "Set">><<wolfTransform>><<updatesidebarimg>><</link>> / <<link "Clear">><<wolfTransform 99>><<updatesidebarimg>><</link>><br>
@@ -1705,7 +1681,7 @@ Bird (30 needed for full transformation): <<link "<">><<set $birdbuild -= 5>><<t
 
 <<widget "cheats-npcs">>
 
-<u>Virginity</u>
+<span class="gold">Virginity</span>
 <br>
 Reset the following NPC's virginities to their starting values:
 <br>
@@ -1724,9 +1700,10 @@ Reset the following NPC's virginities to their starting values:
 <</link>>
 <br><br>
 
-<u>Reputation</u> - <i>Numbers may not appear until the NPC has been met</i>
+<span class="gold">Reputation</span>
+<br>
+<span class="description">Numbers may not appear until the NPC has been met.</span>
 <br>
-
 <<link "<<<">><<npcincr Robin love -100>><<clamp>><<replace "#statsrobinlove">><<print Math.trunc($NPCName[$NPCNameList.indexOf("Robin")].love)>><</replace>><</link>> |
 <<link "<<">><<npcincr Robin love -10>><<clamp>><<replace "#statsrobinlove">><<print Math.trunc($NPCName[$NPCNameList.indexOf("Robin")].love)>><</replace>><</link>> |
 <<link "<">><<npcincr Robin love -1>><<clamp>><<replace "#statsrobinlove">><<print Math.trunc($NPCName[$NPCNameList.indexOf("Robin")].love)>><</replace>><</link>> |
@@ -2178,9 +2155,8 @@ Docks status: <span id="statdockstatus"><<print Math.trunc($dockstatus)>></span>
 	<br><br>
 <</if>>
 
-<u>Fame</u>
+<span class="gold">Fame</span>
 <br>
-
 <<link "<<<">><<famesex -1000 "none" true>><<fameclamp>><<replace "#statsfamesex">><<print Math.trunc($fame.sex)>><</replace>><</link>> |
 <<link "<<">><<famesex -100 "none" true>><<fameclamp>><<replace "#statsfamesex">><<print Math.trunc($fame.sex)>><</replace>><</link>> |
 <<link "<">><<famesex -10 "none" true>><<fameclamp>><<replace "#statsfamesex">><<print Math.trunc($fame.sex)>><</replace>><</link>> |
@@ -2288,12 +2264,10 @@ Model: <span id="statsfamemodel"><<print Math.trunc($fame.model)>></span>
 <<if ["Clothing Shop", "Forest Shop", "School Library Shop", "Adult Shop Store"].includes($passage)>>
 	<span class="red">Teleporting from a clothing store can break your wardrobe.</span> Please leave the shop before teleporting.
 <<else>>
-	Teleporting from anywhere but the overworld can cause bugs.
+	<b>Teleporting from anywhere but the overworld can cause bugs.</b>
 	<br><br>
 
-	<u>Places</u>
-	<br>
-	Town:
+	<span class="gold">Town</span>
 	<br>
 	<<domusicon>>[[Domus Street]]
 	<br>
@@ -2376,14 +2350,14 @@ Model: <span id="statsfamemodel"><<print Math.trunc($fame.model)>></span>
 	<<alleyicon>>[[Residential alleyways]]
 	<br><br>
 
-	<u>Town Outskirts</u>
+	<span class="gold">Town Outskirts</span>
 	<br>
 	<<foresticon>>[[Forest]]
 	<br>
 	<<roadicon>>[[Farm Road 1]]
 	<br><br>
 
-	<u>Underground</u>
+	<span class="gold">Underground</span>
 	<br>
 	<<sewericon>>[[Industrial Drain]]
 	<br>
@@ -2404,7 +2378,7 @@ Model: <span id="statsfamemodel"><<print Math.trunc($fame.model)>></span>
 
 <<widget "cheats-other">>
 
-<u>Time</u>
+<span class="gold">Time</span>
 <br>
 <<link [[Forward 15 minutes|$passage]]>><<pass 15>><</link>>
 <br>
@@ -2427,7 +2401,7 @@ Model: <span id="statsfamemodel"><<print Math.trunc($fame.model)>></span>
 <<link [[Forward 24 hours|$passage]]>><<pass 24 hour>><</link>>
 <br><br>
 
-<u>Weather</u>
+<span class="gold">Weather</span>
 <br>
 Current weather: $weather
 <br>
@@ -2435,19 +2409,23 @@ Change to:
  <<link [[Clear|$passage]]>><<set $weather to "clear">><</link>> |
 <<link [[Overcast|$passage]]>><<set $weather to "overcast">><</link>> |
 <<link [[Rain|$passage]]>><<set $weather to "rain">><</link>>
-
-<br><br>
-<u>Default Action Sets (Too many may reduce combat performance, max outside of cheatmenu is 7)</u>
-<br>
-<<link "<<<">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets -= 10, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>> |
-<<link "<<">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets -= 5, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>> |
-<<link "<">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets -= 1, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>> |
-Sets: <span id="statsDefaultSets"><<print $maxDefaultActionSets>></span>
- | <<link ">">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets += 1, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>>
- | <<link ">>">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets += 5, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>>
- | <<link ">>>">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets += 10, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>>
 <br><br>
 
+<<if $maxDefaultActionSets isnot undefined>>
+	<span class="gold">Default Action Sets</span>
+	<br>
+	<span class="description">Too many may reduce combat performance, max outside of cheatmenu is 7</span>
+	<br>
+	<<link "<<<">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets -= 10, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>> |
+	<<link "<<">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets -= 5, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>> |
+	<<link "<">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets -= 1, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>> |
+	Sets: <span id="statsDefaultSets"><<print $maxDefaultActionSets>></span>
+	| <<link ">">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets += 1, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>>
+	| <<link ">>">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets += 5, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>>
+	| <<link ">>>">><<set $maxDefaultActionSets to Math.clamp($maxDefaultActionSets += 10, 1, 10)>><<replace "#statsDefaultSets">><<print $maxDefaultActionSets>><</replace>><</link>>
+	<br><br>
+<</if>>
+
 <<if $analpregdisable is "f">>
 	<<set _pregnancy to $sexStats.anus.pregnancy>>
 	<div id="cheatsImpregOptions"><<cheatsImpregOptions>></div>
@@ -2457,7 +2435,7 @@ Sets: <span id="statsDefaultSets"><<print $maxDefaultActionSets>></span>
 <</widget>>
 
 <<widget "cheatsImpregOptions">>
-<u>Anal Pregnancy</u>
+<span class="gold">Anal Pregnancy</span>
 <br>
 <<if _pregnancy.count lt _pregnancy.maxCount>>
 	Get Pregnant with a |
@@ -2533,4 +2511,4 @@ Sets: <span id="statsDefaultSets"><<print $maxDefaultActionSets>></span>
 		<<break>>
 	<</if>>
 <</for>>
-<</widget>>
+<</widget>>
\ No newline at end of file
diff --git a/game/base-system/overlays/featsUI.twee b/game/base-system/overlays/featsUI.twee
index 49bca10d01..0d014d7419 100644
--- a/game/base-system/overlays/featsUI.twee
+++ b/game/base-system/overlays/featsUI.twee
@@ -1,8 +1,7 @@
 :: FeatsUI [widget]
 <<widget "feats">>
 <<updateFeats>>
-<h3>Feats</h3>
-
+<br>
 Here you can earn VrelCoins by completing different tasks, each requiring you to meet the requirements in a single save. These will transfer to new games and allow optional bonuses. This will work even if cookies are cleared, however, you have to load your most recent save before starting a new game. Most feats will be earned at midnight, in a specific scene, or when specific text is shown. However, a handful will be unlocked by the hour.
 <br><br>
 Playing on softmode or having the "The rate that events are triggered by allure" setting below 1 will prevent you from earning feats.
@@ -118,7 +117,6 @@ Filter by:
 <</silently>>
 <div @id="'feat-' + _featsCount" class="feat">
 	<div class="featImage">
-		<span class="dot"></span>
 		<<switch _feats[_args[0]].difficulty>>
 			<<case 1>><img src="img/ui/CopperCoin.gif" class="featCoin">
 			<<case 2>><img src="img/ui/SilverCoin.gif" class="featCoin">
@@ -414,7 +412,6 @@ Filter by:
 	<</silently>>
 	<div @id="'feat-' + _featsCount" class="feat">
 		<div class="featImage">
-			<span class="dot"></span>
 			<<switch _feats[_args[0]].difficulty>>
 				<<case 1>><img src="img/ui/CopperCoinFake.gif" class="featCoin">
 				<<case 2>><img src="img/ui/SilverCoinFake.gif" class="featCoin">
diff --git a/game/base-system/overlays/journal.twee b/game/base-system/overlays/journal.twee
index bccbb0d866..884c24c876 100644
--- a/game/base-system/overlays/journal.twee
+++ b/game/base-system/overlays/journal.twee
@@ -1,7 +1,6 @@
 :: Widgets Journal [widget]
 <<widget "journal">>
-
-<h4>Journal</h4>
+<br>
 It is the $monthday<<monthday>> of <<month>> $year.
 <br>
 It has been $days days since the game started.
@@ -28,7 +27,7 @@ It is $season.
 <<for _t to 0; _t lt _plant_keys.length; _t++>>
 	<<if $plants[_plant_keys[_t]].amount gte 1>><<set _plant_temp to 1>>
 		You have <span class="gold"><<print $plants[_plant_keys[_t]].amount>></span> 
-		<<if $images is 1 and setup.plants[_plant_keys[_t]].icon>>
+		<<if $options.images is 1 and setup.plants[_plant_keys[_t]].icon>>
 			<img class="tending_icon" @src="`img/misc/icon/tending/` + setup.plants[_plant_keys[_t]].icon">
 		<</if>>		
 		<<print $plants[_plant_keys[_t]].plural>>. |
@@ -47,7 +46,7 @@ It is $season.
 <</if>>
 <br>
 
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<if $season is "winter">>
 		<img id="world_map" src="img/misc/world_map_winter.png">
 	<<else>>
@@ -603,7 +602,7 @@ It is $season.
 	<<for _i to 0; _i lt _plant_keys.length; _i++>>
 		<<if setup.plants[_plant_keys[_i]].type is "flower" or setup.plants[_plant_keys[_i]].type is "vegetable">>
 			<<if $plants_known.includes( setup.plants[_plant_keys[_i]].name)>>
-				<<if $images is 1 and setup.plants[_plant_keys[_i]].icon>>
+				<<if $options.images is 1 and setup.plants[_plant_keys[_i]].icon>>
 					<img class="tending_icon" @src="`img/misc/icon/tending/` + setup.plants[_plant_keys[_i]].icon">
 				<</if>>
 				<span class="green"><<print setup.plants[_plant_keys[_i]].plural[0].toUpperCase() + setup.plants[_plant_keys[_i]].plural.substring(1)>></span> |
diff --git a/game/base-system/overlays/options.twee b/game/base-system/overlays/options.twee
index c79568eb10..146f99c526 100644
--- a/game/base-system/overlays/options.twee
+++ b/game/base-system/overlays/options.twee
@@ -1,199 +1,226 @@
 :: Options Overlay [widget]
+<<widget "setupOptions">>
+	<<set _optionsRefresh to false>>
+	<<script>>
+		settingsDisableElement();
+		window.Theme.initControl();
+		onInputChanged(() => {
+			if(!T.optionsRefresh) T.optionsRefresh = true;
+		});
+	<</script>>
+<</widget>>
 
-<<widget "options">>
+<<widget "optionsgeneral">>
+	<<setupOptions>>
+	<span class="gold">General</span>
+	<br>
 
-<h3>Options</h3>
-Some of these will only have an effect after changing passage. Changing location, advancing combat/sex or similar actions will be enough.
-<br><br>
+	<<if $debug is 1>>
+		/*<label><<checkbox "$notifyUpdate" false true autocheck>> Notify when there's a new game update available</label>
+		<br>*/
+		<<link "Check for updates">>
+			<<run checkNewVersion()>>
+		<</link>>
+		<br><br>
+	<</if>>
 
-<span class="gold">General Options</span>
+	Theme:
+	<label><input type="radio" name="theme" value="dark" /> Dark</label> |
+	<label><input type="radio" name="theme" value="arctic" /> Nord</label> |
+	<label><input type="radio" name="theme" value="zen" /> Zenburn</label> |
+	<label><input type="radio" name="theme" value="monokai" /> Monokai</label> |
+	<label><input type="radio" name="theme" value="storm" /> Storm</label> |
+	<label><input type="radio" name="theme" value="system-default" /> System default</label>
+	<br>
 
-<br>
-<<if $debug is 1>>
-	/*<label><<checkbox "$notifyUpdate" false true autocheck>> Notify when there's a new game update available</label>
-	<br>*/
-	<<link "Check for updates">>
-		<<run checkNewVersion()>>
-	<</link>>
+	Passage Line Height: <<link "1.75">><<unset $reducedLineHeight>><<removeclass "#passages" "reducedLineHeight">><</link>> | <<link "1.5">><<set $reducedLineHeight to true>><<addclass "#passages" "reducedLineHeight">><</link>>
 	<br><br>
-<</if>>
-
-
-Theme:
-<label>
-	<input type="radio" name="theme" value="dark" /> Dark
-</label> |
-<label>
-	<input type="radio" name="theme" value="arctic" /> Nord
-</label> |
-<label>
-	<input type="radio" name="theme" value="zen" /> Zenburn
-</label> |
-<label>
-	<input type="radio" name="theme" value="monokai" /> Monokai
-</label> |
-<label>
-	<input type="radio" name="theme" value="storm" /> Storm
-</label> |
-<label>
-	<input type="radio" name="theme" value="system-default" /> System default
-</label>
-<<script>>
-	window.Theme.initControl();
-<</script>>
-<br>
-
-Passage Line Height: <<link "1.75">><<unset $reducedLineHeight>><<removeclass "#passages" "reducedLineHeight">><</link>> | <<link "1.5">><<set $reducedLineHeight to true>><<addclass "#passages" "reducedLineHeight">><</link>>
-<br><br>
-<label>
-	<<checkbox "$newWardrobeStyle" false true autocheck>>
-	Show the new wardrobe style
-</label>
-<br>
-
-<label>
-	<<checkbox "$useNarrowMarket" false true autocheck>>
-	Use "narrow screen" version of the market inventory
-</label>
-<br>
-
-<label>
-	<<checkbox "$neverNudeMenus" false true autocheck>>
-	Hide player nudity in menus
-</label>
-<br>
-
-<label>
-	<<checkbox "$showCaptionText" false true autocheck>>
-	Show Caption Text in Sidebar
-</label>
-<br>
-
-<label>
-	<<checkbox "$skipStatisticsConfirmation" false true autocheck>>
-	Skip asking for confirmation when viewing Extra Stats
-</label>
-<br>
-
-<label>
-	<<if $ironmanmode is true>>
-		<<print '<input id="checkbox-autosavedisabled" name="checkbox-autosavedisabled" type="checkbox" tabindex="0" class="macro-checkbox" disabled checked>'>>
-		<span style="color: #7e7e7e;">Disable autosave on sleeping</span>
-	<<else>>
-		<<checkbox "$autosavedisabled" false true autocheck>>
-		Disable autosave on sleeping
+
+	<label>
+		<<checkbox "$options.neverNudeMenus" false true autocheck>>
+		Hide player nudity in menus
+	</label>
+	<br>
+
+	<label data-disabledif="V.ironmanmode===true">
+		<<checkbox "$autosaveDisabled" false true autocheck>> Disable autosave on sleeping
+	</label>
+	<br>
+	<br>
+
+	<span class="gold">Sidebar</span>
+	<br>
+
+	<label><<checkbox "$options.showCaptionText" false true autocheck>> Show Caption Text in Sidebar</label>
+	<br>
+
+	Sidebar character renderer:
+	<label><<radiovar "$options.sidebarRenderer" "img">><<updatesidebarimg>><</radiovar>> Old</label> |
+	<label><<radiovar "$options.sidebarRenderer" "canvas">><<updatesidebarimg>><</radiovar>> New</label> |
+	<label><<radiovar "$options.sidebarRenderer" "both">><<updatesidebarimg>><</radiovar>> Both</label>
+	<br>
+
+	Closed sidebar stats:
+	<label><<radiobutton "$options.sidebarStats" "disabled" autocheck>> Disabled</label> |
+	<label><<radiobutton "$options.sidebarStats" "limited" autocheck>> Limited to important only</label> |
+	<label><<radiobutton "$options.sidebarStats" "all" autocheck>> Show all</label>
+	<br>
+
+	Closed sidebar time:
+	<label><<radiobutton "$options.sidebarTime" "disabled" autocheck>> Disabled</label> |
+	<label><<radiobutton "$options.sidebarTime" "top" autocheck>> Above sidebar stats</label> |
+	<label><<radiobutton "$options.sidebarTime" "bottom" autocheck>> Below sidebar stats</label>
+	<br>
+	<br>
+
+	<span class="gold">Combat</span>
+	<br>
+	Combat Controls:
+	<label><<radiobutton "$options.combatControls" "radio" autocheck>> Radio Buttons</label> |
+	<label><<radiobutton "$options.combatControls" "lists" autocheck>> Lists (No width limit)</label> |
+	<label><<radiobutton "$options.combatControls" "limitedLists" autocheck>> Lists (Width Limit)</label>
+	<br>
+
+	"Yourself" as a target option:
+	<label><<radiobutton "$options.targetYourself" false autocheck>> Disabled</label> |
+	<label><<radiobutton "$options.targetYourself" true autocheck>> Enabled</label>
+	<br>
+
+	<label>
+		<<checkbox "$options.scrollRemember" false true autocheck>>
+		Restore scrolling position during combat
+	</label>
+
+	<<if $map isnot undefined>>
+		<br>
+		<br>
+		<span class="gold">Map</span>
+		<br>
+		<label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.mapMovement" false true autocheck>> Enable map movement by clicking/touching the map icons</label>
+		<br>
+		<label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.mapLegacy" false true autocheck>> Disable SVG map. Enable if town map is not visible.</label>
+		<br>
+		<label data-target="['images', 'maplegacy]" data-disabledif="V.options.images===0||V.options.mapLegacy"><<checkbox "$options.mapMarkers" false true autocheck>> Show clickable area on map</label>
+		<br>
+		<label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.mapTop" false true autocheck>> Move the map above the map links</label>
+	<</if>>
+
+	<br>
+	<br>
+	<<if $passage isnot "Start">>
+		<<button "Restart Game">>
+			<<script>>
+				SugarCube.UI.restart();
+			<</script>>
+		<</button>>
 	<</if>>
-</label>
-<br>
 
-<label>
-	<<checkbox "$scroll_remember" false true autocheck>>
-	Restore scrolling position during combat
-</label>
-<br>
+<</widget>>
 
-<label>
-	<<checkbox "$numpad" false true autocheck>>
-	Enable numpad. Useful on mobile if links break due to translation software
-</label>
+<<widget "optionsperformance">>
+	<<setupOptions>>
+	<span class="gold">Images</span>
+	<br>
+	<<if StartConfig.enableImages is true>>
+		<div>
+			<label><<checkbox "$options.images" 0 1 autocheck>> Enable images</label>
+			<mouse class="tooltip-small linkBlue">(?)<span>Images may not load properly on older Androids</span></mouse>
+		</div>
+		<div><label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.combatImages" 0 1 autocheck>> Enable combat images</label></div>
+
+		<div><label data-target="images" data-disabledif="V.options.images===0">
+			<<checkbox "$options.bodywritingImages" false true autocheck>> Enable body-writing Images
+			<mouse class="tooltip-small linkBlue">(?)<span>Disabling may improve performance and potentially prevent images from not loading correctly</span></mouse>
+		</label></div>
+		<div><label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.silhouetteEnabled" false true autocheck>> Enable NPC silhouettes</label></div>
+		<div><label data-target="images" data-disabledif="V.options.images===0">
+			<<checkbox "$options.tanImgEnabled" false true autocheck>> Visual representation of the player character's skin colour
+			<mouse class="tooltip-small linkBlue">(?)<span>May hinder performance on some devices</span></mouse>
+		</label></div>
+		<div><label data-target='["images", "tanimgenabled"]' data-disabledif="V.options.images===0||V.options.tanImgEnabled===false">
+			<<checkbox "$options.tanningEnabled" false true autocheck>> Tanning changes due to sun exposure
+			<mouse class="tooltip-small linkBlue">(?)<span>Option to disable may be removed at a later date</span></mouse>
+		</label></div>
+		<br>
+
+		<span class="gold">Animations</span>
+		<div><label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.sidebarAnimations" false true autocheck>> Sidebar animations</label></div>
+		<div><label data-target='["images", "sidebaranimations"]' data-disabledif="V.options.images===0||V.options.sidebarAnimations===false"><<checkbox "$options.blinkingEnabled" false true autocheck>> Animate eyes blinking</label></div>
+		<div><label data-target="images" data-disabledif="V.options.images===0||V.options.combatImages===0">
+			<<checkbox "$options.combatAnimations" false true autocheck>> Combat animations
+			<mouse class="tooltip-small linkBlue">(?)<span>Disabling may help improve performance and prevent images from loading incorrectly. Gif images will not be affected. Try disabling sidebar images first</span></mouse>
+		</label></div>
+		<div class="description"></div>
+		<<if $eyelidTEST is true>>
+			<div><label data-target='["images", "sidebaranimations"]' data-disabledif="V.options.images===0||V.options.sidebarAnimations===false"><<checkbox "$options.halfClosedEnabled" false true autocheck>> Enable half-closed eyes graphics</label></div>
+			<div class="description">Draw eyelids in sidebar as half-closed when highly aroused.</div>
+		<</if>>
+		<br>
+		
+
+		<<foldout true "_characterLightingFoldout">>
+			<span class="gold">Character Lighting</span>
+			<div onchange="new Wikifier(null, '<<updatesidebarimg>>')"><label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.characterLightEnabled" false true autocheck>> Enable character lighting</label></div>
+			<div data-target='["images", "characterLightEnabled"]' data-disabledif="V.options.images===0||V.options.characterLightEnabled===false" oninput="new Wikifier(null, '<<updatesidebarimg>>')">
+				<label>Spotlight<br>
+				<<numberslider "$options.lightSpotlight" $options.lightSpotlight 0 1 0.05>></label><br>
+				<label>Gradient<br>
+				<<numberslider "$options.lightGradient" $options.lightGradient 0 1 0.05>></label><br>
+				<label>Glow<br>
+				<<numberslider "$options.lightGlow" $options.lightGlow 0 1 0.05>></label><br>
+				<label>Flat<br>
+				<<numberslider "$options.lightFlat" $options.lightFlat 0 1 0.05>></label><br>
+				<label data-target="images" data-disabledif="V.options.images===0||V.options.combatImages===0">Combat Light<br>
+				<<numberslider "$options.lightCombat" $options.lightCombat 0 1 0.05>></label><br>
+				<label>Angel/Devil TF colour component<br>
+				<<numberslider "$options.lightTFColor" $options.lightTFColor 0 1 0.05>></label><br>
+			</div>
+		<</foldout>>
+		<br>
+
+		<span class="gold">History depth</span>
+		<br>
+		<div class="description">Enables going back in history up to N-1 passages. Changes take effect on settings exit.<br>
+		<span class="red"><b>WARNING:</b> Will cause slowdowns. Additionally, values above 5 can exceed your localStorage quota and cause <br>
+		<b>troubles with saves</b>. Use at your own risk.</span>
+		</div>
+		<<numberslider "$options.maxStates" $options.maxStates 1 20 1 $ironmanmode>>
+		<br><br>
+	<</if>>
+<</widget>>
 
-<<if $map isnot undefined>>
-	<br><br>
-	<span class="gold">Map Options</span>
+<<widget "optionsadvanced">>
+	<<setupOptions>>
+	<span class="gold">Advanced settings</span>
 	<br>
 	<label>
-		<<checkbox "$map.movement" false true autocheck>>
-		Enable map movement by clicking/touching the map icons
+		<<checkbox "$options.numpad" false true autocheck>>
+		Enable numpad. Useful on mobile if links break due to translation software
 	</label>
 	<br>
 	<label>
-		<<checkbox "$map.markers" false true autocheck>>
-		Show clickable area on map
+		<<checkbox "$options.newWardrobeStyle" true false autocheck>>
+		Use the old wardrobe style
 	</label>
 	<br>
-	<<if $map isnot undefined>>
-		<label><<print '<<checkbox "$map.legacy" false true '+($map.legacy is true ? "checked" : "")+'>>'>> Disable SVG map. Enable if town map is not visible. The above option will not work with this enabled. </label><br>
-	<</if>>
-	<label><<print '<<checkbox "$map.top" false true '+($map.top is true ? "checked" : "")+'>>'>>
-		Move the map above the map links
+	<label>
+		<<checkbox "$options.useNarrowMarket" false true autocheck>>
+		Use "narrow screen" version of the market inventory
 	</label>
-<</if>>
-<br><br>
-
-<span class="gold">Image Options</span>
-<br>
-Sidebar character renderer:
-<label><<radiovar "$sidebarRenderer" "img">><<updatesidebarimg>><</radiovar>> Old</label> |
-<label><<radiovar "$sidebarRenderer" "canvas">><<updatesidebarimg>><</radiovar>> New</label> |
-<label><<radiovar "$sidebarRenderer" "both">><<updatesidebarimg>><</radiovar>> Both</label>
-<br>
-
-Closed sidebar stats:
-<label><<radiobutton "$sidebarStats" "Disabled" autocheck>> Disabled</label> |
-<label><<radiobutton "$sidebarStats" "Limited" autocheck>> Limited to important only</label> |
-<label><<radiobutton "$sidebarStats" "All" autocheck>> Show all</label>
-<br>
-
-Closed sidebar time:
-<label><<radiobutton "$sidebarTime" "Disabled" autocheck>> Disabled</label> |
-<label><<radiobutton "$sidebarTime" "top" autocheck>> Above sidebar stats</label> |
-<label><<radiobutton "$sidebarTime" "bottom" autocheck>> Below sidebar stats</label>
-<br>
-/*<label>
-	<<checkbox "$sidebarImage" false true autocheck>>
-	Use sidebar icons rather than text
-</label>
-<br>*/
-<label><<checkbox "$showDebugRenderer" false true autocheck>> Enable renderer debugger</label>
-<br><br>
-
-<span class="gold">Character Lighting Options</span><br>
-<div oninput="new Wikifier(null, '<<updatesidebarimg>>')">
-	Spotlight<br>
-	<<numberslider "$lightSpotlight" $lightSpotlight 0 1 0.05>><br>
-	Gradient<br>
-	<<numberslider "$lightGradient" $lightGradient 0 1 0.05>><br>
-	Glow<br>
-	<<numberslider "$lightGlow" $lightGlow 0 1 0.05>><br>
-	Flat<br>
-	<<numberslider "$lightFlat" $lightFlat 0 1 0.05>><br>
-	Combat Light<br>
-	<<numberslider "$lightCombat" $lightCombat 0 1 0.05>><br>
-	Angel/Devil TF color component<br>
-	<<numberslider "$lightTFColor" $lightTFColor 0 1 0.05>><br>
-</div>
-<br>
-
-<span class="gold">Combat Options</span>
-<br>
-Combat Controls:
-<label><<radiobutton "$combatControls" "radio" autocheck>> Radio Buttons</label> |
-<label><<radiobutton "$combatControls" "lists" autocheck>> Lists (No width limit)</label> |
-<label><<radiobutton "$combatControls" "limitedLists" autocheck>> Lists (Width Limit)</label>
-<br>
-
-"Yourself" as a target option:
-<label><<radiobutton "$targetYourself" false autocheck>> Disabled</label> |
-<label><<radiobutton "$targetYourself" true autocheck>> Enabled</label>
-<br>
-
-Combat images:
-<label><<radiobutton "$combatimages" 0 autocheck>> Disabled</label> |
-<label><<radiobutton "$combatimages" 1 autocheck>> Enabled</label>
-<br><br>
-
-<div class="small-description">To fix animations that aren't playing correctly you can click on them, or press <code>[F]</code> key, or use the button below.</div>
-<br>
-<<if $passage isnot "Start">>
-	<<button "Restart Game">>
-		<<script>>
-			SugarCube.UI.restart();
-		<</script>>
-	<</button>>
-<</if>>
+	<br>
 
-<<button "Fix stuck animations">>
-	<<run fixStuckAnimations()>>
-<</button>>
+	<label>
+		<<checkbox "$options.skipStatisticsConfirmation" false true autocheck>>
+		Skip asking for confirmation when viewing Extra Stats
+	</label>
+	<br>
 
-<</widget>>
+	<label><<checkbox "$options.showDebugRenderer" false true autocheck>> Enable renderer debugger</label>
+	<br>
+	<br>
+	<div class="small-description">To fix animations that aren't playing correctly you can click on them, or press <code>[F]</code> key, or use the button below.</div>
+	<br>
+	<<button "Fix stuck animations">>
+		<<run fixStuckAnimations()>>
+	<</button>>
+<</widget>>
\ No newline at end of file
diff --git a/game/base-system/overlays/overlayReplace.twee b/game/base-system/overlays/overlayReplace.twee
index 498968dd87..33133bb5e0 100644
--- a/game/base-system/overlays/overlayReplace.twee
+++ b/game/base-system/overlays/overlayReplace.twee
@@ -2,204 +2,262 @@
 
 /*
 	Displays overlay (#customOverlay element) with title and content defined by provided key.
-	"overlay-load" event is triggered on `document` when overlay element is updated with new content.
 */
 <<widget "overlayReplace">>
 	<<set _key to _args[0]>>
-
 	<<if _key>>
 		<<if $currentOverlay isnot _key>>
-			<<set $currentOverlay to _key>>
-			<<run $("#customOverlay").attr("data-overlay", $currentOverlay)>>
+		
+			<<script>>
+				let tmpKey = T.key;
+				T.buttons.toggle();
+				updateOptions();
+				V.currentOverlay = T.key;
+				$("#customOverlay").removeClass("hidden").parent().removeClass("hidden");
+				$("#customOverlay").attr("data-overlay", V.currentOverlay);
+			<</script>>
 
 			<<switch _key>>
 				<<case "characteristics">>
-					<<replace #customOverlayTitle>><<OverlayTitle "colorCodes">><</replace>>
+					<<replace #customOverlayTitle>><<titleCharacteristics>><</replace>>
 					<<replace #customOverlayContent>><<characteristics>><</replace>>
-
-				<<case "traits">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
-					<<replace #customOverlayContent>><<traits>><</replace>>
-
 				<<case "social">>
-					<<replace #customOverlayTitle>><<OverlayTitle "colorCodes">><</replace>>
+					<<replace #customOverlayTitle>><<titleSocial>><</replace>>
 					<<replace #customOverlayContent>><<social>><</replace>>
-
+				<<case "traits">>
+					<<replace #customOverlayTitle>><<titleTraits>><</replace>>
+					<<replace #customOverlayContent>><<traits>><</replace>>
 				<<case "journal">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
+					<<replace #customOverlayTitle>><<titleJournal>><</replace>>
 					<<replace #customOverlayContent>><<journal>><</replace>>
-
 				<<case "statistics">>
-					<<replace #customOverlayTitle>><<OverlayTitle "statistics">><</replace>>
+					<<replace #customOverlayTitle>><<titleStats>><</replace>>
 					<<replace #customOverlayContent>><<statistics>><</replace>>
-
-				<<case "extraStatistics">>
-					<<replace #customOverlayTitle>><<OverlayTitle "extraStatistics">><</replace>>
-					<<replace #customOverlayContent>><<extraStatistics>><</replace>>
-
-				<<case "extraStatisticsWarning">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
-					<<replace #customOverlayContent>><<extraStatisticsWarning>><</replace>>
-
 				<<case "gameFeats">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
+					<<replace #customOverlayTitle>><<titleFeats>><</replace>>
 					<<replace #customOverlayContent>><<feats>><</replace>>
-
 				<<case "startFeats">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
+					<<replace #customOverlayTitle>><<titleFeats>><</replace>>
 					<<replace #customOverlayContent>><<feats>><</replace>>
-
+				<<case "cheats">>
+					<<replace #customOverlayTitle>><<titleCheats>><</replace>>
+					<<replace #customOverlayContent>><<cheats>><</replace>>
 				<<case "options">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
-					<<replace #customOverlayContent>><<options>><</replace>>
-
+					<<replace #customOverlayTitle>><<titleOptions>><</replace>>
+					<<replace #customOverlayContent>><<optionsgeneral>><</replace>>
 				<<case "saves">>
-					<<replace #customOverlayTitle>><<OverlayTitle "saves">><</replace>>
+					<<replace #customOverlayTitle>><<titleSaves>><</replace>>
 					<<replace #customOverlayContent>><<saves>><</replace>>
-
-				<<case "optionsExportImport">>
-					<<replace #customOverlayTitle>><<OverlayTitle "optionsExportImport">><</replace>>
-					<<replace #customOverlayContent>><<optionsExportImport>><</replace>>
-
-				<<case "cheats">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
-					<<replace #customOverlayContent>><<cheats>><</replace>>
-
-				<<case "canvasLayers">>
-					<<replace #customOverlayTitle>><<OverlayTitle "canvasLayers">><</replace>>
-					<<replace #customOverlayContent>><<canvasLayersEditor>><</replace>>
-
-				<<case "canvasColours">>
-					<<replace #customOverlayTitle>><<OverlayTitle "canvasColours">><</replace>>
-					<<replace #customOverlayContent>><<canvasColoursEditor `$cheatdisable is "f"`>><</replace>>
-
-				<<case "canvasModel">>
-					<<replace #customOverlayTitle>><<OverlayTitle "canvasModel">><</replace>>
-					<<replace #customOverlayContent>><<canvasModelEditor>><</replace>>
-
 				<<case "blackjackHelp">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
+					<<replace #customOverlayTitle>><<titleBlackjackHelp>><</replace>>
 					<<replace #customOverlayContent>><<blackjackHelp>><</replace>>
-
 				<<case "eventExtraInfo">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
+					<<replace #customOverlayTitle>><<titleEventInfo>><</replace>>
 					<<replace #customOverlayContent>><<eventExtraInfo>><</replace>>
-
+				<<case "canvasModel">>
+					<<replace #customOverlayTitle>><<titleDebugRenderer>><</replace>>
+					<<replace #customOverlayContent>><<canvasModelEditor>><</replace>>
 				<<case "outfitEditor">>
-					<<replace #customOverlayTitle>><<OverlayTitle>><</replace>>
+					<<replace #customOverlayTitle>><<titleOutfitEditor>><</replace>>
 					<<replace #customOverlayContent>><<outfitEditor>><</replace>>
 			<</switch>>
 
-			<<removeclass "#customOverlay" "hidden">>
-			<<script>>
-				document.getElementById("customOverlay").scrollTop = 0;
-				$(document).trigger("overlay-load", $("#customOverlay"));
-			<</script>>
-
 		<<else>>
-			<<set $currentOverlay to null>>
-			<<addclass "#customOverlay" "hidden">>
+			<<run closeOverlay()>>
 		<</if>>
 	<</if>>
 <</widget>>
 
-/* Custom overlay title section. Renders "Close" button and optional content defined by provided key */
-<<widget "OverlayTitle">>
-	<<set _key to _args[0]>>
-
-	<<button Close>>
-		<<addclass "#customOverlay" "hidden">>
-		<<set $currentOverlay to null>>
-	<</button>>
+<<widget "titleCharacteristics">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Characteristics">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<characteristics>><</replace>>
+		<</button>>
+		<<colourCodes>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-	<<switch _key>>
-		<<case "saves">>
-			<<button "Export/Import Save">>
-				<<overlayReplace "optionsExportImport">>
-				<<set $currentOverlay to null>>
-			<</button>>
+<<widget "titleSocial">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Social">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<social>><</replace>>
+		<</button>>
+		<<colourCodes>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<<case "optionsExportImport">>
-			<<button "Return to Saves">>
-				<<overlayReplace "saves">>
-			<</button>>
+<<widget "titleTraits">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Traits">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<traits>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<<case "statistics">>
-			<<button "Extra Stats (Spoilers)">>
-				<<if $skipStatisticsConfirmation>>
-					<<overlayReplace "extraStatistics">>
-				<<else>>
-					<<overlayReplace "extraStatisticsWarning">>
-				<</if>>
+<<widget "titleJournal">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Journal">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<journal>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-				<<set $currentOverlay to null>>
-			<</button>>
+<<widget "titleStats">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Statistics">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<statistics>><</replace>>
+		<</button>>
+		<<button "Extra stats (spoilers)">>
+			<<toggleTab>>
+			<<if $options.skipStatisticsConfirmation>>
+				<<replace #customOverlayContent>><<extraStatistics>><</replace>>
+			<<else>>
+				<<replace #customOverlayContent>><<extraStatisticsWarning>><</replace>>
+			<</if>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<<case "extraStatistics">>
-			<<button "Statistics">>
-				<<overlayReplace "statistics">>
-				<<set $currentOverlay to null>>
-			<</button>>
+<<widget "titleFeats">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Feats">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<feats>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<<case "colorCodes">>
-			<<button "Colour Codes">>
-				<<script>>overlayShowHide('statsHelp');<</script>>
-			<</button>>
-			<div id="statsHelp" class="hidden">
-				<span class="green">Excellent</span>
-				<br>
-				<span class="teal">Good</span>
-				<br>
-				<span class="lblue">Decent</span>
-				<br>
-				<span class="blue">Okay</span>
-				<br>
-				<span class="purple">Poor</span>
-				<br>
-				<span class="pink">Bad</span>
-				<br>
-				<span class="red">Terrible</span>
-				<br>
-			</div>
-	<</switch>>
-
-	<<if _key && _key.indexOf("canvas") == 0>>
-		<<if _key is not "canvasLayers">>
-			<<button "Layers">>
-				<<overlayReplace "canvasLayers">>
+<<widget "titleCheats">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Stats">>
+			<<toggleTab>>
+			<<replace #cheatsShown>><<cheats-characterStats>><</replace>>
+			<<run $("#customOverlayContent").scrollTop(0);>>
+		<</button>>
+		<<button "Visual">>
+			<<toggleTab>>
+			<<replace #cheatsShown>><<cheats-characterVisual>><</replace>>
+			<<run $("#customOverlayContent").scrollTop(0);>>
+		<</button>>
+		<<button "NPCs">>
+			<<toggleTab>>
+			<<replace #cheatsShown>><<cheats-npcs>><</replace>>
+			<<run $("#customOverlayContent").scrollTop(0);>>
+		<</button>>
+		<<if !$statFreeze>>
+			<<button "Teleport">>
+				<<toggleTab>>
+				<<replace #cheatsShown>><<cheats-teleport>><</replace>>
+				<<run $("#customOverlayContent").scrollTop(0);>>
 			<</button>>
-		<<else>>
-			<div class="buttonlike -noborder">Layers</div>
 		<</if>>
+		<<button "Other">>
+			<<toggleTab>>
+			<<replace #cheatsShown>><<cheats-other>><</replace>>
+			<<run $("#customOverlayContent").scrollTop(0);>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<<if _key is not "canvasColours">>
-			<<button "Colours">>
-				<<overlayReplace "canvasColours">>
-			<</button>>
-		<<else>>
-			<div class="buttonlike -noborder">Colours</div>
-		<</if>>
+<<widget "titleOptions">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "General">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<optionsgeneral>><</replace>>
+		<</button>>
+		<<button "Performance">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<optionsperformance>><</replace>>
+		<</button>>
+		<<button "Advanced">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<optionsadvanced>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<<if _key is not "canvasModel">>
-			<<button "Model">>
-				<<overlayReplace "canvasModel">>
-			<</button>>
-		<<else>>
-			<div class="buttonlike -noborder">Model</div>
-		<</if>>
+<<widget "titleSaves">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Saves">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<saves>><</replace>>
+		<</button>>
+		<<button "Export/Import">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<optionsExportImport>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
+
+<<widget "titleBlackjackHelp">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Blackjack Guide">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<blackjackHelp>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
-		<br>
+<<widget "titleEventInfo">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Event Info">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<eventExtraInfo>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
 
+<<widget "titleDebugRenderer">>
+	<<setupTabs 2>>
+	<div id="overlayTabs" class="tab">
+		<<button "Layers">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<canvasLayersEditor>><</replace>>
+		<</button>>
+		<<button "Colours">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<canvasColoursEditor `$cheatdisable is "f"`>><</replace>>
+		<</button>>
+		<<button "Model">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<canvasModelEditor>><</replace>>
+		<</button>>
 		<<if Renderer.lastAnimation>>
-			<<button "Start/stop animation">>
+			<<button "Start/Stop Animation">>
 				<<script>>
 					if (Renderer.lastAnimation.playing) { Renderer.lastAnimation.stop(); }
 					else { Renderer.lastAnimation.start(); }
 				<</script>>
 			<</button>>
 		<</if>>
-
-		<<button "Refresh caches">>
+		<<button "Refresh Caches">>
 			<<script>>
 				Renderer.Stats.logmsgLoad.value = "";
 				Renderer.Stats.logmsgRender.value = "";
@@ -211,15 +269,46 @@
 				Renderer.lastModel.redraw();
 			<</script>>
 		<</button>>
-
-		<br>
-
 		<<script>>
-			output.append(Renderer.Stats.logmsgLoad.bindText($("<div>")[0]));
-			output.append(Renderer.Stats.logmsgRender.bindText($("<div>")[0]));
-			output.append(Renderer.Stats.logmsgAnimate.bindText($("<div>")[0]));
+			output.append(Renderer.Stats.logmsgLoad.bindText($("<div class='rendererOutput'>")[0]));
+			output.append(Renderer.Stats.logmsgRender.bindText($("<div class='rendererOutput'>")[0]));
+			output.append(Renderer.Stats.logmsgAnimate.bindText($("<div class='rendererOutput'>")[0]));
 		<</script>>
-	<</if>>
+	</div>
+	<<closeButton>>
+<</widget>>
+
+<<widget "titleOutfitEditor">>
+	<<setupTabs>>
+	<div id="overlayTabs" class="tab">
+		<<button "Outfit Editor">>
+			<<toggleTab>>
+			<<replace #customOverlayContent>><<outfitEditor>><</replace>>
+		<</button>>
+	</div>
+	<<closeButton>>
+<</widget>>
+
+<<widget "colourCodes">>
+	<mouse class="tooltip-small colourCodes"><span>Colour Codes</span>
+		<span><i class="green">Excellent</i> | <i class="teal">Good</i> |
+		<i class="lblue">Decent</i> | <i class="blue">Okay</i> |
+		<i class="purple">Poor</i> | <i class="pink">Bad</i> |
+		<i class="red">Terrible</i></span>
+	</mouse>
+<</widget>>
 
-	<br><br>
+<<widget "setupTabs">>
+	<<script>>
+		T.tab = new window.Tab("overlayTabs", "tab-selected");
+		T.tab.setActive(T.args[0] || 0);
+	<</script>>
 <</widget>>
+
+<<widget "toggleTab">>
+	<<run T.tab.toggle()>>
+<</widget>>
+
+<<widget "closeButton">>
+	<div class="customOverlayClose" onclick="closeOverlay()"></div>
+<</widget>>
\ No newline at end of file
diff --git a/game/base-system/overlays/saves-export-import.twee b/game/base-system/overlays/saves-export-import.twee
index 1c6173c98d..fe5ac4da85 100644
--- a/game/base-system/overlays/saves-export-import.twee
+++ b/game/base-system/overlays/saves-export-import.twee
@@ -2,10 +2,6 @@
 
 <<widget "optionsExportImport">>
 
-<h3>Saves Export/Import</h3>
-
-<h4>File Import/Export</h4>
-
 <<if SugarCube.Browser.isMobile.any() is true>>
 	Note that saving and loading from file does not work on Android currently.
 <<else>>
@@ -30,8 +26,9 @@
 		Unable to save to file currently.
 	<</if>>
 <</if>>
+<br>
 
-<h4>Text Import/Export</h4>
+<span class="gold">Text Import/Export</span>
 <<if !($dancing is 0 and $combat is 0 and $replayScene is undefined)>>
 	<span class="red"><b>Combat event active, only use resulting save data for bug reporting!!</b></span><br>
 <</if>>
diff --git a/game/base-system/overlays/saves.twee b/game/base-system/overlays/saves.twee
index eb75572266..dae0c0cc9f 100644
--- a/game/base-system/overlays/saves.twee
+++ b/game/base-system/overlays/saves.twee
@@ -1,5 +1,4 @@
 :: Saves overlay [widget]
-
 <<widget "saves">>
 	<<if StartConfig.sneaky>>
 		<div class="sneaky-warning">
@@ -12,9 +11,7 @@
 			</p>
 		</div>
 	<</if>>
-	
-	<h3>Saves</h3>
-
+	<br>
 	<<if $ironmanmode is true>>
 		<span style="background-color: #ffffff1a;">Ironman mode enabled:</span>
 		<ul class="ironman-ul"><li>You can save your game in Ironman mode, but it will lead you back to the Start menu.</li>
diff --git a/game/base-system/overlays/social.twee b/game/base-system/overlays/social.twee
index 26c2189d4d..9d2ae256a9 100644
--- a/game/base-system/overlays/social.twee
+++ b/game/base-system/overlays/social.twee
@@ -1,8 +1,6 @@
 :: Social [widget]
 
 <<widget "social">>
-
-
 <div id="relation-display">
 	<<silently>>
 		<<script>>
@@ -79,19 +77,37 @@
 			T.otherNPCs = T.orderedNPCs.slice(T.importantNpcOrder.length);
 		<</script>>
 	<</silently>>
-	<h4>Primary Relationships</h4>
+
+	<br>
+	<span class="gold">Primary Relationships</span>
 	<div id="npc-relations" class="relation-box-list">
+		<<set _initNPC to 0>>
 		<<for _k = 0; _k lt _importantNPCs.length; _k++>>
 			<<relation-box _importantNPCs[_k] _npcConfig[_importantNPCs[_k].nam]>>
+			<<set _initNPC += _npcData.init>>
 		<</for>>
 	</div>
-	<h4>People of Interest</h4>
+	<<if _initNPC is 0>>
+		//No primary relationships//
+		<br>
+	<</if>>
+
+	<br>
+	<span class="gold">People of Interest</span>
 	<div id="secondary-npcs" class="relation-box-list">
+		<<set _initNPC to 0>>
 		<<for _k= 0; _k lt _otherNPCs.length; _k++>>
 			<<relation-box _otherNPCs[_k] _npcConfig[_otherNPCs[_k].nam]>>
+			<<set _initNPC += _npcData.init>>
 		<</for>>
 	</div>
-	<h4>Reputation</h4>
+	<<if _initNPC is 0>>
+		//No secondary relationships//
+		<br>
+	<</if>>
+
+	<br>
+	<span class="gold">Reputation</span>
 	<div id="faction-reputations" class="relation-box-list">
 		<<silently>>
 			/* Police config */
@@ -336,7 +352,8 @@
 			<</if>>
 		<</silently>>
 
-		<h4>Farm Status</h4>
+		<br>
+		<span class="gold">Farm Status</span>
 		<div id="farm-status" class="relation-box-list">
 			<<relation-box-simple _farmHorseBoxConfig>>
 			<<relation-box-simple _farmPigBoxConfig>>
@@ -347,7 +364,9 @@
 			<</if>>
 		</div>
 	<</if>>
-	<h4>Fame</h4>
+
+	<br>
+	<span class="gold">Fame</span>
 	<div id="global-recognition" class="relation-box-list">
 		<<silently>>
 			<<set _fameStates = [
@@ -437,20 +456,23 @@
 		<<relation-box-simple _overallFameBoxConfig>>
 	</div>
 
+	<br>
 	The townsfolk know you as <span class="teal"><<overworld_nickname>>.</span> Those in the criminal underworld call you <span class="pink"><<underworld_nickname>>.</span>
 
 	<<if $syndromewolves is 1 or $dockwork gte 2>>
-		<h4>Other</h4>
+
+		<br>
+		<span class="gold">Other</span>
 	<</if>>
 	<<if $syndromewolves is 1>>
 		<div id="other-relation-blocks">
-				Wolf pack harmony: <img id="statbar" src="img/ui/wolfharmony.png">
+				<b>Wolf pack harmony:</b> <img id="statbar" src="img/ui/wolfharmony.png">
 				<div class="meter">
 					<<set $percent=Math.floor((Math.min(20, $wolfpackharmony)/20)*100)>>
 					<<print '<div class="goldbar" style="width:' + $percent + '%"></div>'>>
 				</div>
 
-				Wolf pack ferocity: <img id="statbar" src="img/ui/wolfferocity.png">
+				<b>Wolf pack ferocity:</b> <img id="statbar" src="img/ui/wolfferocity.png">
 				<div class="meter">
 					<<set $percent=Math.floor((Math.min(20, $wolfpackferocity)/20)*100)>>
 					<<print '<div class="goldbar" style="width:' + $percent + '%"></div>'>>
@@ -461,7 +483,7 @@
 
 	<<if $dockwork gte 2>>
 		<div id="other-relation-blocks">
-				Docks:
+				<b>Docks:</b>
 				<<set $dockstatus = Math.clamp($dockstatus, 0, 100)>>
 				<<if $dockstatus gte 100>>
 					<span class="green">The other workers respect you.</span>
diff --git a/game/base-system/overlays/statistics.twee b/game/base-system/overlays/statistics.twee
index e3d9f2ff34..e5603cf4e8 100644
--- a/game/base-system/overlays/statistics.twee
+++ b/game/base-system/overlays/statistics.twee
@@ -1,438 +1,444 @@
 :: Statistics [widget]
 <<widget "statistics">>
-<h3>Statistics</h3>
-__Virginities__
-<br>
-<<if $player.vaginaExist>>
-	Vaginal virginity: <<print ($player.virginity.vaginal is true ? "Present" : "Taken by " + ($player.virginity.vaginal is false ? "unknown" : $player.virginity.vaginal))>>
+
+<<foldout false "_virginitiesFoldout">>
+	<span class="gold">Virginities</span>
+	<<if $player.vaginaExist>>
+		Vaginal virginity: <<print ($player.virginity.vaginal is true ? "Present" : "Taken by " + ($player.virginity.vaginal is false ? "unknown" : $player.virginity.vaginal))>>
+		<br>
+	<</if>>
+	<<if $player.penisExist>>
+		Penile virginity: <<print ($player.virginity.penile is true ? "Present" : "Taken by " + ($player.virginity.penile is false ? "unknown" : $player.virginity.penile))>>
+		<br>
+	<</if>>
+
+	Anal virginity: <<print ($player.virginity.anal is true ? "Present" : "Taken by " + ($player.virginity.anal is false ? "unknown" : $player.virginity.anal))>>
 	<br>
-<</if>>
-<<if $player.penisExist>>
-	Penile virginity: <<print ($player.virginity.penile is true ? "Present" : "Taken by " + ($player.virginity.penile is false ? "unknown" : $player.virginity.penile))>>
+	Oral virginity: <<print ($player.virginity.oral is true ? "Present" : "Taken by " + ($player.virginity.oral is false ? "unknown" : $player.virginity.oral))>>
 	<br>
-<</if>>
-
-Anal virginity: <<print ($player.virginity.anal is true ? "Present" : "Taken by " + ($player.virginity.anal is false ? "unknown" : $player.virginity.anal))>>
-<br>
-Oral virginity: <<print ($player.virginity.oral is true ? "Present" : "Taken by " + ($player.virginity.oral is false ? "unknown" : $player.virginity.oral))>>
-<br>
-Handholding virginity: <<print ($player.virginity.handholding is true ? "Present" : "Taken by " + ($player.virginity.handholding is false ? "unknown" : $player.virginity.handholding))>>
-<br>
-First kiss: <<print ($player.virginity.kiss is true ? "Present" : "Taken by " + ($player.virginity.kiss is false ? "unknown" : $player.virginity.kiss))>>
-<br><br>
-__Virginities taken__
-<br>
-<!-- For the total virginities taken, iterate over every virginity type and sum up the number of entries belonging to each. -->
-<<set _total to 0>>
-<<run Object.values($virginTaken).forEach(type => _total += type.length)>>
-Total: _total
-<br>
+	Handholding virginity: <<print ($player.virginity.handholding is true ? "Present" : "Taken by " + ($player.virginity.handholding is false ? "unknown" : $player.virginity.handholding))>>
+	<br>
+	First kiss: <<print ($player.virginity.kiss is true ? "Present" : "Taken by " + ($player.virginity.kiss is false ? "unknown" : $player.virginity.kiss))>>
+	<br><br>
+<</foldout>>
 
-<!-- For each individual virginity type, the number is named and unnamed combined, but the list of names has unnamed npcs filtered out. -->
-<<set _vaginalNamed to $virginTaken.vaginal.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
-<<set _penileNamed to $virginTaken.penile.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
-<<set _analNamed to $virginTaken.anal.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
-<<set _oralNamed to $virginTaken.oral.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
-<<set _handholdingNamed to $virginTaken.handholding.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
-<<set _kissNamed to $virginTaken.kiss.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
+<<foldout false "_virginitiesTakenFoldout">>
+	<span class="gold">Virginities taken</span>
+	<!-- For the total virginities taken, iterate over every virginity type and sum up the number of entries belonging to each. -->
+	<<set _total to 0>>
+	<<run Object.values($virginTaken).forEach(type => _total += type.length)>>
+	Total: _total
+	<br>
 
-Vaginal: $virginTaken.vaginal.length<<print (_vaginalNamed.length gte 1 ? ", including: " + _vaginalNamed.join(', ') : "")>>
-<br>
-Penile: $virginTaken.penile.length<<print (_penileNamed.length gte 1 ? ", including: " + _penileNamed.join(', ') : "")>>
-<br>
-Anal: $virginTaken.anal.length<<print (_analNamed.length gte 1 ? ", including: " + _analNamed.join(', ') : "")>>
-<br>
-Oral: $virginTaken.oral.length<<print (_oralNamed.length gte 1 ? ", including: " + _oralNamed.join(', ') : "")>>
-<br>
-First hands held: $virginTaken.handholding.length<<print (_handholdingNamed.length gte 1 ? ", including: " + _handholdingNamed.join(', ') : "")>>
-<br>
-First kisses: $virginTaken.kiss.length<<print (_kissNamed.length gte 1 ? ", including: " + _kissNamed.join(', ') : "")>>
-<br><br>
+	<!-- For each individual virginity type, the number is named and unnamed combined, but the list of names has unnamed npcs filtered out. -->
+	<<set _vaginalNamed to $virginTaken.vaginal.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
+	<<set _penileNamed to $virginTaken.penile.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
+	<<set _analNamed to $virginTaken.anal.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
+	<<set _oralNamed to $virginTaken.oral.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
+	<<set _handholdingNamed to $virginTaken.handholding.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
+	<<set _kissNamed to $virginTaken.kiss.filter(name => $NPCNameList.indexOf(name) isnot -1)>>
 
-__Jobs__
-<br>
-Danced: $dancestat
-<br>
-Drinks served: $drinksservedstat
-<br>
-Tables served: $tablesservedstat
-<br>
-Whored yourself: $prostitutionstat
-<br>
-<<if $gamemode isnot "soft">>
-Forcibly whored out: $forcedprostitutionstat
-<br>
-<</if>>
-Hours worked on the docks: $dockhours
-<br>
-Buns sold at the cafe: $bunstat
-<br>
-Most "cream" produced: <<print parseFloat($creamstat.toFixed(1))>> mL
-<br>
-Smugglers intercepted: $smuggler_stolen_stat
-<br>
-Produce sold: $produce_sold
-<br>
-<<if $farmersProduce>>
-	Produce sold in bulk: $farmersProduce.totalSold
+	Vaginal: $virginTaken.vaginal.length<<print (_vaginalNamed.length gte 1 ? ", including: " + _vaginalNamed.join(', ') : "")>>
 	<br>
-<</if>>
-Fertiliser Used: $fertiliser.used
-<br>
-Hours worked on a farm: <<print Math.trunc($farm_shift / 60)>>
-<br>
-Cattle milked: $cattle_milked
-<br>
-Clients serviced as a masseur: $masseur_stat
-<br>
-Wild plants picked: $wild_plant_stat
-<br>
-Aphrodisiacs sold: $stat_aphrodisiacs_sold
-<br>
-<br>
-
-__Sex__
-<br>
-Number of orgasms you've experienced: $orgasmstat
-<br>
-<<if $asphyxiaLvl gte 2>>
-	Orgasms while being choked: $chokeorgasm
+	Penile: $virginTaken.penile.length<<print (_penileNamed.length gte 1 ? ", including: " + _penileNamed.join(', ') : "")>>
 	<br>
-<</if>>
-<<if $player.penisExist or $toydildodisable is "f">>
-	Penetrated others: $penilestat
+	Anal: $virginTaken.anal.length<<print (_analNamed.length gte 1 ? ", including: " + _analNamed.join(', ') : "")>>
 	<br>
-<</if>>
-<<if $player.penisExist>>
-	Ejaculated in others: $penileejacstat
+	Oral: $virginTaken.oral.length<<print (_oralNamed.length gte 1 ? ", including: " + _oralNamed.join(', ') : "")>>
 	<br>
-<</if>>
-<<if $player.vaginaExist>>
-	Vaginally penetrated: $vaginalstat
+	First hands held: $virginTaken.handholding.length<<print (_handholdingNamed.length gte 1 ? ", including: " + _handholdingNamed.join(', ') : "")>>
 	<br>
-	Ejaculated in vaginally: $vaginalejacstat
+	First kisses: $virginTaken.kiss.length<<print (_kissNamed.length gte 1 ? ", including: " + _kissNamed.join(', ') : "")>>
+	<br><br>
+<</foldout>>
+
+<<foldout false "_jobsFoldout">>
+	<span class="gold">Jobs</span>
+	Danced: $dancestat
 	<br>
-<</if>>
-<<if $analdisable is "f">>
-	Anally penetrated: $analstat
+	Drinks served: $drinksservedstat
 	<br>
-	Ejaculated in anally: $analejacstat
+	Tables served: $tablesservedstat
 	<br>
-<</if>>
-Orally penetrated: $oralstat
-<br>
-Ejaculated in orally: $oralejacstat
-<br>
-Handjobs given: $handstat
-<br>
-Handjob ejaculations: $handejacstat
-<br>
-<<if $footdisable is "f">>
-	Footjobs given: $feetstat
-	<br>
-	Footjob ejaculations: $feetejacstat
+	Whored yourself: $prostitutionstat
 	<br>
-<</if>>
-Thighjobs given: $thighstat
-<br>
-Thighjob ejaculations: $thighejacstat
-<br>
-Chestjobs given: $cheststat
-<br>
-Chestjob ejaculations: $chestejacstat
-<br>
-Buttjobs given: $bottomstat
-<br>
-Buttjob ejaculations: $bottomejacstat
-<br>
-Hair ejaculated on: $hairejacstat
-<br>
-Tummy ejaculated on: $tummyejacstat
-<br>
-Neck ejaculated on: $neckejacstat
-<br>
-<<if $player.vaginaExist>>
-	Pussy ejaculated on: $vaginalentranceejacstat
+	<<if $gamemode isnot "soft">>
+	Forcibly whored out: $forcedprostitutionstat
 	<br>
-<</if>>
-Face ejaculated on: $faceejacstat
-<br>
-Total times you've been ejaculated on or in: $ejacstat
-<br>
-Gloryholes serviced: $gloryholestat
-<br>
-Masturbated: $masturbationstat
-<br>
-Masturbated to orgasm: $masturbationorgasmstat
-<br>
-Minutes spent masturbating: $masturbationtimestat
-<br>
-<<if $breastfeedingdisable is "f">>
-	Breast milk drank: $milk_drank_stat mL
-	<br>
-	Breast milk produced: $milk_produced_stat mL
+	<</if>>
+	Hours worked on the docks: $dockhours
 	<br>
-<</if>>
-<<if $plantdisable is "f">>
-	Nectar drank: $nectar_drank_stat mL
+	Buns sold at the cafe: $bunstat
 	<br>
-<</if>>
-<<if $player.penisExist>>
-	Semen produced: <<print Math.floor($semen_produced_stat)>> mL
+	Most "cream" produced: <<print parseFloat($creamstat.toFixed(1))>> mL
 	<br>
-<</if>>
-<<if $player.vaginaExist>>
-	Lewd fluid produced: <<print Math.floor($lube_produced_stat)>> mL
+	Smugglers intercepted: $smuggler_stolen_stat
 	<br>
-<</if>>
-<<if $player.penisExist or $breastfeedingdisable is "f">>
-	Fluid forcibly milked: $fluid_forced_stat mL
+	Produce sold: $produce_sold
 	<br>
-<</if>>
-<<if $knot_stat isnot undefined>>
-	Knotted: $knot_stat
+	<<if $farmersProduce>>
+		Produce sold in bulk: $farmersProduce.totalSold
+		<br>
+	<</if>>
+	Fertiliser Used: $fertiliser.used
 	<br>
-<</if>>
-<<if $sextoystat isnot undefined>>
-	Sex toys used on others: $sextoystat
-<</if>>
-<br>
-<<if $analdoubledisable is "f" and $analdoublestat isnot undefined>>
-	Double anally penetrated: $analdoublestat
+	Hours worked on a farm: <<print Math.trunc($farm_shift / 60)>>
 	<br>
-<</if>>
-<<if $vaginaldoubledisable is "f" and $vaginaldoublestat isnot undefined>>
-	Double vaginally penetrated: $vaginaldoublestat
+	Cattle milked: $cattle_milked
 	<br>
-<</if>>
-<<if $watersportsdisable is "f">>
-	Urinated on: $urinestat
-	<br>
-<</if>>
-<br>
-
-
-<<if $gamemode isnot "soft">>
-	__Violence__
+	Clients serviced as a masseur: $masseur_stat
 	<br>
-	Molested: $moleststat
+	Wild plants picked: $wild_plant_stat
 	<br>
-	Raped: $rapestat
+	Aphrodisiacs sold: $stat_aphrodisiacs_sold
+	<br><br>
+<</foldout>>
+
+<<foldout false "_sexFoldout">>
+	<span class="gold">Sex</span>
+	Number of orgasms you've experienced: $orgasmstat
 	<br>
-	<<if $bestialitydisable is "f">>
-		Raped by animals: $beastrapestat
+	<<if $asphyxiaLvl gte 2>>
+		Orgasms while being choked: $chokeorgasm
 		<br>
-	<<else>>
-		Raped by monster people: $beastrapestat
+	<</if>>
+	<<if $player.penisExist or $toydildodisable is "f">>
+		Penetrated others: $penilestat
 		<br>
 	<</if>>
-	<<if $tentacledisable is "f">>
-		Raped by tentacle monsters: $tentaclerapestat
+	<<if $player.penisExist>>
+		Ejaculated in others: $penileejacstat
 		<br>
 	<</if>>
-	<<if $voredisable is "f">>
-		Swallowed: $swallowedstat
+	<<if $player.vaginaExist>>
+		Vaginally penetrated: $vaginalstat
+		<br>
+		Ejaculated in vaginally: $vaginalejacstat
 		<br>
 	<</if>>
-	<<if $parasitedisable is "f">>
-		Parasites hosted: $parasitestat
+	<<if $analdisable is "f">>
+		Anally penetrated: $analstat
+		<br>
+		Ejaculated in anally: $analejacstat
 		<br>
 	<</if>>
-	Been hit: $hitstat
+	Orally penetrated: $oralstat
+	<br>
+	Ejaculated in orally: $oralejacstat
 	<br>
-	Hit others: $attackstat
+	Handjobs given: $handstat
 	<br>
-	Pepper spray used: $spraystat
+	Handjob ejaculations: $handejacstat
 	<br>
-	<<if $NPCName[$NPCNameList.indexOf("Eden")].init>>
-		Practise shots fired with Eden: $stat_shoot
+	<<if $footdisable is "f">>
+		Footjobs given: $feetstat
+		<br>
+		Footjob ejaculations: $feetejacstat
 		<br>
 	<</if>>
-	Machines disabled: $machine_stat
+	Thighjobs given: $thighstat
 	<br>
-	<<if $lurkerdisable is "f">>
-		Lurkers captured: $stat_lurkers_captured
-		<br><br>
+	Thighjob ejaculations: $thighejacstat
+	<br>
+	Chestjobs given: $cheststat
+	<br>
+	Chestjob ejaculations: $chestejacstat
+	<br>
+	Buttjobs given: $bottomstat
+	<br>
+	Buttjob ejaculations: $bottomejacstat
+	<br>
+	Hair ejaculated on: $hairejacstat
+	<br>
+	Tummy ejaculated on: $tummyejacstat
+	<br>
+	Neck ejaculated on: $neckejacstat
+	<br>
+	<<if $player.vaginaExist>>
+		Pussy ejaculated on: $vaginalentranceejacstat
+		<br>
 	<</if>>
-<</if>>
-
-__Dates__
-<br>
-<<if $dateCount.Total lte 0>>
-	You haven't gone on any dates!<br>
-<<else>>
-	Total Dates: $dateCount.Total
+	Face ejaculated on: $faceejacstat
+	<br>
+	Total times you've been ejaculated on or in: $ejacstat
+	<br>
+	Gloryholes serviced: $gloryholestat
+	<br>
+	Masturbated: $masturbationstat
+	<br>
+	Masturbated to orgasm: $masturbationorgasmstat
 	<br>
-	<<if $dateCount.Robin gte 1>>
-		Dates with Robin: $dateCount.Robin
+	Minutes spent masturbating: $masturbationtimestat
+	<br>
+	<<if $breastfeedingdisable is "f">>
+		Breast milk drank: $milk_drank_stat mL
+		<br>
+		Breast milk produced: $milk_produced_stat mL
 		<br>
 	<</if>>
-	<<if $dateCount.Whitney gte 1>>
-		Dates with Whitney: $dateCount.Whitney
+	<<if $plantdisable is "f">>
+		Nectar drank: $nectar_drank_stat mL
 		<br>
 	<</if>>
-	<<if $dateCount.Kylar gte 1>>
-		Dates with Kylar: $dateCount.Kylar
+	<<if $player.penisExist>>
+		Semen produced: <<print Math.floor($semen_produced_stat)>> mL
 		<br>
 	<</if>>
-	<<if $dateCount.Eden gte 1>>
-		Dates with Eden: $dateCount.Eden
+	<<if $player.vaginaExist>>
+		Lewd fluid produced: <<print Math.floor($lube_produced_stat)>> mL
 		<br>
 	<</if>>
-	<<if $dateCount.Avery gte 1>>
-		Dates with Avery: $dateCount.Avery
+	<<if $player.penisExist or $breastfeedingdisable is "f">>
+		Fluid forcibly milked: $fluid_forced_stat mL
 		<br>
 	<</if>>
-	<<if $dateCount.BlackWolfHunts gte 1>>
-		Hunts with the Black Wolf: $dateCount.BlackWolfHunts
+	<<if $knot_stat isnot undefined>>
+		Knotted: $knot_stat
 		<br>
 	<</if>>
-	<<if $dateCount.GreatHawkHunts gte 1>>
-		Hunts with the Great Hawk: $dateCount.GreatHawkHunts
+	<<if $sextoystat isnot undefined>>
+		Sex toys used on others: $sextoystat
+	<</if>>
+	<br>
+	<<if $analdoubledisable is "f" and $analdoublestat isnot undefined>>
+		Double anally penetrated: $analdoublestat
 		<br>
 	<</if>>
-	<<if $dateCount.Alex gte 1>>
-		Dates with Alex: $dateCount.Alex
+	<<if $vaginaldoubledisable is "f" and $vaginaldoublestat isnot undefined>>
+		Double vaginally penetrated: $vaginaldoublestat
 		<br>
 	<</if>>
-	<<if $dateCount.Sydney gte 1>>
-		Dates with Sydney: $dateCount.Sydney
+	<<if $watersportsdisable is "f">>
+		Urinated on: $urinestat
 		<br>
 	<</if>>
-<</if>>
-<br>
-
-/*ToDo: Pregnancy, remove check to properly enable*/
-<<if $pregnancyTesting>>
-	__Pregnancy__
 	<br>
-	<<if $player.vaginaExist>>
-		Times given birth: <<print $sexStats.vagina.pregnancy.totalBirthEvents>>
+<</foldout>>
+
+<<if $gamemode isnot "soft">>
+	<<foldout false "_violenceFoldout">>
+		<span class="gold">Violence</span>
+		Molested: $moleststat
+		<br>
+		Raped: $rapestat
+		<br>
+		<<if $bestialitydisable is "f">>
+			Raped by animals: $beastrapestat
+			<br>
+		<<else>>
+			Raped by monster people: $beastrapestat
+			<br>
+		<</if>>
+		<<if $tentacledisable is "f">>
+			Raped by tentacle monsters: $tentaclerapestat
+			<br>
+		<</if>>
+		<<if $voredisable is "f">>
+			Swallowed: $swallowedstat
+			<br>
+		<</if>>
+		<<if $parasitedisable is "f">>
+			Parasites hosted: $parasitestat
+			<br>
+		<</if>>
+		Been hit: $hitstat
 		<br>
-		Total number of children: <<print $pregnancyStats.playerChildren>>
+		Hit others: $attackstat
 		<br>
-		Total number of human children: <<print $pregnancyStats.humanChildren>>
+		Pepper spray used: $spraystat
 		<br>
-		Total number of wolf children: <<print $pregnancyStats.wolfChildren>>
+		<<if $NPCName[$NPCNameList.indexOf("Eden")].init>>
+			Practise shots fired with Eden: $stat_shoot
+			<br>
+		<</if>>
+		Machines disabled: $machine_stat
 		<br>
-		After Morning pills taken: <<print $pregnancyStats.aftermorningpills>>
+		<<if $lurkerdisable is "f">>
+			Lurkers captured: $stat_lurkers_captured
+			<br><br>
+		<</if>>
+	<</foldout>>
+<</if>>
+
+<<foldout false "_datesFoldout">>
+	<span class="gold">Dates</span>
+	<<if $dateCount.Total lte 0>>
+		You haven't gone on any dates!<br>
+	<<else>>
+		Total Dates: $dateCount.Total
 		<br>
-	<</if>>
-	<<if $player.vaginaExist or $pregnancyStats.pregnancyTestsTaken gt 0>>
-		Pregnancy tests taken: <<print $pregnancyStats.pregnancyTestsTaken>>
+		<<if $dateCount.Robin gte 1>>
+			Dates with Robin: $dateCount.Robin
+			<br>
+		<</if>>
+		<<if $dateCount.Whitney gte 1>>
+			Dates with Whitney: $dateCount.Whitney
+			<br>
+		<</if>>
+		<<if $dateCount.Kylar gte 1>>
+			Dates with Kylar: $dateCount.Kylar
+			<br>
+		<</if>>
+		<<if $dateCount.Eden gte 1>>
+			Dates with Eden: $dateCount.Eden
+			<br>
+		<</if>>
+		<<if $dateCount.Avery gte 1>>
+			Dates with Avery: $dateCount.Avery
+			<br>
+		<</if>>
+		<<if $dateCount.BlackWolfHunts gte 1>>
+			Hunts with the Black Wolf: $dateCount.BlackWolfHunts
+			<br>
+		<</if>>
+		<<if $dateCount.GreatHawkHunts gte 1>>
+			Hunts with the Great Hawk: $dateCount.GreatHawkHunts
+			<br>
+		<</if>>
+		<<if $dateCount.Alex gte 1>>
+			Dates with Alex: $dateCount.Alex
+			<br>
+		<</if>>
+		<<if $dateCount.Sydney gte 1>>
+			Dates with Sydney: $dateCount.Sydney
+			<br>
+		<</if>>
 	<</if>>
 	<br>
-	Anal Pregnancy Births: <<print $sexStats.anus.pregnancy.givenBirth>>
-	<br><br>
-<</if>>
-
-
+<</foldout>>
 
-__Gambling__
-<br>
-Games of blackjack played: $estatePersistent.totalGamesPlayed
-<br>
-Games of blackjack played with betting: $estatePersistent.totalGamesPlayedWithBetting
-<br>
-Rounds of blackjack won/lost/tied: $estatePersistent.totalRoundsWon/$estatePersistent.totalRoundsLost/$estatePersistent.totalRoundsTied
-<br>
-Rounds of blackjack won/lost/tied (with bets): $estatePersistent.totalBetRoundsWon/$estatePersistent.totalBetRoundsLost/$estatePersistent.totalBetRoundsTied
-<br>
-Money won in blackjack: <<formatmoney $estatePersistent.totalBetMoneyMade>>_printmoney
-<br>
-Money lost in blackjack: <<formatmoney $estatePersistent.totalBetMoneyLost>>_printmoney
-<br>
-Money confiscated in blackjack: <<formatmoney $estatePersistent.totalMoneyConfiscated>>_printmoney
-<br>
-Tips received in blackjack: <<formatmoney $estatePersistent.totalTipMoneyMade>>_printmoney
-<br>
-Times caught cheating: $estatePersistent.totalCaughtCheating
-<br>
-Highest blackjack streak: $estatePersistent.winStreakHighScore
-<<if $blackjack_played gt 0 or $blackjack_won gt 0>>
-	<br>
-	Rounds of old blackjack played/won: $blackjack_played/$blackjack_won
-<</if>>
-<<if $blackjack_streak_high and $blackjack_streak_high gt 0>>
-	<br>
-	Highest old blackjack streak: $blackjack_streak_high
+/*ToDo: Pregnancy, remove check to properly enable*/
+<<if $pregnancyTesting>>
+	<<foldout false "_pregnancyFoldout">>
+		<span class="gold">Pregnancy</span>
+		<<if $player.vaginaExist>>
+			Times given birth: <<print $sexStats.vagina.pregnancy.totalBirthEvents>>
+			<br>
+			Total number of children: <<print $pregnancyStats.playerChildren>>
+			<br>
+			Total number of human children: <<print $pregnancyStats.humanChildren>>
+			<br>
+			Total number of wolf children: <<print $pregnancyStats.wolfChildren>>
+			<br>
+			After Morning pills taken: <<print $pregnancyStats.aftermorningpills>>
+			<br>
+		<</if>>
+		<<if $player.vaginaExist or $pregnancyStats.pregnancyTestsTaken gt 0>>
+			Pregnancy tests taken: <<print $pregnancyStats.pregnancyTestsTaken>>
+		<</if>>
+		<br>
+		Anal Pregnancy Births: <<print $sexStats.anus.pregnancy.givenBirth>>
+		<br><br>
+	<</foldout>>
 <</if>>
-<br><br>
-
 
-__Miscellaneous__
-<br>
-<<if $gamemode isnot "soft">>
-	Rescued: $rescued
+<<foldout false "_gamblingFoldout">>
+	<span class="gold">Gambling</span>
+	Games of blackjack played: $estatePersistent.totalGamesPlayed
 	<br>
-<</if>>
-Clothing stripped: $clothesstripstat
-<br>
-Clothing ruined: $clothesruinstat
-<br>
-Passed out: $passoutstat
-<br>
-/*ToDo: Pregnancy, remove the duplicate stat*/
-<<if $analpregdisable is "f">>
-	Anal Pregnancy Births: <<print $sexStats.anus.pregnancy.givenBirth>>
+	Games of blackjack played with betting: $estatePersistent.totalGamesPlayedWithBetting
 	<br>
-<</if>>
-Crime History: $crimehistory
-<br>
-Distinctions won: $distinction_stat
-<br>
-Hours slept: $sleepStat
-<br>
-Underwear stolen: $stat_panties_stolen
-<br>
-Sentenced with community service: $stat_police.community
-<br>
-Sentenced with the pillory:	$stat_police.pillory
-<br>
-Days in prison: $stat_police.prison
-<br>
-Hypnotised: $hypnotised
-<br>
-<<if $wraith and $wraith.possessCount>>
-	Possessed: $wraith.possessCount
-<</if>>
-
-
+	Rounds of blackjack won/lost/tied: $estatePersistent.totalRoundsWon/$estatePersistent.totalRoundsLost/$estatePersistent.totalRoundsTied
+	<br>
+	Rounds of blackjack won/lost/tied (with bets): $estatePersistent.totalBetRoundsWon/$estatePersistent.totalBetRoundsLost/$estatePersistent.totalBetRoundsTied
+	<br>
+	Money won in blackjack: <<formatmoney $estatePersistent.totalBetMoneyMade>>_printmoney
+	<br>
+	Money lost in blackjack: <<formatmoney $estatePersistent.totalBetMoneyLost>>_printmoney
+	<br>
+	Money confiscated in blackjack: <<formatmoney $estatePersistent.totalMoneyConfiscated>>_printmoney
+	<br>
+	Tips received in blackjack: <<formatmoney $estatePersistent.totalTipMoneyMade>>_printmoney
+	<br>
+	Times caught cheating: $estatePersistent.totalCaughtCheating
+	<br>
+	Highest blackjack streak: $estatePersistent.winStreakHighScore
+	<<if $blackjack_played gt 0 or $blackjack_won gt 0>>
+		<br>
+		Rounds of old blackjack played/won: $blackjack_played/$blackjack_won
+	<</if>>
+	<<if $blackjack_streak_high and $blackjack_streak_high gt 0>>
+		<br>
+		Highest old blackjack streak: $blackjack_streak_high
+	<</if>>
+	<br><br>
+<</foldout>>
 
-<br><br>
-__Save Game Details__
-<<if $saveDetails isnot undefined>>
+<<foldout false "_miscFoldout">>
+	<span class="gold">Miscellaneous</span>
+	<<if $gamemode isnot "soft">>
+		Rescued: $rescued
+		<br>
+	<</if>>
+	Clothing stripped: $clothesstripstat
 	<br>
-	Normal saves count: <<print $saveDetails.slot.count>>
+	Clothing ruined: $clothesruinstat
 	<br>
-	Exported saves count: <<print $saveDetails.exported.count>>
+	Passed out: $passoutstat
 	<br>
-	Auto saves count: <<print $saveDetails.auto.count>>
+	/*ToDo: Pregnancy, remove the duplicate stat*/
+	<<if $analpregdisable is "f">>
+		Anal Pregnancy Births: <<print $sexStats.anus.pregnancy.givenBirth>>
+		<br>
+	<</if>>
+	Crime History: $crimehistory
 	<br>
-<</if>>
-<<if $saveVersions isnot undefined>>
-	Versions Played On:
-	<br>
-	<<for _i to 0; _i lt $saveVersions.length; _i++>>
-		<<if _i gt 0>>
-			<<if $saveVersions[_i].split(".")[2] is $saveVersions[_i - 1].split(".")[2]>>
-				--
-			<<else>>
-				<br>
-			<</if>>
-		<</if>>
-		$saveVersions[_i]
-	<</for>>
+	Distinctions won: $distinction_stat
 	<br>
-<</if>>
-<<if $saveVersion>>
-	Save loaded from version: $saveVersion
-<</if>>
+	Hours slept: $sleepStat
+	<br>
+	Underwear stolen: $stat_panties_stolen
+	<br>
+	Sentenced with community service: $stat_police.community
+	<br>
+	Sentenced with the pillory:	$stat_police.pillory
+	<br>
+	Days in prison: $stat_police.prison
+	<br>
+	Hypnotised: $hypnotised
+	<<if $wraith and $wraith.possessCount>>
+		<br>
+		Possessed: $wraith.possessCount
+	<</if>>
+	<br><br>
+<</foldout>>
+
+
+<<foldout false "_saveFoldout">>
+	<span class="gold">Save Game Details</span>
+	<<if $saveDetails isnot undefined>>
+		<br>
+		Normal saves count: <<print $saveDetails.slot.count>>
+		<br>
+		Exported saves count: <<print $saveDetails.exported.count>>
+		<br>
+		Auto saves count: <<print $saveDetails.auto.count>>
+		<br>
+	<</if>>
+	<<if $saveVersions isnot undefined>>
+		Versions Played On:
+		<br>
+		<<for _i to 0; _i lt $saveVersions.length; _i++>>
+			<<if _i gt 0>>
+				<<if $saveVersions[_i].split(".")[2] is $saveVersions[_i - 1].split(".")[2]>>
+					--
+				<<else>>
+					<br>
+				<</if>>
+			<</if>>
+			$saveVersions[_i]
+		<</for>>
+		<br>
+	<</if>>
+	<<if $saveVersion>>
+		Save loaded from version: $saveVersion
+	<</if>>
+<</foldout>>
 <</widget>>
 
 <<widget "extraStatisticsWarning">>
 
-<<if $skipStatisticsConfirmation is undefined>><<set $skipStatisticsConfirmation to false>><</if>>
+<<if $options.skipStatisticsConfirmation is undefined>><<set $options.skipStatisticsConfirmation to false>><</if>>
 
 <h3>Extra Statistics</h3>
 
@@ -440,218 +446,220 @@ __Save Game Details__
 	Are you sure you want to see these? They may contain spoilers!
 	<br>
 	<<link "Yes">>
-		<<overlayReplace "extraStatistics">>
+		<<replace #customOverlayContent>><<extraStatistics>><</replace>>
 	<</link>>
-	&nbsp;&nbsp;&nbsp;<<checkbox "$skipStatisticsConfirmation" false true autocheck>> Don't Show Again
+	&nbsp;&nbsp;&nbsp;<<checkbox "$options.skipStatisticsConfirmation" false true autocheck>> Don't Show Again
 	<!-- ignore the nbsp's, they're just for formatting -->
 </div>
 <</widget>>
 
 <<widget "extraStatistics">>
 
-<h3>Extra Statistics</h3>
 <div id="spoilerWarningConfirmed">
-	__State__
-	<br>
-	Pain: <<print Math.trunc($pain)>>
-	<br>
-	Arousal: <<print Math.trunc($arousal)>>
-	<br>
-	Fatigue: <<print Math.trunc($tiredness)>>
-	<br>
-	Stress: <<print Math.trunc($stress)>>
-	<br>
-	Trauma: <<print Math.trunc($trauma)>>
-	<br>
-	Control: <<print Math.trunc($control)>>
-	<br>
-	Allure: <<print Math.trunc($allure)>>
-	<br>
-	Alcohol: <<print Math.trunc($drunk)>>
-	<br>
-	Drugs: <<print Math.trunc($drugged)>>
-	<br>
-	Hallucinogens: <<print Math.trunc($hallucinogen)>>
-	<br><br>
-
-	__Characteristics__
-	<br>
-	Purity: <<print Math.trunc($purity)>>
-	<br>
-	Beauty: <<print Math.trunc($beauty)>>
-	<br>
-	Physique: <<print Math.trunc($physique)>>
-	<br>
-	Willpower: <<print Math.trunc($willpower)>>
-	<br>
-	Awareness: <<print Math.trunc($awareness)>>
-	<br>
-	Promiscuity: <<print Math.trunc($promiscuity)>>
-	<br>
-	Exhibitionism: <<print Math.trunc($exhibitionism)>>
-	<br>
-	Deviancy: <<print Math.trunc($deviancy)>>
-	<br>
-	Corruption: <<print Math.trunc($corruption_slime)>>
-	<br>
-	<<if $temple_rank is "initiate" or $temple_rank is "monk" or $temple_rank is "priest">>
-		Grace: <<print Math.trunc($grace)>>
+	<<foldout false "_stateFoldout">>
+		<span class="gold">State</span>
+		Pain: <<print Math.trunc($pain)>>
 		<br>
-	<</if>>
-	Submissiveness: <<print Math.trunc($submissive)>>
-	<br>
-	Masochism: <<print Math.trunc($masochism)>>
-	<br>
-	Sadism: <<print Math.trunc($sadism)>>
-	<br>
-	Crossdresser progression:
-	<<if $crossdressingTrait isnot undefined>>
-		<<print Math.trunc($crossdressingTrait)>> %
-	<<else>>
-		0
-	<</if>>
-	<br>
-	Lactating: <<print ($lactating is 1 ? "True" : "False")>>
-	<br>
-	<<if $lactating is 1>>
-		Milk amount: <<print Math.trunc($milk_amount)>>
+		Arousal: <<print Math.trunc($arousal)>>
 		<br>
-		Milk volume: <<print Math.trunc($milk_volume)>>
+		Fatigue: <<print Math.trunc($tiredness)>>
 		<br>
-	<</if>>
-	<<if $player.penisExist>>
-		Semen amount: <<print Math.trunc($semen_amount)>>
+		Stress: <<print Math.trunc($stress)>>
 		<br>
-		Semen volume: <<print Math.trunc($semen_volume)>>
+		Trauma: <<print Math.trunc($trauma)>>
 		<br>
-	<</if>>
-	<br>
+		Control: <<print Math.trunc($control)>>
+		<br>
+		Allure: <<print Math.trunc($allure)>>
+		<br>
+		Alcohol: <<print Math.trunc($drunk)>>
+		<br>
+		Drugs: <<print Math.trunc($drugged)>>
+		<br>
+		Hallucinogens: <<print Math.trunc($hallucinogen)>>
+		<br><br>
+	<</foldout>>
 
-	__Clothes__
-	<br>
-	<<if $worn.upper.name isnot "naked">>
-		Upper wetness: <<print Math.trunc($upperwet)>>
+	<<foldout false "_charFoldout">>
+		<span class="gold">Characteristics</span>
+		Purity: <<print Math.trunc($purity)>>
 		<br>
-		Upper integrity: <<print Math.trunc($worn.upper.integrity)>>
+		Beauty: <<print Math.trunc($beauty)>>
 		<br>
-	<</if>>
-	<<if $worn.lower.name isnot "naked">>
-		Lower wetness: <<print Math.trunc($lowerwet)>>
+		Physique: <<print Math.trunc($physique)>>
 		<br>
-		Lower integrity: <<print Math.trunc($worn.lower.integrity)>>
+		Willpower: <<print Math.trunc($willpower)>>
 		<br>
-	<</if>>
-	<<if $worn.under_upper.name isnot "naked">>
-		Under Upper wetness: <<print Math.trunc($underupperwet)>>
+		Awareness: <<print Math.trunc($awareness)>>
 		<br>
-		Under Upper integrity: <<print Math.trunc($worn.under_upper.integrity)>>
+		Promiscuity: <<print Math.trunc($promiscuity)>>
 		<br>
-	<</if>>
-	<<if $worn.under_lower.name isnot "naked">>
-		Under Lower wetness: <<print Math.trunc($underlowerwet)>>
+		Exhibitionism: <<print Math.trunc($exhibitionism)>>
 		<br>
-		Under Lower integrity: <<print Math.trunc($worn.under_lower.integrity)>>
+		Deviancy: <<print Math.trunc($deviancy)>>
 		<br>
-	<</if>>
-	<<if $worn.genitals.name isnot "naked">>
-		<<print setup.clothes.genitals[clothesIndex('genitals',$worn.genitals)].name_cap>> integrity: <<print Math.trunc($worn.genitals.integrity)>>
+		Corruption: <<print Math.trunc($corruption_slime)>>
 		<br>
-	<</if>>
-	<br>
-
-	__Social__
-	<br>
-	School status: <<print Math.trunc($cool)>>
-	<br>
-	Delinquency: <<print Math.trunc($delinquency)>>
-	<br>
-	Detention: <<print Math.trunc($detention)>>
-	<br>
-	Crime: <<print Math.trunc($crime)>>
-	<br>
-	Orphanage hope: <<print Math.trunc($orphan_hope)>>
-	<br>
-	Orphanage rebelliousness: <<print Math.trunc($orphan_reb)>>
-	<br>
-	<<if $dockwork is 2>>
-		Docks status: <<print Math.trunc($dockstatus)>>
+		<<if $temple_rank is "initiate" or $temple_rank is "monk" or $temple_rank is "priest">>
+			Grace: <<print Math.trunc($grace)>>
+			<br>
+		<</if>>
+		Submissiveness: <<print Math.trunc($submissive)>>
 		<br>
-	<</if>>
-	Sex fame: <<print Math.trunc($fame.sex)>>
-	<br>
-	Prostitution fame: <<print Math.trunc($fame.prostitution)>>
-	<br>
-	Rape fame: <<print Math.trunc($fame.rape)>>
-	<br>
-	Bestiality fame: <<print Math.trunc($fame.bestiality)>>
-	<br>
-	Exhibitionism fame: <<print Math.trunc($fame.exhibitionism)>>
-	<br>
-	<<if $pregnancyTesting>> <!-- ToDo: pregnancy, remove to properly enable -->
-		Pregnancy fame: <<print Math.trunc($fame.pregnancy)>>
+		Masochism: <<print Math.trunc($masochism)>>
 		<br>
-	<</if>>
-	Combat fame: <<print Math.trunc($fame.scrap)>>
-	<br>
-	Kindness fame: <<print Math.trunc($fame.good)>>
-	<br>
-	Business fame: <<print Math.trunc($fame.business)>>
-	<br>
-	<<if $dev is 1>>
-		Pimp fame: <<print Math.trunc($fame.pimp)>>
+		Sadism: <<print Math.trunc($sadism)>>
 		<br>
-	<</if>>
-	Socialite fame: <<print Math.trunc($fame.social)>>
-	<br>
-	Model fame: <<print Math.trunc($fame.model)>>
-	<br><br>
+		Crossdresser progression:
+		<<if $crossdressingTrait isnot undefined>>
+			<<print Math.trunc($crossdressingTrait)>> %
+		<<else>>
+			0
+		<</if>>
+		<br>
+		Lactating: <<print ($lactating is 1 ? "True" : "False")>>
+		<br>
+		<<if $lactating is 1>>
+			Milk amount: <<print Math.trunc($milk_amount)>>
+			<br>
+			Milk volume: <<print Math.trunc($milk_volume)>>
+			<br>
+		<</if>>
+		<<if $player.penisExist>>
+			Semen amount: <<print Math.trunc($semen_amount)>>
+			<br>
+			Semen volume: <<print Math.trunc($semen_volume)>>
+			<br>
+		<</if>>
+		<br>
+	<</foldout>>
 
+	<<foldout false "_clothesFoldout">>
+		<span class="gold">Clothes</span>
+		<<if $worn.upper.name isnot "naked">>
+			Upper wetness: <<print Math.trunc($upperwet)>>
+			<br>
+			Upper integrity: <<print Math.trunc($worn.upper.integrity)>>
+			<br>
+		<</if>>
+		<<if $worn.lower.name isnot "naked">>
+			Lower wetness: <<print Math.trunc($lowerwet)>>
+			<br>
+			Lower integrity: <<print Math.trunc($worn.lower.integrity)>>
+			<br>
+		<</if>>
+		<<if $worn.under_upper.name isnot "naked">>
+			Under Upper wetness: <<print Math.trunc($underupperwet)>>
+			<br>
+			Under Upper integrity: <<print Math.trunc($worn.under_upper.integrity)>>
+			<br>
+		<</if>>
+		<<if $worn.under_lower.name isnot "naked">>
+			Under Lower wetness: <<print Math.trunc($underlowerwet)>>
+			<br>
+			Under Lower integrity: <<print Math.trunc($worn.under_lower.integrity)>>
+			<br>
+		<</if>>
+		<<if $worn.genitals.name isnot "naked">>
+			<<print setup.clothes.genitals[clothesIndex('genitals',$worn.genitals)].name_cap>> integrity: <<print Math.trunc($worn.genitals.integrity)>>
+			<br>
+		<</if>>
+		<br>
+	<</foldout>>
 
-	__Transformations__
-	<br>
-	Wolfiness: <<print Math.trunc($wolfbuild)>> (30+ for full transformation)
-	<br>
-	Wolf manifestation: <<print Math.trunc($wolfgirl)>>
-	<br>
-	Cattiness: <<print Math.trunc($catbuild)>> (50+ for full transformation)
-	<br>
-	Cat manifestation: <<print Math.trunc($cat)>>
-	<br>
-	<<if $hallucinations gte 2 or $bestialitydisable is "t">>Harpyness<<else>>Birdieness<</if>>: <<print Math.trunc($birdbuild)>> (30+ for full transformation)
-	<br>
-	<<if $hallucinations gte 2 or $bestialitydisable is "t">>Harpy<<else>>Bird<</if>> manifestation: <<print Math.trunc($harpy)>>
-	<br>
-	Bovinity: <<print Math.trunc($cowbuild)>> (30+ for full transformation)
-	<br>
-	Cow manifestation: <<print Math.trunc($cow)>>
-	<br>
-	Angelicness: <<print Math.trunc($angelbuild)>> (50+ for full transformation)
-	<br>
-	Angel manifestation: <<print Math.trunc($angel)>>
-	<br>
-	Demonicness: <<print Math.trunc($demonbuild)>> (30+ for full transformation)
-	<br>
-	Demonic manifestation: <<print Math.trunc($demon)>>
-	<br>
-	Fallen manifestation:
-	<<print ($fallenangel is undefined ? 0 : Math.trunc($fallenangel))>>
-	<br>
-	<br>
-	
+	<<foldout false "_socialFoldout">>
+		<span class="gold">Social</span>
+		School status: <<print Math.trunc($cool)>>
+		<br>
+		Delinquency: <<print Math.trunc($delinquency)>>
+		<br>
+		Detention: <<print Math.trunc($detention)>>
+		<br>
+		Crime: <<print Math.trunc($crime)>>
+		<br>
+		Orphanage hope: <<print Math.trunc($orphan_hope)>>
+		<br>
+		Orphanage rebelliousness: <<print Math.trunc($orphan_reb)>>
+		<br>
+		<<if $dockwork is 2>>
+			Docks status: <<print Math.trunc($dockstatus)>>
+			<br>
+		<</if>>
+		Sex fame: <<print Math.trunc($fame.sex)>>
+		<br>
+		Prostitution fame: <<print Math.trunc($fame.prostitution)>>
+		<br>
+		Rape fame: <<print Math.trunc($fame.rape)>>
+		<br>
+		Bestiality fame: <<print Math.trunc($fame.bestiality)>>
+		<br>
+		Exhibitionism fame: <<print Math.trunc($fame.exhibitionism)>>
+		<br>
+		<<if $pregnancyTesting>> <!-- ToDo: pregnancy, remove to properly enable -->
+			Pregnancy fame: <<print Math.trunc($fame.pregnancy)>>
+			<br>
+		<</if>>
+		Combat fame: <<print Math.trunc($fame.scrap)>>
+		<br>
+		Kindness fame: <<print Math.trunc($fame.good)>>
+		<br>
+		Business fame: <<print Math.trunc($fame.business)>>
+		<br>
+		<<if $dev is 1>>
+			Pimp fame: <<print Math.trunc($fame.pimp)>>
+			<br>
+		<</if>>
+		Socialite fame: <<print Math.trunc($fame.social)>>
+		<br>
+		Model fame: <<print Math.trunc($fame.model)>>
+		<br><br>
+	<</foldout>>
+
+	<<foldout false "_violenceFoldout">>
+		<span class="gold">Transformations</span>
+		Wolfiness: <<print Math.trunc($wolfbuild)>> (30+ for full transformation)
+		<br>
+		Wolf manifestation: <<print Math.trunc($wolfgirl)>>
+		<br>
+		Cattiness: <<print Math.trunc($catbuild)>> (50+ for full transformation)
+		<br>
+		Cat manifestation: <<print Math.trunc($cat)>>
+		<br>
+		<<if $hallucinations gte 2 or $bestialitydisable is "t">>Harpyness<<else>>Birdieness<</if>>: <<print Math.trunc($birdbuild)>> (30+ for full transformation)
+		<br>
+		<<if $hallucinations gte 2 or $bestialitydisable is "t">>Harpy<<else>>Bird<</if>> manifestation: <<print Math.trunc($harpy)>>
+		<br>
+		Bovinity: <<print Math.trunc($cowbuild)>> (30+ for full transformation)
+		<br>
+		Cow manifestation: <<print Math.trunc($cow)>>
+		<br>
+		Angelicness: <<print Math.trunc($angelbuild)>> (50+ for full transformation)
+		<br>
+		Angel manifestation: <<print Math.trunc($angel)>>
+		<br>
+		Demonicness: <<print Math.trunc($demonbuild)>> (30+ for full transformation)
+		<br>
+		Demonic manifestation: <<print Math.trunc($demon)>>
+		<br>
+		Fallen manifestation:
+		<<print ($fallenangel is undefined ? 0 : Math.trunc($fallenangel))>>
+		<br><br>
+	<</foldout>>
 	
-	__Anal Pregnancy__
-	<br>
-	<<set _pregnancy to $sexStats.anus.pregnancy>>
-	<<for _i to 0; _i lt _pregnancy.maxCount; _i++>>
-	<<if _pregnancy[_i] isnot null>>
-	<<if _pregnancy[_i].fertilised>>
-	Anal slot <<=_i+1>> is pregnant with a _pregnancy[_i].stats.gender _pregnancy[_i].creature, and will be ready to deliver in less than <<=_pregnancy[_i].daysLeft + 1>> days.<br>
-	<<else>>
-	Anal slot <<=_i+1>> has a _pregnancy[_i].stats.gender _pregnancy[_i].creature egg ready to be fertilised.<br>
-	<</if>>
-	<<else>>
-	Anal slot <<=_i+1>> is empty.<br>
-	<</if>>
-	<</for>>
+	<<foldout false "_violenceFoldout">>
+		<span class="gold">Anal Pregnancy</span>
+		<<set _pregnancy to $sexStats.anus.pregnancy>>
+		<<for _i to 0; _i lt _pregnancy.maxCount; _i++>>
+		<<if _pregnancy[_i] isnot null>>
+		<<if _pregnancy[_i].fertilised>>
+		Anal slot <<=_i+1>> is pregnant with a _pregnancy[_i].stats.gender _pregnancy[_i].creature, and will be ready to deliver in less than <<=_pregnancy[_i].daysLeft + 1>> days.<br>
+		<<else>>
+		Anal slot <<=_i+1>> has a _pregnancy[_i].stats.gender _pregnancy[_i].creature egg ready to be fertilised.<br>
+		<</if>>
+		<<else>>
+		Anal slot <<=_i+1>> is empty.<br>
+		<</if>>
+		<</for>>
+	<</foldout>>
 </div>
-<</widget>>
+<</widget>>
\ No newline at end of file
diff --git a/game/base-system/settings.twee b/game/base-system/settings.twee
index d1683015c3..4703533691 100644
--- a/game/base-system/settings.twee
+++ b/game/base-system/settings.twee
@@ -18,10 +18,6 @@
 <<set $awareselect to "innocent">>
 <<set $background to "waif">>
 <<set $startingseason to "autumn">>
-<<if StartConfig.enableImages is true>>
-	<<set $images to 1>>
-	<<set $silhouettedisable to "f">>
-<</if>>
 <<set $numberify_enabled to 1>>
 <<set $gamemode to "normal">>
 <<set $whitechance to 90>>
@@ -62,7 +58,6 @@
 <<set $pregnancyspeechdisable to "f">>
 <<set $tipdisable to "f">>
 <<set $statdisable to "f">>
-<<set $bodywritingImages to true>>
 <<if $debug is 1>>
 	<<set $debugdisable to "f">>
 <<else>>
@@ -77,22 +72,7 @@
 <<set $checkstyle to "words">>
 <<set $blackwolfmonster to 1>>
 <<set $greathawkmonster to 1>>
-<<set $blinkingdisable to "f">>
-<<set $halfcloseddisable to "f">>
-
-<<set $newWardrobeStyle to true>>
-<<set $lightSpotlight to 0.2>>
-<<set $lightGradient to 0>>
-<<set $lightGlow to 0>>
-<<set $lightFlat to 0>>
-<<set $lightCombat to 0.2>>
-<<set $lightTFColor to 0.2>>
-<<set $sidebarStats to "Disabled">>
-<<set $sidebarTime to "Disabled">>
-<<set $combatControls to "radio">>
 <<set $reducedLineHeight to false>>
-<<set $sidebarAnimations to true>>
-<<set $combatAnimations to true>>
 <<set $clothesPrice to 1>>
 <<set $clothesPriceUnderwear to 1>>
 <<set $clothesPriceSchool to 1>>
@@ -109,7 +89,6 @@
 <<set $condomchance to 50>>
 <<set $condomautochance to 50>>
 <<set $multipleWardrobes to "isolated">>
-<<set $targetYourself to false>>
 <<set $tending_yield_factor to 5>>
 
 <<set $notifyUpdate = true>>
@@ -175,7 +154,7 @@
 		<<button "Character Creation<span class='red'>*</span>">>
 			<<displaySettings "characterSettings">>
 		<</button>>
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<<button "Feat Boosts<span class='red'>*</span> <img class='imgButton' src='img/ui/GoldCoin.gif'/>">>
 				<<displaySettings "featSettings">>
 			<</button>>
@@ -232,9 +211,9 @@
 	<<set _buttonName to "Confirm">>
 <</if>>
 <<link _buttonName>>
-	<<if ($feats.locked is true or ($cheatdisabletoggle is "t" and $rentmod gte 1)) and ($feats.soft is true or ($gamemode isnot "soft" and $alluremod gte 1)) and $maxStates lte 5>>
+	<<if ($feats.locked is true or ($cheatdisabletoggle is "t" and $rentmod gte 1)) and ($feats.soft is true or ($gamemode isnot "soft" and $alluremod gte 1)) and $options.maxStates lte 5>>
 		<<settingsExitFunction>>
-	<<elseif $maxStates lte 5>><!-- confirm cheats -->
+	<<elseif $options.maxStates lte 5>><!-- confirm cheats -->
 		<<replace #settingsExit>><<settingsExitConfirm>><</replace>>
 	<<else>><!-- confirm huge history -->
 		<<replace #settingsExit>><<settingsExitConfirmHistory>><</replace>>
@@ -271,13 +250,13 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 </span>
 <br>
 <<link "Disable the feature">>
-	<<set $maxStates to 1>>
+	<<set $options.maxStates to 1>>
 	<<replace #settingsExit>><<settingsExit>><</replace>>
 	<<displaySettings>>
 <</link>>
 <br>
 <<link "Lower the values to safer levels">>
-	<<set $maxStates to 5>>
+	<<set $options.maxStates to 5>>
 	<<replace #settingsExit>><<settingsExit>><</replace>>
 	<<displaySettings>>
 <</link>>
@@ -573,17 +552,17 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<<if StartConfig.enableImages is true>>
 		<<link "Test Colour">>
 			<<replace #test>>
-				<<if $skinColor.tanImgEnabled is "f">>
-					<<set $skinColor.tanImgEnabled to "t">>
+				<<if $options.tanImgEnabled>>
+					<<set $options.tanImgEnabled to true>>
 					<<set _skincolortemp to true>>
 				<</if>>
-				<<print '<div style="height: 30px; width: 50px; background-color: red; filter: '+skinColor($skinColor.tanImgEnabled, $skinColor.range,setup.skinColor[$skinColor.natural])+';"></div>'>>
+				<<print '<div style="height: 30px; width: 50px; background-color: red; filter: '+skinColor($options.tanImgEnabled, $skinColor.range,setup.skinColor[$skinColor.natural])+';"></div>'>>
 				<<if _skincolortemp is true>>
-					<<set $skinColor.tanImgEnabled to "f">>
+					<<set $options.tanImgEnabled to false>>
 				<</if>>
 			<</replace>>
 		<</link>> (approximate)
-		<div id="test">/*<<print '<div style="height: 30px; width: 50px; background-color: red; filter: '+skinColor($skinColor.tanImgEnabled, $skinColor.range,setup.skinColor[$skinColor.natural])+';"></div>'>>*/</div>
+		<div id="test">/*<<print '<div style="height: 30px; width: 50px; background-color: red; filter: '+skinColor($options.tanImgEnabled, $skinColor.range,setup.skinColor[$skinColor.natural])+';"></div>'>>*/</div>
 		<br>
 	<</if>>
 	<br>
@@ -1200,105 +1179,16 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 <</widget>>
 
 <<widget "generalSettings">>
-	<span class="gold">Images</span>
-	<<if StartConfig.enableImages is true>>
-		<label><div class="settingsToggleBig">
-		<<checkbox "$images" 0 1 autocheck>> Enable images
-		<div class="description">Images may not load properly on older Androids.</div>
-		<label data-target="images" data-disabledif="V.images===0"><<checkbox "$combatimages" 0 1 autocheck>> Enable combat images
-		</label></div>
-
-		<label><div class="settingsToggleBig">
-		CSS animations
-		<div><label><<checkbox "$sidebarAnimations" false true autocheck>> Sidebar animations</label></div>
-		<div><label><<checkbox "$combatAnimations" false true autocheck>> Combat animations</label></div>
-		<div class="description">Disabling may help improve performance and prevent images from loading incorrectly. Gif images will not be affected. Try disabling sidebar images first.</div>
-		</div></label>
-
-		<label><div class="settingsToggleBig">
-		<<checkbox "$bodywritingImages" false true autocheck>> Enable body-writing Images
-		<div class="description">Disabling may improve performance and potentially prevent images from not loading correctly.</div>
-		</div></label>
-
-		<label><div class="settingsToggleBig">
-		<<checkbox "$silhouettedisable" "t" "f" autocheck>> Enable NPC silhouettes
+	<<if StartConfig.enableImages is true and $debug is 1>>
+		<span class="gold">Images</span>
+		<label><div class="settingsToggleBig"><div style="display: inline-flex;">
+		Face style
+		<div style="margin-left: 1em;"><<textbox "$facestyle" $facestyle>></div></div>
+		<div class="description">This setting works only if you have installed face styles other than default.</div>
+		<<script>>jQuery(document).ready(() => { jQuery('#textbox-facestyle').css('width', '100%').css('min-width', 'unset').css('height', '0.75em'); });<</script>>
 		</div></label>
-
-		<<if $skinColor.init is false and $passage isnot "Start">>
-			<span class="gold">You can now choose your character's skin colour. Click "Test" to preview the setting on the paperdolls. Click "Confirm" when you've made your selection.</span> This can cause performance issues on some devices. Should this be an issue, the option to disable the new skin system will appear here.
-			<br>
-			<div id="skinColorDiv"><img class="" src="img/bodyRed/baseReColorTest.png"></div>
-
-			Skin colour:<br>
-			Reddish:
-			<label>Light <<radiobutton "$naturalSkinColor" "light" autocheck>></label> |
-			<label>Medium <<radiobutton "$naturalSkinColor" "medium" autocheck>></label> |
-			<label>Dark <<radiobutton "$naturalSkinColor" "dark" autocheck>></label> |
-			<label>Gyaru <<radiobutton "$naturalSkinColor" "gyaru" autocheck>> (Pale with no tan, very dark with full tan)</label>
-			<br>
-			Yellowish:
-			<label>Light <<radiobutton "$naturalSkinColor" "ylight" autocheck>></label> |
-			<label>Medium <<radiobutton "$naturalSkinColor" "ymedium" autocheck>></label> |
-			<label>Dark <<radiobutton "$naturalSkinColor" "ydark" autocheck>></label>
-			<label>Gyaru <<radiobutton "$naturalSkinColor" "ygyaru" autocheck>></label>
-			<br><br>
-			<<if $range is undefined>>
-				<<set $range to 0>>
-			<</if>>
-			<label>Initial Tan: <<numberslider "$range" 0 0 100 1>></label>
-			<br>
-			<<link "Test">>
-				<<if $range isnot undefined and $naturalSkinColor isnot undefined>>
-					<<replace #skinColorDiv>><<SkinColorImgTest $range $naturalSkinColor>><</replace>>
-				<</if>>
-			<</link>>
-
-			<br>
-			<<link [[Confirm|$passage]]>>
-				<<if $range isnot undefined and $naturalSkinColor isnot undefined>>
-					<<set $skinColor.range to $range>>
-					<<set $skinColor.natural to $naturalSkinColor>>
-					<<set $skinColor.tanningEnabled to true>>
-					<<set $skinColor.tanImgEnabled to "t">>
-					<<setSkinColorBase>>
-					<<unset $naturalSkinColor>>
-					<<unset $range>>
-				<</if>>
-			<</link>> - <span class="red">These settings can not be changed after Confirming.</span>
-		<<else>>
-			<label><div class="settingsToggleBig">
-			<<checkbox "$skinColor.tanImgEnabled" "f" "t" autocheck>> Visual representation of the player character's skin colour
-			<div class="description"><span class="pink">May hinder performance on some devices.</span></div>
-			</div></label>
-			<label><div class="settingsToggleBig">
-			<<checkbox "$skinColor.tanningEnabled" false true autocheck>> Tanning changes due to sun exposure
-			<div class="description"><span class="red">Option to disable may be removed at a later date.</span></div>
-			</div></label>
-		<</if>>
-
-		<label><div class="settingsToggleBig">
-		<<checkbox "$blinkingdisable" "t" "f" autocheck>> Animate eyes blinking
-		<div class="description">Works only if CSS animations are enabled.</div>
-		</div></label>
-		<<if $eyelidTEST is true>>
-		<label><div class="settingsToggleBig">
-		<<checkbox "$halfcloseddisable" "t" "f" autocheck>> Enable half-closed eyes graphics
-		<div class="description">Draw eyelids in sidebar as half-closed when highly aroused.</div>
-		</div></label>
-		<</if>>
-		<<if $debug is 1>>
-			<label><div class="settingsToggleBig"><div style="display: inline-flex;">
-			Face style
-			<div style="margin-left: 1em;"><<textbox "$facestyle" $facestyle>></div></div>
-			<div class="description">This setting works only if you have installed face styles other than default.</div>
-			<<script>>jQuery(document).ready(() => { jQuery('#textbox-facestyle').css('width', '100%').css('min-width', 'unset').css('height', '0.75em'); });<</script>>
-			</div></label>
-		<</if>>
-	<<else>>
-		<br>
-		Not Available
+		<br><br>
 	<</if>>
-	<br><br>
 	<span class="gold">Numbered link navigation</span>
 	<br>
 	<<if StartConfig.enableLinkNumberify is true>>
@@ -1371,25 +1261,11 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<input type="button" value="Set Zoom" onclick="zoom(undefined, true)"/>
 	<br><br>
 
-
-	<span class="gold">History depth</span><br>
-	<div class="description">Enables going back in history up to N-1 passages. Changes take effect on settings exit.<br>
-	<span class="red"><b>WARNING:</b> Will cause slowdowns. Additionally, values above 5 can exceed your localStorage quota and cause <br>
-	<b>troubles with saves</b>. Use at your own risk.</span>
-	</div>
-	<<numberslider "$maxStates" $maxStates 1 20 1 $ironmanmode>>
-	<br><br>
-
-
 	<span class="gold">Cheats menu</span>
 	<label><div class="settingsToggleBig">
-	<<if $ironmanmode is true>>
-		<<print '<input id="checkbox-autosavedisabled" name="checkbox-autosavedisabled" type="checkbox" tabindex="0" class="macro-checkbox" disabled>'>>
-		<span style="color: #7e7e7e;">Enable cheats</span>
-	<<else>>
-		<<checkbox "$cheatdisabletoggle" "t" "f" autocheck>>
-		Enable cheats
-	<</if>>
+	<label data-disabledif="V.ironmanmode===true">
+		<<checkbox "$cheatdisabletoggle" "t" "f" autocheck>> Enable cheats
+	</label>
 	<div class="description">Button shows in sidebar. <span class="red">Leaving the settings with cheats enabled will prevent you from earning feats in a save.</span></div>
 	</div></label>
 	<br><br>
@@ -1398,7 +1274,7 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<<if version.major gt 2 or version.minor gt 29>>
 		<<link [["Character Viewer"|Clothes Testing]]>>
 			<<set $lastPassage to $passage>>
-			<<set $gameTanImgSetting to clone($skinColor.tanImgEnabled)>>
+			<<set $gameTanImgSetting to clone($options.tanImgEnabled)>>
 		<</link>>
 		- This will allow you to have a play with the character sprites.
 		<br>
diff --git a/game/base-system/skinColor.twee b/game/base-system/skinColor.twee
index 1975a9dd39..be647f117d 100644
--- a/game/base-system/skinColor.twee
+++ b/game/base-system/skinColor.twee
@@ -3,8 +3,6 @@
 	<<if $skinColor isnot undefined>>
 		<<set _natural to $skinColor.natural>>
 		<<set _init to $skinColor.init>>
-		<<set _tanning to $skinColor.tanningEnabled>>
-		<<set _enable to $skinColor.tanImgEnabled>>
 	<<else>>
 		<<set _natural to "light">>
 		<<set _init to false>>
@@ -15,8 +13,6 @@
 		"tanLoc":["body", "breasts", "penis", "swimshorts", "swimsuitTop", "swimsuitBottom", "bikiniTop", "bikiniBottom", "tshirt"],
 		"natural": _natural,
 		"init": _init,
-		"tanningEnabled": _tanning,
-		"tanImgEnabled": _enable,
 		"range": 0,
 		"current": {
 			"test": "",
@@ -49,8 +45,6 @@
 		"tanLoc":["body", "breasts", "penis", "swimshorts", "swimsuitTop", "swimsuitBottom", "bikiniTop", "bikiniBottom", "tshirt"],
 		"natural": null,
 		"init": false,
-		"tanningEnabled": false,
-		"tanImgEnabled": "f",
 		"range": 0,
 		"current": {
 			"test": "",
@@ -92,28 +86,28 @@
 
 			<<for _i to 0; _i lt $skinColor.tanLoc.length; _i++>>
 				<<set $skinColor.tanValues.push($skinColor.range)>>
-				<<set $skinColor.current[$skinColor.tanLoc[_i]] to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+				<<set $skinColor.current[$skinColor.tanLoc[_i]] to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 			<</for>>
-			<<set $skinColor.current.mouth to skinColor($skinColor.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
+			<<set $skinColor.current.mouth to skinColor($options.tanImgEnabled, $skinColor.range,$skinColor.overwrite)>>
 		<</if>>
 	<</if>>
 <</widget>>
 
 <<widget "SkinColorImgTest">>
 
-<<if $skinColor.tanImgEnabled is "f">>
-	<<set $skinColor.tanImgEnabled to "t">>
+<<if !$options.tanImgEnabled>>
+	<<set $options.tanImgEnabled to true>>
 	<<set _skincolortemp to true>>
 <</if>>
-<<print '<img class="" src="img/bodyRed/baseReColorTest.png" style="filter:'+skinColor($skinColor.tanImgEnabled, $range,setup.skinColor[$naturalSkinColor])+'">'>>
+<<print '<img class="" src="img/bodyRed/baseReColorTest.png" style="filter:'+skinColor($options.tanImgEnabled, $range,setup.skinColor[$naturalSkinColor])+'">'>>
 <<if _skincolortemp is true>>
-	<<set $skinColor.tanImgEnabled to "f">>
+	<<set $options.tanImgEnabled to false>>
 <</if>>
 
 <</widget>>
 
 <<widget "tanned">>
-<<if $skinColor.tanningEnabled is true>>
+<<if $options.tanningEnabled is true>>
 	<<set _coverage to [0,0,0,0,0,0,0,0,0]>>
 	<<if _args[1] is "ignoreCoverage">>
 		<<set _coverage to [0,0,0,0,0,0,0,0,0]>>
@@ -130,12 +124,12 @@
 		<<if _coverage[_i] is 0>>
 			<<set _tanLoc to $skinColor.tanLoc[_i]>>
 			<<set $skinColor.tanValues[_i] to Math.clamp(($skinColor.tanValues[_i] + _tanChange).toFixed(1), 0, 100)>>
-			<<set $skinColor.current[_tanLoc] to skinColor($skinColor.tanImgEnabled, $skinColor.tanValues[_i],$skinColor.overwrite)>>
+			<<set $skinColor.current[_tanLoc] to skinColor($options.tanImgEnabled, $skinColor.tanValues[_i],$skinColor.overwrite)>>
 		<</if>>
 	<</for>>
-	<<set $skinColor.current.mouth to skinColor($skinColor.tanImgEnabled, $skinColor.tanValues[0],$skinColor.overwrite)>>
+	<<set $skinColor.current.mouth to skinColor($options.tanImgEnabled, $skinColor.tanValues[0],$skinColor.overwrite)>>
 <</if>>
-<<if $skinColor.tanningEnabled is false and $skinColor.tanImgEnabled is "f">>
+<<if $options.tanningEnabled is false and !$options.tanImgEnabled>>
 	<<set $skinColor.current to {
 		"test": "",
 		"body": "",
@@ -150,11 +144,11 @@
 		"mouth": ""
 	}>>
 <</if>>
-<<if $skinColor.tanningEnabled is false and $skinColor.tanImgEnabled is "t">>
+<<if $options.tanningEnabled is false and $options.tanImgEnabled>>
 	<<for _s to 0; _s lt $skinColor.tanLoc.length; _s++>>
-		<<set $skinColor.current[$skinColor.tanLoc[_s]] to skinColor($skinColor.tanImgEnabled, $skinColor.tanValues[_s],$skinColor.overwrite)>>
+		<<set $skinColor.current[$skinColor.tanLoc[_s]] to skinColor($options.tanImgEnabled, $skinColor.tanValues[_s],$skinColor.overwrite)>>
 	<</for>>
-	<<set $skinColor.current.mouth to skinColor($skinColor.tanImgEnabled, $skinColor.tanValues[0],$skinColor.overwrite)>>
+	<<set $skinColor.current.mouth to skinColor($options.tanImgEnabled, $skinColor.tanValues[0],$skinColor.overwrite)>>
 <</if>>
 <</widget>>
 
diff --git a/game/base-system/tending.twee b/game/base-system/tending.twee
index 332e9ac357..d3a9fcca90 100644
--- a/game/base-system/tending.twee
+++ b/game/base-system/tending.twee
@@ -124,7 +124,7 @@
 				<<if $leftarm is "bound" and $rightarm is "bound">>
 					<span class="red">Can't pick when your arms are bound.</span>
 				<<else>>
-					<<if $images is 1 and $_plantedPlant.icon>>
+					<<if $options.images is 1 and $_plantedPlant.icon>>
 						<img class="tending_icon" @src="`img/misc/icon/tending/` + $_plantedPlant.icon">
 					<</if>>
 					<<link "Pick ($_timeStr)" $passage>><<pass _pass>><<tending_harvest _plantbed>><<clear_plot _plantbed>><</link>>
@@ -254,7 +254,7 @@
 				<</switch>>
 				<<set $_timeString to getTimeString(_passTime)>>
 				<<capture _passTime _plantbed _plantType>>
-					<<if $images is 1 and $_plant.icon>>
+					<<if $options.images is 1 and $_plant.icon>>
 						<img class="tending_icon" @src="`img/misc/icon/tending/` + $_plant.icon">
 					<</if>>
 					<<link "Plant $_plant.plural ($_timeString)" $passage>><<pass _passTime>><<run plantSeedsInPlot(_plantbed, _plantType)>><</link>>
@@ -486,12 +486,12 @@
 	You pick
 	<<if _tending_amount is 1>>
 		a 
-		<<if $images is 1 and setup.plants[$_type].icon>>
+		<<if $options.images is 1 and setup.plants[$_type].icon>>
 			<img class="tending_icon" @src="`img/misc/icon/tending/` + setup.plants[$_type].icon">
 		<</if>>
 		<<print setup.plants[$_type].name.replace(/_/g," ")>>.
 	<<else>>
-		<<if $images is 1 and setup.plants[$_type].icon>>
+		<<if $options.images is 1 and setup.plants[$_type].icon>>
 			<img class="tending_icon" @src="`img/misc/icon/tending/` + setup.plants[$_type].icon">
 		<</if>>
 		<<number _tending_amount>> <<print setup.plants[$_type].plural>>.
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index 0b0f5a6956..2265dc8570 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -1106,7 +1106,7 @@
 <<else>>
 	No effect on warmth.
 <</if>>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	(<span class="cold-resist-icon">_args[0]</span>)
 <<else>>
 	(Warmth rating: _args[0])
@@ -5779,7 +5779,7 @@ School finishes on the first Monday of December.
 /* Argument 0 is the npc, argument 1 is their virginity. */
 <<widget "NPCvirginitywarning">>
 <<if $NPCNameList.indexOf(_args[0]) >= 0 and $NPCName[$NPCNameList.indexOf(_args[0])].virginity[_args[1]] is true and $statdisable is "f">>
-	<<if $combatControls.includes("ists")>>
+	<<if $options.combatControls.includes("ists")>>
 		<br>
 	<</if>>
 	<<switch _args[1]>>
diff --git a/game/base-system/widgets.js b/game/base-system/widgets.js
index f98143c601..51ef0e2a54 100644
--- a/game/base-system/widgets.js
+++ b/game/base-system/widgets.js
@@ -333,17 +333,17 @@ function exposedcheck() {
 DefineMacro("exposedcheck", exposedcheck);
 
 function updatehistorycontrols(){
-	if (V.maxStates === undefined || V.maxStates > 20) {
+	if (V.options.maxStates === undefined || V.options.maxStates > 20) {
 		/* initiate new variable based on engine config and limit it to 20 */
-		V.maxStates = Math.clamp(1, 20, Config.history.maxStates);
+		V.options.maxStates = Math.clamp(1, 20, Config.history.maxStates);
 	}
-	if (V.maxStates == 1) {
+	if (V.options.maxStates == 1) {
 		/* when disabled, irreversibly delete history controls the way sugarcube intended */
 		Config.history.maxStates = 1;
 		jQuery('#ui-bar-history').remove();
 	} else {
 		/* set actual maxStates in accordance with our new variable */
-		Config.history.maxStates = V.maxStates;
+		Config.history.maxStates = V.options.maxStates;
 		/* ensure that controls are enabled so sugarcube won't destroy them on reload */
 		Config.history.controls = true;
 		/* if irreversibly deleted, restore #ui-bar-history from oblivion and pop it after #ui-bar-toggle */
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 631ad275fa..9f2a52e3c0 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -1119,9 +1119,9 @@
 
 <<widget "tirednesscaption">>
 <div id="tirednesscaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Fatigue:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $tiredness gte C.tiredness.max>>
 				<span class="red">You are exhausted.</span>
 			<<elseif $tiredness gte (C.tiredness.max / 5) * 4>>
@@ -1145,7 +1145,7 @@
 	<</if>>
 
 	<<set $tiredness = Math.clamp($tiredness, 0, C.tiredness.max)>>
-	<<set _showCaptionText to !$showCaptionText>>
+	<<set _showCaptionText to !$options.showCaptionText>>
 	<<statbar $tiredness `C.tiredness.max` _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
@@ -1171,9 +1171,9 @@
 
 <<widget "stresscaption">>
 <div id="stresscaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Stress:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $stress gte $stressmax>>
 				<span class="red">You are overwhelmed!</span>
 			<<elseif $stress gte ($stressmax / 5) * 4>>
@@ -1192,7 +1192,7 @@
 		<</if>>
 	</div>
 	<<set $stress = Math.clamp($stress, 0, $stressmax)>>
-	<<set _showCaptionText to !$showCaptionText>>
+	<<set _showCaptionText to !$options.showCaptionText>>
 	<<statbar $stress $stressmax _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
@@ -1200,9 +1200,9 @@
 
 <<widget "traumacaption">>
 <div id="traumacaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Trauma:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $trauma gte $traumamax>>
 				<span class="red">You feel numb.</span>
 			<<elseif $trauma gte ($traumamax / 5) * 4>>
@@ -1220,7 +1220,7 @@
 			<</if>>
 		<</if>>
 	</div>
-	<<set _showCaptionText to !$showCaptionText>>
+	<<set _showCaptionText to !$options.showCaptionText>>
 	<<statbar $trauma $traumamax _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
@@ -1228,9 +1228,9 @@
 
 <<widget "innocencecaption">>
 <div id="innocencecaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Innocence:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $awareness gte 0>>
 				<span class="red">You understand.</span>
 			<<elseif $awareness gt -40>>
@@ -1248,7 +1248,7 @@
 			<</if>>
 		<</if>>
 	</div>
-	<<set _showCaptionText to !$showCaptionText>>
+	<<set _showCaptionText to !$options.showCaptionText>>
 	<<statbarinverted $awareness -200 _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
@@ -1256,9 +1256,9 @@
 
 <<widget "controlcaption">>
 <div id="controlcaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Control:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $possessed>>
 				<<if $control gte $controlmax>>
 					<span class="green">You are in control.</span>
@@ -1294,7 +1294,7 @@
 			<</if>>
 		<</if>>
 	</div>
-	<<set _showCaptionText to !$showCaptionText>>
+	<<set _showCaptionText to !$options.showCaptionText>>
 	<<statbarinverted $control $controlmax _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
@@ -1302,9 +1302,9 @@
 
 <<widget "arousalcaption">>
 <div id="arousalcaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Arousal:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $arousal gte $arousalmax>>
 				<span class="red">You shake with arousal.</span>
 			<<elseif $arousal gte ($arousalmax / 5) * 4>>
@@ -1322,7 +1322,7 @@
 			<</if>>
 		<</if>>
 	</div>
-	<<set _showCaptionText to !$showCaptionText>>
+	<<set _showCaptionText to !$options.showCaptionText>>
 	<<statbar $arousal $arousalmax _showCaptionText>>
 	<div style="clear:both;"></div>
 </div>
@@ -1330,9 +1330,9 @@
 
 <<widget "allurecaption">>
 <div id="allurecaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Allure:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $allure gte (6000 * $alluremod)>><span class="red">You look like you need to be ravaged.</span>
 			<<elseif $allure gte (4000 * $alluremod)>><span class="pink">You look perverted.</span>
 			<<elseif $allure gte (3000 * $alluremod)>><span class="purple">You look lewd.</span>
@@ -1343,7 +1343,7 @@
 			<</if>>
 		<</if>>
 	</div>
-	<div @class="($showCaptionText is true ? 'meter' : 'rightMeter')">
+	<div @class="($options.showCaptionText is true ? 'meter' : 'rightMeter')">
 		<<set $percent=Math.floor(($allure/(8000 * $alluremod))*100)>>
 		<<if $allure gte (6000 * $alluremod)>>
 		<<print '<div class="redbar" style="width:' + $percent + '%"></div>'>>
@@ -1381,10 +1381,10 @@
 <<widget "oxygencaption">>
 <div id="oxygencaption">
 	<<if _args[0] is true>>
-		<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+		<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 			Air:
 		</div>
-		<<set _showCaptionText to !$showCaptionText>>
+		<<set _showCaptionText to !$options.showCaptionText>>
 	<<else>>
 		<<unset _showCaptionText>>
 	<</if>>
@@ -1431,8 +1431,8 @@
 		<<set $_barWidth to `width:${$_percent}%`>>
 
 		<div id="drunkcaption">
-			<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
-				<<if $showCaptionText is true>>
+			<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
+				<<if $options.showCaptionText is true>>
 					<<set $_drunk_level to Math.clamp(Math.floor($drunk / 120), 0, 4) * 120>>
 					<<switch $_drunk_level>>
 						<<case 0>><span @class="$_colour">You are woozy.</span>
@@ -1445,7 +1445,7 @@
 					Drunk:
 				<</if>>
 			</div>
-			<div @class="($showCaptionText is true ? 'meter' : 'rightMeter')">
+			<div @class="($options.showCaptionText is true ? 'meter' : 'rightMeter')">
 				<div @class="$_barColour" @style="$_barWidth"></div>
 			</div>
 			<div style="clear:both;"></div>
@@ -1461,14 +1461,14 @@
 		<<set $_barWidth to `width:${$_percent}%`>>
 
 		<div id="druggedcaption">
-			<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
-				<<if $showCaptionText is true>>
+			<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
+				<<if $options.showCaptionText is true>>
 					<span class="pink">A lewd warmth fills you</span>
 				<<else>>
 					Drugged:
 				<</if>>
 			</div>
-			<div @class="($showCaptionText is true ? 'meter' : 'rightMeter')">
+			<div @class="($options.showCaptionText is true ? 'meter' : 'rightMeter')">
 				<div @class="$_barColour" @style="$_barWidth"></div>
 			</div>
 			<div style="clear:both;"></div>
@@ -1484,14 +1484,14 @@
 		<<set $_barWidth to `width:${$_percent}%`>>
 
 		<div id="hallucinogencaption">
-			<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
-				<<if $showCaptionText is true>>
+			<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
+				<<if $options.showCaptionText is true>>
 					<span class="purple">Your perception is altered</span>
 				<<else>>
 					Hallucinogen:
 				<</if>>
 			</div>
-			<div @class="($showCaptionText is true ? 'meter' : 'rightMeter')">
+			<div @class="($options.showCaptionText is true ? 'meter' : 'rightMeter')">
 				<div @class="$_barColour" @style="$_barWidth"></div>
 			</div>
 			<div style="clear:both;"></div>
@@ -1501,9 +1501,9 @@
 
 <<widget "paincaption">>
 <div id="paincaption">
-	<div @class="($showCaptionText is true ? '' : 'rightMeterText')">
+	<div @class="($options.showCaptionText is true ? '' : 'rightMeterText')">
 		Pain:
-		<<if $showCaptionText is true>>
+		<<if $options.showCaptionText is true>>
 			<<if $pain gte 100 and $willpowerpain is 0>><span class="red">You sob uncontrollably.</span>
 			<<elseif $pain gte 80>><span class="pink">You cry and whimper.</span>
 			<<elseif $pain gte 60>><span class="purple">You are crying.</span>
@@ -1514,7 +1514,7 @@
 			<</if>>
 		<</if>>
 	</div>
-	<div @class="($showCaptionText is true ? 'meter' : 'rightMeter')">
+	<div @class="($options.showCaptionText is true ? 'meter' : 'rightMeter')">
 		<<set $percent=Math.floor(($pain/100)*100)>>
 		<<if $pain gte 100 and $willpowerpain is 0>>
 		<<print '<div class="redbar" style="width:' + $percent + '%"></div>'>>
@@ -1674,7 +1674,7 @@
 		<<set _weather_display to "normal">>
 	<</if>>
 
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<if $daystate is "day">>
 			<<if $location is "tentworld">>
 				<img id="daystate" src="img/misc/tentskyday.png">
@@ -3256,7 +3256,7 @@ $mouthstate is "tentacledeep">>
 
 <<widget "textmap">>
 
-<<if $map.movement is true and !$possessed>>
+<<if $options.mapMovement is true and !$possessed>>
 __Map__<br>
 |.....<a class="no-numberify mapmove" onclick="mapMove('Barb Street')" title="Barb Street">Ba</a> &#9866; <a class="no&#9866;numberify mapmove" onclick="mapMove('Cliff Street')" title="Cliff Street">Cl</a> &#9866; <a class="no&#9866;numberify mapmove" onclick="mapMove('Starfish Street')" title="Starfish Street">St</a> &#9866; <a class="no&#9866;numberify mapmove" onclick="mapMove('Mer Street')" title="Mer Street">Me</a><br>
 |..╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲<br>
@@ -3276,7 +3276,7 @@ __Map__<br>
 
 <<widget map>>
 	<<set $map.location to _args[0]>>
-	<<if $images is 1 and $map.movement is true and $map.legacy isnot true and !$possessed>>
+	<<if $options.images is 1 and $options.mapMovement is true and $options.mapLegacy isnot true and !$possessed>>
 		<<set _boxLocations to [
 			{ x: 1,		y: 46}, /*Domus				*/
 			{ x: 38,	y: 9},	/*Barb				*/
@@ -3304,7 +3304,7 @@ __Map__<br>
 
 			<<for _i to 0; _i lt $map.arrayList.length; _i++>>
 				<<set _canMoveTo = $debug || $map.available[$passage].includes($map.arrayList[_i])>>
-				<<set _showMarker = $debug || ($map.markers && (_canMoveTo || $passage is $map.arrayList[_i]))>>
+				<<set _showMarker = $debug || ($options.mapMarkers && (_canMoveTo || $passage is $map.arrayList[_i]))>>
 
 				<a class="mapmove"
 						@onclick="'mapMove(V.map.arrayList[' + _i + ']);'"
@@ -3321,13 +3321,13 @@ __Map__<br>
 			<</for>>
 		<</svg>>
 
-	<<elseif $images is 1 and $map.legacy isnot true>>
+	<<elseif $options.images is 1 and $options.mapLegacy isnot true>>
 		<svg width="260" height="130">
 			<image x="2" xlink:href="img/misc/map.png"/>
 			<image x="2" @xlink:href="'img/misc/maparrow'+$map.location+'.png'"/>
 		</svg>
-	<<elseif $images is 1>>
-		<<if $images is 1 and $map.movement is true and !$possessed>>
+	<<elseif $options.images is 1>>
+		<<if $options.mapMovement is true and !$possessed>>
 			<!-- Image Map Generated by http://www.image-map.net/ -->
 			<map id="town-image-map" name="town-image-map">
 				<area class="no-numberify" alt="Barb Street" title="Barb Street" coords="62,20,39,42" shape="rect" onclick="mapMove('Barb Street')">
@@ -3427,7 +3427,7 @@ __Map__<br>
 <</widget>>
 
 <<widget "statbaricons">>
-	<<if $images is 1 and _args[0]>>
+	<<if $options.images is 1 and _args[0]>>
 		<<if _args[1] gte 1>>
 			<img id="statbar" @src="'img/ui/' + _args[0] + '.png'">
 		<<elseif _args[2] gte 1>>
@@ -3574,7 +3574,7 @@ __Map__<br>
 
 	<div class="characteristic-box">
 		<div class="characteristic-top-line">
-			<<if $images is 1 and _config.icon>>
+			<<if $options.images is 1 and _config.icon>>
 				<img class="characteristic-icon" @src="'img/' + _config.icon + '.png'" />
 			<</if>>
 			<span class="characteristic-title">_config.name<<characteristic-box-modifier `clone(_config.modifier)` `clone(_config.modTypes)` `clone(_config.name)`>></span>
@@ -3689,7 +3689,7 @@ __Map__<br>
 	<div class="relation-box" @style="(_boxConfig.style || '')">
 		<<if _boxConfig.name>>
 			<div class="relation-top-line">
-				<<if $images and _boxConfig.icon>>
+				<<if $options.images and _boxConfig.icon>>
 						<img class="relation-icon" @src="_boxConfig.icon" />
 				<</if>>
 				<span class="relation-name">_boxConfig.name</span>
@@ -3804,7 +3804,7 @@ __Map__<br>
 				<div class="relation-description">
 					<<npcrelationship _npcData.nam>>
 				</div>
-				<div @class="'relation-stat-list' + ($images ? '' : ' no-images')">
+				<div @class="'relation-stat-list' + ($options.images ? '' : ' no-images')">
 					<<for _j = 0; _j lt _importantNpcStats.length; _j++>>
 						<<if _npcData[_importantNpcStats[_j]] gt 0 and _checkRequirements(_importantNpcStats[_j])>>
 							<<relation-box-stat _getStatConfig(_importantNpcStats[_j]) true>>
@@ -3846,7 +3846,7 @@ __Map__<br>
 		<<if _important>>
 			<label>_config.name</label>
 		<</if>>
-		<<if $images>>
+		<<if $options.images>>
 			<div class="relation-stat">
 				<span @class="'relation-stat-icon ' + (_config.iconOrientation || 'horizontal')">
 					<img class="active-icon-img" @src="_config.activeIcon">
diff --git a/game/overworld-plains/loc-estate/cards_widgets.twee b/game/overworld-plains/loc-estate/cards_widgets.twee
index 775d4fa724..92ba830c00 100644
--- a/game/overworld-plains/loc-estate/cards_widgets.twee
+++ b/game/overworld-plains/loc-estate/cards_widgets.twee
@@ -1108,7 +1108,6 @@ One of the guards goes into the barn and comes back with a collar and chain, whi
 
 <<widget "blackjackHelp">>
 <<set _consts__max_marked to 8>>
-<h3>Blackjack Guide</h3>
 <ul>
 	<li>Your goal is to beat the dealer in having a higher score that never goes above 21.</li>
 	<li>Cards are valued from 2 to 11. Jack, Queen and King are worth 10 each, Ace is worth either 1 or 11, whichever is more favourable.</li>
diff --git a/game/overworld-plains/loc-farm/widgets.twee b/game/overworld-plains/loc-farm/widgets.twee
index 283b8fb4e2..69b2737b21 100644
--- a/game/overworld-plains/loc-farm/widgets.twee
+++ b/game/overworld-plains/loc-farm/widgets.twee
@@ -2301,7 +2301,7 @@
 	<</if>>
 	<<prop haybale semen penis_pump milk breast_pump>>
 <</if>>
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<br><br>
 	<<timed 100ms>>
 		<<combatimg>>
diff --git a/game/overworld-plains/loc-livestock/widgets.twee b/game/overworld-plains/loc-livestock/widgets.twee
index 3e6718e27c..9dd3bc84f4 100644
--- a/game/overworld-plains/loc-livestock/widgets.twee
+++ b/game/overworld-plains/loc-livestock/widgets.twee
@@ -275,7 +275,7 @@ You overhear two farmhands talking behind the fence.
 <</widget>>
 
 <<widget "milking_img">>
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<machine_init>>
 	<<if $player.penisExist and $breastfeedingdisable is "f">>
 		<<if _args[0]>>
diff --git a/game/overworld-town/loc-alley/commercial.twee b/game/overworld-town/loc-alley/commercial.twee
index 9de4272798..b59d3ebddf 100644
--- a/game/overworld-town/loc-alley/commercial.twee
+++ b/game/overworld-town/loc-alley/commercial.twee
@@ -29,7 +29,7 @@ There's a ladder to your left, you think it will take you to the rooftops.
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "commercial">>
 			<br>
 		<</if>>
@@ -70,7 +70,7 @@ There's a ladder to your left, you think it will take you to the rooftops.
 		<</if>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "commercial">>
 		<</if>>
diff --git a/game/overworld-town/loc-alley/industrial.twee b/game/overworld-town/loc-alley/industrial.twee
index f9479f8960..c8250f1336 100644
--- a/game/overworld-town/loc-alley/industrial.twee
+++ b/game/overworld-town/loc-alley/industrial.twee
@@ -24,7 +24,7 @@ There's a ladder to your right, you think it will take you to the rooftops. The
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "industrial">>
 			<br>
 		<</if>>
@@ -52,7 +52,7 @@ There's a ladder to your right, you think it will take you to the rooftops. The
 		<</if>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "industrial">>
 		<</if>>
diff --git a/game/overworld-town/loc-alley/park.twee b/game/overworld-town/loc-alley/park.twee
index 7bf8a1e55e..1e040d2802 100644
--- a/game/overworld-town/loc-alley/park.twee
+++ b/game/overworld-town/loc-alley/park.twee
@@ -137,7 +137,7 @@ Tulips grow in great patches near the riverbank.
 		<<link [[Next|Park]]>><<set $eventskip to 1>><</link>>
 		<br>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "park">>
 			<br>
 		<</if>>
@@ -241,7 +241,7 @@ Tulips grow in great patches near the riverbank.
 			<br>
 		<</if>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "park">>
 		<</if>>
diff --git a/game/overworld-town/loc-alley/residential.twee b/game/overworld-town/loc-alley/residential.twee
index 11a995102b..8d07cbbc88 100644
--- a/game/overworld-town/loc-alley/residential.twee
+++ b/game/overworld-town/loc-alley/residential.twee
@@ -27,7 +27,7 @@ Your home is nearby.
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "residential">>
 			<br>
 		<</if>>
@@ -74,7 +74,7 @@ Your home is nearby.
 		<</if>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "residential">>
 		<</if>>
diff --git a/game/overworld-town/loc-brothel/main.twee b/game/overworld-town/loc-brothel/main.twee
index 5e3b0970a3..b029fe5a11 100644
--- a/game/overworld-town/loc-brothel/main.twee
+++ b/game/overworld-town/loc-brothel/main.twee
@@ -1553,7 +1553,7 @@ You wash until you're squeaky clean.<<wash>>
 <span class="red">You hear a crash outside, followed by shouts and screams.</span> The <<person>> freezes.
 <<set $enemyarousal to 0>><<set $enemytrust to -200>>
 <<set $enemyhealth to ($enemyhealthmax / 5) * 4>><<set $enemyanger to ($enemyangermax / 5) * 2>>
-<<if $images is 1 and $combatimages is 1>>
+<<if $options.images is 1 and $options.combatImages is 1>>
 	<<timed 100ms>>
 		<br><br><br>
 		<<combatimg>>
diff --git a/game/overworld-town/loc-cafe/main.twee b/game/overworld-town/loc-cafe/main.twee
index 61aade5647..bc9c1d6666 100644
--- a/game/overworld-town/loc-cafe/main.twee
+++ b/game/overworld-town/loc-cafe/main.twee
@@ -175,7 +175,7 @@ You are in the Ocean Breeze Cafe.
 	<<if $money gte 300>>
 		<<if ndef $milkshake>><<set $milkshake to 0>><</if>>
 		<<if $milkshake lt 2>>
-			<<milkshakeicon>><<if $images is 1>><</if>><<link [[Buy milkshake to go (0:02 £3)|Ocean Breeze]]>><<set $money -= 300>> <<set $milkshake +=1>> <<pass 2>><</link>>
+			<<milkshakeicon>><<link [[Buy milkshake to go (0:02 £3)|Ocean Breeze]]>><<set $money -= 300>> <<set $milkshake +=1>> <<pass 2>><</link>>
 			<br>
 		<</if>>
 	<</if>>
diff --git a/game/overworld-town/loc-cafe/widgets.twee b/game/overworld-town/loc-cafe/widgets.twee
index a83460dbd4..ac6d39d505 100644
--- a/game/overworld-town/loc-cafe/widgets.twee
+++ b/game/overworld-town/loc-cafe/widgets.twee
@@ -164,7 +164,7 @@ Suspicion:
 	<<print '<div class="redbar" style="width:' + $percent + '%"></div>'>>
 </div>
 <br><br>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<<set _buns_sold to Math.clamp(_buns_sold, 0, 200)>>
 	<<for _i to 0; _i lt _buns_sold; _i++>>
 		<<icon "food_creambun.png">>
diff --git a/game/overworld-town/loc-market/widgets.twee b/game/overworld-town/loc-market/widgets.twee
index 247db82e3d..87bfa56978 100644
--- a/game/overworld-town/loc-market/widgets.twee
+++ b/game/overworld-town/loc-market/widgets.twee
@@ -96,7 +96,7 @@
 		<<set _canmath to 0>>
 <</switch>>
 
-<<set _mobile to ($useNarrowMarket and _canmath gt 4)>>
+<<set _mobile to ($options.useNarrowMarket and _canmath gt 4)>>
 
 <!-- <<for _mobile to 0; _mobile lt 2; _mobile++>><<for _canmath to 0; _canmath lt 7; _canmath++>><center>---mobile:_mobile math:_canmath---</center> -->
 
@@ -233,7 +233,7 @@ total colums			:	-		-		-		2		3		5		6
 	<<for _t to 0; _t lt _plant_keys.length; _t++>>
 		<<if $stall_stats[_plant_keys[_t]].inventory.amount gt 0>>
 			<<if _first>>
-				<<if $images is 1 and $plants[_plant_keys[_t]].icon>>
+				<<if $options.images is 1 and $plants[_plant_keys[_t]].icon>>
 					<img class="tending_icon" @src="`img/misc/icon/tending/` + $plants[_plant_keys[_t]].icon">
 				<</if>>
 				<span class="gold"><<print $stall_stats[_plant_keys[_t]].inventory.amount>></span>
@@ -241,7 +241,7 @@ total colums			:	-		-		-		2		3		5		6
 				(<<printmoney _plant_value>> each)
 			<<else>>
 				|
-				<<if $images is 1 and $plants[_plant_keys[_t]].icon>>
+				<<if $options.images is 1 and $plants[_plant_keys[_t]].icon>>
 					<img class="tending_icon" @src="`img/misc/icon/tending/` + $plants[_plant_keys[_t]].icon">
 				<</if>>
 				<span class="gold"><<print $stall_stats[_plant_keys[_t]].inventory.amount>></span>
diff --git a/game/overworld-town/loc-prison/punishment.twee b/game/overworld-town/loc-prison/punishment.twee
index 04a01a1d5f..dd47014124 100644
--- a/game/overworld-town/loc-prison/punishment.twee
+++ b/game/overworld-town/loc-prison/punishment.twee
@@ -68,7 +68,7 @@ Writing is engraved on its surface.
 
 <div id="die_text">
 	<span id="die_1">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_roll.gif">
 		<<else>>
 			?
@@ -76,7 +76,7 @@ Writing is engraved on its surface.
 	</span>
 	+
 	<span id="die_2">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_roll.gif">
 		<<else>>
 			?
@@ -95,7 +95,7 @@ Writing is engraved on its surface.
 
 <<timed 2s>>
 	<<replace "#die_1">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_' + _die_1 + '.png'">
 	<<else>>
 		_die_1
@@ -104,7 +104,7 @@ Writing is engraved on its surface.
 <</timed>>
 <<timed 3s>>
 	<<replace "#die_2">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_' + _die_2 + '.png'">
 	<<else>>
 		_die_2
diff --git a/game/overworld-town/loc-prison/widgets.twee b/game/overworld-town/loc-prison/widgets.twee
index ab1631cd52..fb171f34ef 100644
--- a/game/overworld-town/loc-prison/widgets.twee
+++ b/game/overworld-town/loc-prison/widgets.twee
@@ -1590,7 +1590,7 @@ You have the inmates' attention. A thought flashes through your mind. A desire f
 <</widget>>
 
 <<widget "prison_map">>
-<<if $images is 1>>
+<<if $options.images is 1>>
 	<br>
 	<div id="prison_map">
 		<<if $season is "winter">>
diff --git a/game/overworld-town/loc-prison/work.twee b/game/overworld-town/loc-prison/work.twee
index 2e6355bf56..d184ea82b6 100644
--- a/game/overworld-town/loc-prison/work.twee
+++ b/game/overworld-town/loc-prison/work.twee
@@ -520,7 +520,7 @@ You step away from the <<person>>. <<He>> takes the hint, though gives your <<bo
 
 <div id="die_text">
 	<span id="die_1">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_roll.gif">
 		<<else>>
 			?
@@ -528,7 +528,7 @@ You step away from the <<person>>. <<He>> takes the hint, though gives your <<bo
 	</span>
 	+
 	<span id="die_2">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_roll.gif">
 		<<else>>
 			?
@@ -547,7 +547,7 @@ You step away from the <<person>>. <<He>> takes the hint, though gives your <<bo
 
 <<timed 1s>>
 	<<replace "#die_1">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_' + _die_1 + '.png'">
 	<<else>>
 		_die_1
@@ -556,7 +556,7 @@ You step away from the <<person>>. <<He>> takes the hint, though gives your <<bo
 <</timed>>
 <<timed 2s>>
 	<<replace "#die_2">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_' + _die_2 + '.png'">
 	<<else>>
 		_die_2
@@ -585,7 +585,7 @@ Your turn.
 
 <div id="die_text">
 	<span id="die_1">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_roll.gif">
 		<<else>>
 			?
@@ -593,7 +593,7 @@ Your turn.
 	</span>
 	+
 	<span id="die_2">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_roll.gif">
 		<<else>>
 			?
@@ -612,7 +612,7 @@ Your turn.
 
 <<timed 1s>>
 	<<replace "#die_1">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_' + _die_1 + '.png'">
 	<<else>>
 		_die_1
@@ -621,7 +621,7 @@ Your turn.
 <</timed>>
 <<timed 2s>>
 	<<replace "#die_2">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_' + _die_2 + '.png'">
 	<<else>>
 		_die_2
diff --git a/game/overworld-town/loc-shop/clothing-v2.twee b/game/overworld-town/loc-shop/clothing-v2.twee
index 54cb9cc775..f65f75762f 100644
--- a/game/overworld-town/loc-shop/clothing-v2.twee
+++ b/game/overworld-town/loc-shop/clothing-v2.twee
@@ -177,7 +177,7 @@
 
 	<!-- Filters -->
 	<div class="filters-button no-numberify div-link">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<span class="button-icon"><img src="img/misc/icon/filter.png"></span>
 		<<else>>
 			Filters
@@ -194,7 +194,7 @@
 
 	<!-- Options -->
 	<div class="clothingshop-options-button no-numberify div-link">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<span class="button-icon"><img src="img/misc/icon/options.png"></span>
 		<<else>>
 			Opt.
@@ -212,7 +212,7 @@
 	<!-- Help / Legend button -->
 	<<if !$shopDefaults.noHelp>>
 		<div class="shop-legend-button no-numberify div-link">
-			<<if $images is 1>>
+			<<if $options.images is 1>>
 				<span class="button-icon"><img src="img/misc/icon/help.png"></span>
 			<<else>>
 				Help
@@ -274,7 +274,7 @@
 			<div class="clothing-item div-link">
 				<!-- Clothing icon -->
 				<div @class="'clothing-icon ' + _compact">
-					<<if _locked and $images is 1>>
+					<<if _locked and $options.images is 1>>
 						<img src="img/misc/icon/lock.png" class="clothing-locked">
 					<<else>>
 						<<if _item.colour_options.length > 0>>
@@ -308,7 +308,7 @@
 										<div class="female"></div>
 									<</if>>
 								<<else>>
-									<<if $images is 1>>
+									<<if $options.images is 1>>
 										<<if _item.gender is "m">>
 											<img src="img/misc/icon/male.png" class="male">
 										<<elseif _item.gender is "f">>
@@ -374,7 +374,7 @@
 						<!-- Integrity, Reveal and Warmth indicators -->
 						<<if !$shopDefaults.compactMode>>
 							<div class="clothing-integrity">
-								<<if $images is 1>>
+								<<if $options.images is 1>>
 									<img class="clothing-stats-icon" src="img/misc/icon/integrity.png">
 								<<else>>
 									<span class="clothing-stats-text">I.</span>
@@ -385,7 +385,7 @@
 								<</for>>
 							</div>
 							<div class="clothing-reveal">
-								<<if $images is 1>>
+								<<if $options.images is 1>>
 									<img class="clothing-stats-icon" src="img/misc/icon/reveal.png">
 								<<else>>
 									<span class="clothing-stats-text">R.</span>
@@ -396,7 +396,7 @@
 								<</for>>
 							</div>
 							<div class="clothing-warmth">
-								<<if $images is 1>>
+								<<if $options.images is 1>>
 									<img class="clothing-stats-icon" src="img/misc/icon/warmth.png">
 								<<else>>
 									<span class="clothing-stats-text">W.</span>
@@ -442,7 +442,7 @@
 <</widget>>
 
 <<widget "clothingtrait">>
-	<<if $images is 1 and (_args[1] or _args[0] isnot "normal")>>
+	<<if $options.images is 1 and (_args[1] or _args[0] isnot "normal")>>
 		<<silently>><<shopTraitDescription _args[0]>><</silently>>
 		<mouse class="tooltip-tiny black"><img @src="'img/misc/icon/clothes/traits/' + _args[0] + '.png'" class="clothing-trait">
 		<<if _args[1] is undefined>><span><<print _clothesTrait>></span><</if>>
@@ -489,13 +489,13 @@
 		<<set _slimeSlots to setup.clothingLayer.torso>>
 		<<if !_slimeSlots.includes($clothingShopSlot) or currentSkillValue('willpower') gte 800 or _temp_choice.reveal gte 500 or _temp_choice.type.includesAny("school", "event") or $corruption_slime lt 80>>
 			<div class="clothing-colours-div">
-				<<set _hiddenMannequin = $images is 1 ? "" : "hidden">>
+				<<set _hiddenMannequin = $options.images is 1 ? "" : "hidden">>
 				<!-- Item preview -->
-				<div id="mannequin" @class="'mannequin ' + _hiddenMannequin + ($sidebarRenderer is 'both' ? ' both-renderers' : '')">
+				<div id="mannequin" @class="'mannequin ' + _hiddenMannequin + ($options.sidebarRenderer is 'both' ? ' both-renderers' : '')">
 					<<mannequin>>
 				</div>
 				<!-- Item colour selection -->
-				<<set _translate = $images is 1 ? "translate-colours-container" : "">>
+				<<set _translate = $options.images is 1 ? "translate-colours-container" : "">>
 				<div @class="'colours-container ' + _translate">
 					<div @class="'mannequin-placeholder ' + _hiddenMannequin"></div>
 					<<if _temp_choice.colour_options.length gt 1>>
@@ -762,7 +762,7 @@
 			<<set _active = (_acc == "primary" ? $colouraction : $accessorycolouraction) == _buttonName ? "active" : "">>
 			<div @class="'colour-button div-link ' + _active">
 				<div @class="'bg-' + _buttonName.replace(/ /g, '-')">
-					<<if $images is 1>>
+					<<if $options.images is 1>>
 						<<if _buttonName == "custom">>
 							<img src="img/misc/icon/custom.png">
 						<</if>>
@@ -841,7 +841,7 @@
 					<</listbox>>
 					<<set _delDisabled = Object.keys($customColors.presets).includes(_preset_choice[_acc]) ? "" : "disabled">>
 					<div @class="'delete-preset div-link ' + _delDisabled">
-						<<if $images is 1>><img src="img/misc/icon/delete.png"><<else>>Del<</if>>
+						<<if $options.images is 1>><img src="img/misc/icon/delete.png"><<else>>Del<</if>>
 						<<link "">>
 							<<if _preset_choice[_acc] and $customColors.presets[_preset_choice[_acc]] and confirm('Delete preset "' + _preset_choice[_acc] + '"?')>>
 								<<run delete $customColors.presets[_preset_choice[_acc]]>>
@@ -852,7 +852,7 @@
 					</div>
 				</div>
 				<div class="save-preset div-link">
-					<<if $images is 1>><img src="img/misc/icon/save.png"><<else>>Save<</if>>
+					<<if $options.images is 1>><img src="img/misc/icon/save.png"><<else>>Save<</if>>
 					<<link "">>
 						<<run saveCustomColourPreset(_acc)>>
 						<<updateclotheslist>>
@@ -971,7 +971,7 @@
 <</widget>>
 
 <<widget "mannequin">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<set _slot = _args[0] or _realSlot>>
 		<<set _index = _args[1] or _realIndex>>
 		<<set _item = setup.clothes[_slot][_index]>>
@@ -1011,10 +1011,10 @@
 			<<else>>
 				<<set _breastImg to ($mannequinBreastsSize is undefined ? 3 : (_mannequinGender is "m" ? 0 : $mannequinBreastsSize))>>
 			<</if>>
-			<<set _clothed = (((_slot != "under_upper" and $neverNudeMenus) or (_slot == "under_upper" and !_item.type.includes("naked"))) and _breastImg >= 2) ? "_clothed" : "">>
+			<<set _clothed = (((_slot != "under_upper" and $options.neverNudeMenus) or (_slot == "under_upper" and !_item.type.includes("naked"))) and _breastImg >= 2) ? "_clothed" : "">>
 
 			<div class="mannequin-inner">
-				<<if $sidebarRenderer isnot "img">>
+				<<if $options.sidebarRenderer isnot "img">>
 					<<selectmodel "main" "shop">>
 						<<set _modeloptions.mannequin to true>>
 						<<set _modeloptions.show_face to false>>
@@ -1025,7 +1025,7 @@
 						<<if $mannequinHasPenis>>
 							<<set _modeloptions.penis to "default">>
 						<</if>>
-						<<if $neverNudeMenus>>
+						<<if $options.neverNudeMenus>>
 							<<if _slot != "under_upper" and (_mannequinGender == "f" or _mannequinGender == "h")>>
 								<<set _modeloptions.worn_under_upper to 12>>
 								<<set _modeloptions.worn_under_upper_colour to "pale white">>
@@ -1067,14 +1067,14 @@
 								<</if>>
 							<</if>>
 						<</for>>
-						<<if $sidebarRenderer is "both">>
+						<<if $options.sidebarRenderer is "both">>
 							<<set _item = _items_list[0].item>>
 							<<set _slot = _items_list[0].slot>>
 						<</if>>
 					<<rendermodel "canvas-mannequin">>
 				<</if>>
 
-				<<if $sidebarRenderer isnot "canvas">>
+				<<if $options.sidebarRenderer isnot "canvas">>
 				<div class="mannequin-body">
 					<img src="img/body/mannequin/leftarmidle.png">
 					<img src="img/body/mannequin/basenoarms.png">
@@ -1085,7 +1085,7 @@
 						<img src="img/body/mannequin/penis.png">
 					<</if>>
 
-					<<if $neverNudeMenus>>
+					<<if $options.neverNudeMenus>>
 						<div class="neverNudeMenus">
 							<<if _slot != "under_upper" and (_mannequinGender == "f" or _mannequinGender == "h")>>
 								<div class="layer-under_upper clothes-pale-white">
@@ -1109,7 +1109,7 @@
 				<!-- Mannequin gender toggle button -->
 				<div class="mannequin-buttons no-numberify">
 					<div class="div-link mannequin-gender-button">
-						<<if $images is 1>>
+						<<if $options.images is 1>>
 							<<set _genderIcon = (_mannequinGender == "m" ? "male" : (_mannequinGender == "f" ? "female" : "unisex"))>>
 							<img @src="'img/misc/icon/' + _genderIcon + '.png'">
 						<<else>>
@@ -1119,7 +1119,7 @@
 					</div>
 				</div>
 
-				<<if $sidebarRenderer isnot "canvas">>
+				<<if $options.sidebarRenderer isnot "canvas">>
 				<div class="mannequin-clothes">
 					<<unset _styleP>>
 					<<unset _styleS>>
@@ -1214,7 +1214,7 @@
 <</widget>>
 
 <<widget "updatesidebarmoney">>
-	<<if $images>>
+	<<if $options.images>>
 		<<replace #stats>><<statsCaption>><</replace>>
 	<<else>>
 		<<replace #money-noimg>><<statsMoneyNoImg>><</replace>>
@@ -1445,7 +1445,7 @@
 		<div class="legend-caption bold gold">Legend</div>
 		<br>
 
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<div>
 				<img src="img/misc/icon/integrity.png">
 				Integrity rating. How hard it is to tear clothing into scraps.
diff --git a/game/overworld-town/loc-shop/clothingCategories-v2.twee b/game/overworld-town/loc-shop/clothingCategories-v2.twee
index fd82d83f36..24a5b0acc6 100644
--- a/game/overworld-town/loc-shop/clothingCategories-v2.twee
+++ b/game/overworld-town/loc-shop/clothingCategories-v2.twee
@@ -281,7 +281,7 @@
 		<div class="category-group">
 			<<set _active = _args[0] == "all" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "all">>
 				<<else>>
 					<div class="category-icon-alt">OO</div>
@@ -293,7 +293,7 @@
 			<div class="category-group">
 				<<set _active = _args[0] == "overoutfit" ? "active" : "">>
 				<div @class="'div-link category-tab ' + _active">
-					<<if $images is 1>>
+					<<if $options.images is 1>>
 						<<clothingcategoryicon "overoutfit">>
 					<<else>>
 						<div class="category-icon-alt">OO</div>
@@ -306,7 +306,7 @@
 			<<if $shopName isnot "school">>
 				<<set _active = _args[0] == "outfit" ? "active" : "">>
 				<div @class="'div-link category-tab ' + _active">
-					<<if $images is 1>>
+					<<if $options.images is 1>>
 						<<clothingcategoryicon "outfit">>
 					<<else>>
 						<div class="category-icon-alt">O</div>
@@ -316,7 +316,7 @@
 			<</if>>
 			<<set _active = _args[0] == "upper" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "upper">>
 				<<else>>
 					<div class="category-icon-alt">U</div>
@@ -325,7 +325,7 @@
 			</div>
 			<<set _active = _args[0] == "lower" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "lower">>
 				<<else>>
 					<div class="category-icon-alt">L</div>
@@ -336,7 +336,7 @@
 		<div class="category-group">
 			<<set _active = _args[0] == "underoutfit" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "underoutfit">>
 				<<else>>
 					<div class="category-icon-alt">UO</div>
@@ -345,7 +345,7 @@
 			</div>
 			<<set _active = _args[0] == "underupper" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "underupper">>
 				<<else>>
 					<div class="category-icon-alt">UU</div>
@@ -354,7 +354,7 @@
 			</div>
 			<<set _active = _args[0] == "underlower" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "underlower">>
 				<<else>>
 					<div class="category-icon-alt">UL</div>
@@ -365,7 +365,7 @@
 				<<set _active = _args[0] == "genitals" ? "active" : "">>
 				/* Left here for future expansion */
 				/*<div @class="'div-link category-tab ' + _active">
-					<<if $images is 1>>
+					<<if $options.images is 1>>
 						<<clothingcategoryicon "genitals">>
 					<<else>>
 						<div class="category-icon-alt">Fe</div>
@@ -377,7 +377,7 @@
 		<div class="category-group">
 			<<set _active = _args[0] == "head" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "head">>
 				<<else>>
 					<div class="category-icon-alt">He</div>
@@ -386,7 +386,7 @@
 			</div>
 			<<set _active = _args[0] == "face" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "face">>
 				<<else>>
 					<div class="category-icon-alt">Fa</div>
@@ -396,7 +396,7 @@
 			<<if $shopName isnot "school">>
 				<<set _active = _args[0] == "neck" ? "active" : "">>
 				<div @class="'div-link category-tab ' + _active">
-					<<if $images is 1>>
+					<<if $options.images is 1>>
 						<<clothingcategoryicon "neck">>
 					<<else>>
 						<div class="category-icon-alt">Ne</div>
@@ -406,7 +406,7 @@
 			<</if>>
 			<<set _active = _args[0] == "hands" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "hand">>
 				<<else>>
 					<div class="category-icon-alt">Ha</div>
@@ -415,7 +415,7 @@
 			</div>
 			<<set _active = _args[0] == "legs" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "legs">>
 				<<else>>
 					<div class="category-icon-alt">Le</div>
@@ -424,7 +424,7 @@
 			</div>
 			<<set _active = _args[0] == "feet" ? "active" : "">>
 			<div @class="'div-link category-tab ' + _active">
-				<<if $images is 1>>
+				<<if $options.images is 1>>
 					<<clothingcategoryicon "feet">>
 				<<else>>
 					<div class="category-icon-alt">Fe</div>
diff --git a/game/overworld-town/loc-shop/widgets.twee b/game/overworld-town/loc-shop/widgets.twee
index a0222a0ca5..951e86443e 100644
--- a/game/overworld-town/loc-shop/widgets.twee
+++ b/game/overworld-town/loc-shop/widgets.twee
@@ -162,7 +162,7 @@ Forth argument - item index*/
 			<br>
 			<<shopCustomColors>>
 		<</if>>
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<input type="button" value="Image" onclick="Wikifier.wikifyEval('<<shopFullImageToggle>>');">
 			<br>
 			<div id="shopFullImage" @class="($shopDefaults.invertImagesHidden is true? '' : ' hidden')"><<shopFullImage $clothingShopSlot $clothes_choice>></div>
@@ -558,7 +558,7 @@ Secondary Colour:
 <br>
 <label><<print '<<checkbox "$shopDefaults.invertCustomColorsHidden" false true '+($shopDefaults.invertCustomColorsHidden is true? "checked" : "")+'>>'>> Show custom colours by default.</label>
 <br>
-<<if $images is 1>>
+<<if $options.images is 1>>
 <label><<print '<<checkbox "$shopDefaults.invertImagesHidden" false true '+($shopDefaults.invertImagesHidden is true? "checked" : "")+'>>'>> Show clothes images by default.</label>
 <br>
 <</if>>
@@ -1188,7 +1188,7 @@ Name: <input id="colorName" type="text" value="Custom" maxlength="30" onfocus="V
 <</widget>>
 
 <<widget "updatesidebarimg">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<if $passage is "Start">>
 			<<startingPlayerImageUpdate>>
 		<<else>>
diff --git a/game/overworld-town/loc-street/barb.twee b/game/overworld-town/loc-street/barb.twee
index 4195e02fac..06fe894b65 100644
--- a/game/overworld-town/loc-street/barb.twee
+++ b/game/overworld-town/loc-street/barb.twee
@@ -63,7 +63,7 @@ You are on Barb Street. Silver blocks of flats tower all around you. You can hea
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "barb">>
 			<br>
 		<</if>>
@@ -107,7 +107,7 @@ You are on Barb Street. Silver blocks of flats tower all around you. You can hea
 		<<stormdrain>>
 		<br>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "barb">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/cliff.twee b/game/overworld-town/loc-street/cliff.twee
index 5d6ed51c9c..1af754498c 100644
--- a/game/overworld-town/loc-street/cliff.twee
+++ b/game/overworld-town/loc-street/cliff.twee
@@ -133,7 +133,7 @@ There's a path leading down to the beach.
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "cliff">>
 			<br>
 		<</if>>
@@ -200,7 +200,7 @@ There's a path leading down to the beach.
 		<<commercial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "cliff">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/connudatus.twee b/game/overworld-town/loc-street/connudatus.twee
index 45da588fdb..ceb904749c 100644
--- a/game/overworld-town/loc-street/connudatus.twee
+++ b/game/overworld-town/loc-street/connudatus.twee
@@ -98,7 +98,7 @@ You are on Connudatus Street. The numerous clubs, bars and restaurants make it t
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "connudatus">>
 			<br>
 		<</if>>
@@ -154,7 +154,7 @@ You are on Connudatus Street. The numerous clubs, bars and restaurants make it t
 		<<commercial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "connudatus">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/danube.twee b/game/overworld-town/loc-street/danube.twee
index 82e404f4cf..a24baf898f 100644
--- a/game/overworld-town/loc-street/danube.twee
+++ b/game/overworld-town/loc-street/danube.twee
@@ -53,7 +53,7 @@ Some homes host extravagant Halloween displays.
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "danube">>
 			<br>
 		<</if>>
@@ -99,7 +99,7 @@ Some homes host extravagant Halloween displays.
 		<<residential>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "danube">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/domus.twee b/game/overworld-town/loc-street/domus.twee
index 1c3c214150..634e8e89af 100644
--- a/game/overworld-town/loc-street/domus.twee
+++ b/game/overworld-town/loc-street/domus.twee
@@ -104,7 +104,7 @@ You are on Domus Street. The orphanage is here. The street is dominated by small
 		<<elseif ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 			<<eventsstreet>>
 		<<else>>
-			<<if $map.top is true>>
+			<<if $options.mapTop is true>>
 				<<map "domus">>
 				<br>
 			<</if>>
@@ -150,7 +150,7 @@ You are on Domus Street. The orphanage is here. The street is dominated by small
 			<<loiter>>
 
 			<<displayLinks>>
-			<<if $map.top isnot true>>
+			<<if $options.mapTop isnot true>>
 				<br>
 				<<map "domus">>
 			<</if>>
diff --git a/game/overworld-town/loc-street/elk.twee b/game/overworld-town/loc-street/elk.twee
index 05071fcde0..c7cd1a9ed5 100644
--- a/game/overworld-town/loc-street/elk.twee
+++ b/game/overworld-town/loc-street/elk.twee
@@ -30,7 +30,7 @@ You are on Elk Street. There are roads leading to several large industrial compl
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "elk">>
 			<br>
 		<</if>>
@@ -88,7 +88,7 @@ You are on Elk Street. There are roads leading to several large industrial compl
 		<<industrial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "elk">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/exposed.twee b/game/overworld-town/loc-street/exposed.twee
index ccfb6d5764..bbf9e9464f 100644
--- a/game/overworld-town/loc-street/exposed.twee
+++ b/game/overworld-town/loc-street/exposed.twee
@@ -10,7 +10,7 @@
 <<elseif $danger gte (9900 - $allure) and $eventskip is 0>>
 
 <<else>>
-	<<if $map.top is true>>
+	<<if $options.mapTop is true>>
 		<<map "barb">>
 		<br>
 	<</if>>
@@ -29,7 +29,7 @@
 	<<stormdrain>>
 	<br>
 	<<displayLinks>>
-	<<if $map.top isnot true>>
+	<<if $options.mapTop isnot true>>
 		<br>
 		<<map "barb" "exposed">>
 	<</if>>
diff --git a/game/overworld-town/loc-street/harvest.twee b/game/overworld-town/loc-street/harvest.twee
index 87bd7eae1c..aba44705dd 100644
--- a/game/overworld-town/loc-street/harvest.twee
+++ b/game/overworld-town/loc-street/harvest.twee
@@ -30,7 +30,7 @@ You are on Harvest Street. There's a road leading out of town, and many of the b
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "harvest">>
 			<br>
 		<</if>>
@@ -86,7 +86,7 @@ You are on Harvest Street. There's a road leading out of town, and many of the b
 		<<industrial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "harvest">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/high.twee b/game/overworld-town/loc-street/high.twee
index 8b9f41cab4..3ddd064c76 100644
--- a/game/overworld-town/loc-street/high.twee
+++ b/game/overworld-town/loc-street/high.twee
@@ -44,7 +44,7 @@ You are on the High Street, centre of the town's commercial activity. The shoppi
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "high">>
 			<br>
 		<</if>>
@@ -89,7 +89,7 @@ You are on the High Street, centre of the town's commercial activity. The shoppi
 		<<park>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "high">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/mer.twee b/game/overworld-town/loc-street/mer.twee
index 6c49e60b91..c0058c88a6 100644
--- a/game/overworld-town/loc-street/mer.twee
+++ b/game/overworld-town/loc-street/mer.twee
@@ -34,7 +34,7 @@ You are on Mer Street. The street is dominated by the docks and shipping industr
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "mer">>
 			<br>
 		<</if>>
@@ -62,7 +62,7 @@ You are on Mer Street. The street is dominated by the docks and shipping industr
 		<<industrial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "mer">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/nightingale.twee b/game/overworld-town/loc-street/nightingale.twee
index bd65da4231..e81f29c7bd 100644
--- a/game/overworld-town/loc-street/nightingale.twee
+++ b/game/overworld-town/loc-street/nightingale.twee
@@ -30,7 +30,7 @@ You are on Nightingale Street. It is dominated by the civic hospital but there a
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "nightingale">>
 			<br>
 		<</if>>
@@ -74,7 +74,7 @@ You are on Nightingale Street. It is dominated by the civic hospital but there a
 		<<park>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "nightingale">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/oxford.twee b/game/overworld-town/loc-street/oxford.twee
index be2bcc02e1..cbba88bc29 100644
--- a/game/overworld-town/loc-street/oxford.twee
+++ b/game/overworld-town/loc-street/oxford.twee
@@ -91,7 +91,7 @@ You are on Oxford Street. There's an eclectic mix of buildings, but most notable
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "oxford">>
 			<br>
 		<</if>>
@@ -160,7 +160,7 @@ You are on Oxford Street. There's an eclectic mix of buildings, but most notable
 		<<industrial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "oxford">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/starfish.twee b/game/overworld-town/loc-street/starfish.twee
index d7523c9156..00e7cdffb6 100644
--- a/game/overworld-town/loc-street/starfish.twee
+++ b/game/overworld-town/loc-street/starfish.twee
@@ -41,7 +41,7 @@ You are on Starfish Street. Wind blows in from the ocean.
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "starfish">>
 			<br>
 		<</if>>
@@ -83,7 +83,7 @@ You are on Starfish Street. Wind blows in from the ocean.
 		<<park>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "starfish">>
 		<</if>>
diff --git a/game/overworld-town/loc-street/wolf.twee b/game/overworld-town/loc-street/wolf.twee
index 54016b730e..d32e5f2e72 100644
--- a/game/overworld-town/loc-street/wolf.twee
+++ b/game/overworld-town/loc-street/wolf.twee
@@ -32,7 +32,7 @@ You are on Wolf Street. The nearby forest bleeds into the town here, particularl
 	<<if ($danger gte (9900 - $allure) or $eventforced) and $eventskip is 0>>
 		<<eventsstreet>>
 	<<else>>
-		<<if $map.top is true>>
+		<<if $options.mapTop is true>>
 			<<map "wolf">>
 			<br>
 		<</if>>
@@ -67,7 +67,7 @@ You are on Wolf Street. The nearby forest bleeds into the town here, particularl
 		<<commercial>>
 		<<stormdrain>>
 		<<displayLinks>>
-		<<if $map.top isnot true>>
+		<<if $options.mapTop isnot true>>
 			<br>
 			<<map "wolf">>
 		<</if>>
diff --git a/game/overworld-town/mapLocations.twee b/game/overworld-town/mapLocations.twee
index 6aad28e22d..57234a9765 100644
--- a/game/overworld-town/mapLocations.twee
+++ b/game/overworld-town/mapLocations.twee
@@ -5,10 +5,7 @@
 	<<set _map to clone($map)>>
 <</if>>
 <<set $map to {
-	"movement": true,
-	"top": false,
 	"hideLinks": false,
-	"markers": false,
 	"available": {
 		"Domus Street": ["Barb Street", "Danube Street", "Residential alleyways"],
 
@@ -39,11 +36,6 @@
 	},
 	"arrayList": ["Domus Street","Barb Street","Danube Street","Connudatus Street","Cliff Street","Wolf Street","High Street","Starfish Street","Nightingale Street","Oxford Street","Mer Street","Elk Street","Harvest Street","Residential alleyways","Commercial alleyways","Park","Industrial alleyways"]
 }>>
-<<if $avaliableMapsVersion is 2>>
-	<<set $map.movement to clone(_map.movement)>>
-	<<set $map.top to clone(_map.top)>>
-	<<set $map.markers to clone(_map.markers)>>
-<</if>>
 <<set $availableMapsVersion to 3>>
 <</widget>>
 
@@ -51,7 +43,7 @@
 <<widget "displayLinks">>
 
 <<for _i to 0; _i lt $link_table.length; _i++>>
-	<<if $map.hideLinks is true and $map.movement is true>>
+	<<if $map.hideLinks is true and $options.mapMovement is true>>
 		<<if $map.hideLinksCheck[_i] is true>>
 			<<continue>>
 		<</if>>
@@ -67,7 +59,7 @@
 <</widget>>
 
 <<widget "hideDisplay">>
-<<if $map.hideLinks is true and $map.movement is true>>
+<<if $map.hideLinks is true and $options.mapMovement is true>>
 	<<if _args[0] is true>>
 		<<set $map.hideLinksCheck.push(true)>>
 	<<else>>
diff --git a/game/overworld-underground/loc-underground/robin.twee b/game/overworld-underground/loc-underground/robin.twee
index d70711606e..e92f0ac78b 100644
--- a/game/overworld-underground/loc-underground/robin.twee
+++ b/game/overworld-underground/loc-underground/robin.twee
@@ -665,7 +665,7 @@ Most of the audience was staring at Robin, but all eyes snap to you as you are l
 
 <div id="die_text">
 	<span id="die_1">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_stone_roll.gif">
 		<<else>>
 			?
@@ -673,7 +673,7 @@ Most of the audience was staring at Robin, but all eyes snap to you as you are l
 	</span>
 
 	<span id="die_2">
-		<<if $images is 1>>
+		<<if $options.images is 1>>
 			<img src="img/misc/die_stone_roll.gif">
 		<<else>>
 			?
@@ -686,7 +686,7 @@ Most of the audience was staring at Robin, but all eyes snap to you as you are l
 
 <<timed 2s>>
 	<<replace "#die_1">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_stone_' + $uDice1 + '.png'">
 	<<else>>
 		$uDice1
@@ -695,7 +695,7 @@ Most of the audience was staring at Robin, but all eyes snap to you as you are l
 <</timed>>
 <<timed 4s>>
 	<<replace "#die_2">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<img @src="'img/misc/die_stone_' + $uDice2 + '.png'">
 	<<else>>
 		$uDice2
diff --git a/game/special-masturbation/widgets.twee b/game/special-masturbation/widgets.twee
index 0a98a0e4fb..9611d828de 100644
--- a/game/special-masturbation/widgets.twee
+++ b/game/special-masturbation/widgets.twee
@@ -203,7 +203,7 @@
 <</widget>>
 
 <<widget "masturbationbowlimage">>
-	<<if $images is 1>>
+	<<if $options.images is 1>>
 		<<set _masturbation_temp to Math.floor(($masturbation_fluid / 30))>>
 		<div id="divbowl">
 			<img id="map" src="img/misc/icon/masturbationbowl.png">
diff --git a/img/dolls/battleTestControls/characterDebug.js b/img/dolls/battleTestControls/characterDebug.js
index cbba13032c..09753dccf1 100644
--- a/img/dolls/battleTestControls/characterDebug.js
+++ b/img/dolls/battleTestControls/characterDebug.js
@@ -355,8 +355,6 @@ var skinColor = {
   tanLoc: ["body", "breasts", "penis", "swimshorts", "swimsuitTop", "swimsuitBottom", "bikiniTop", "bikiniBottom", "tshirt"],
   natural: "light",
   init: true,
-  tanningEnabled: true,
-  tanImgEnabled: "t",
   range: 17,
   current: {
     test: "",
diff --git a/modules/css/base.css b/modules/css/base.css
index e396d43048..254490190f 100644
--- a/modules/css/base.css
+++ b/modules/css/base.css
@@ -100,10 +100,150 @@ button:disabled {
 	background-color: var(--900);
 }
 
+.colourCodes {
+	cursor: help;
+	display: inline;
+	color: var(--link);
+	margin-left: 15px;
+}
+
+.rendererOutput {
+	display: inline;
+	margin-left: 10px;
+}
+
+/** Tabs **/
+.tab {
+	display: table;
+    width: 100%;
+	border: 1px solid #ccc;
+	border-radius: 4px 4px 0px 0px;
+	background-color: var(--750);
+  }
+
+.tab button:first-child{
+	border-radius: 4px 0px 0px 0px;
+}
+.tab button {
+	background-color: var(--800);
+	display: table-cell;
+	float: none;
+	outline: none;
+	cursor: pointer;
+	padding: 5px 15px;
+	margin: 0px;
+	min-width: 150px;
+	--max-width: max-content;
+	width: calc(var(--max-width) + 100px);
+	transition: 0.0s;
+	text-decoration: none;
+	font-size: 20px;
+	border: none;
+	border-right: 1px solid var(--300);
+	position: relative;
+	white-space: nowrap;
+	overflow: hidden;
+}
+
+.tab button:hover {
+	background-color: var(--850);
+	border: none;
+	border-right: 1px solid var(--300);
+}
+
+.tab button:active {
+	background-color: var(--850);
+	border: none;
+	border-right: 1px solid var(--300);
+}
+
+.tab button.tab-selected {
+	background-color: var(--850);
+	border: none;
+	cursor: default;
+	border-right: 1px solid var(--300);
+	border-bottom: 1px solid var(--850);
+	margin-bottom: -1px;
+	position: relative;
+}
+
+.tab button.tab-close {
+	position: relative;
+	right: 0px;
+	border-right: 1px solid var(--300);
+	border-radius: 4px 4px 0px 0px;
+	width: 100px;
+	float: right;
+}
+
+@media screen and (max-width: 1125px) {
+	.tab button {
+		padding: 5px 10px;
+		min-width: 125px;
+		width: calc(var(--max-width) + 50px);
+	}
+}
+
+@media screen and (max-width: 1000px) {
+	.tab button, .tab.colourCodes {
+		font-size: 98%;
+	}
+	.tab button {
+		padding: 5px 10px;
+		min-width: 100px;
+		width: calc(var(--max-width) + 40px);
+	}
+}
+
+@media screen and (max-width: 595px) {
+	.tab button, .tab.colourCodes {
+		font-size: 96%;
+	}
+	.tab button {
+		padding: 5px 10px;
+		min-width: 75px;
+		width: calc(var(--max-width) + 25px);
+	}
+}
+
+@media screen and (max-width: 470px) {
+	.tab button, .tab.colourCodes {
+		font-size: 94%;
+	}
+	.tab button {
+		padding: 5px 10px;
+		min-width: 50px;
+		width: calc(var(--max-width) + 10px);
+	}
+}
+
+/* Foldout */
+
+.foldoutHeader {
+	cursor: pointer;
+}
+
+.foldoutToggle {
+	border: solid var(--200);
+	border-width: 0 3px 3px 0;
+	display: inline-block;
+	padding: 3px;
+	margin-right: 8px;
+	margin-left: 8px;
+	transform: rotate(-45deg);
+	-webkit-transform: rotate(-45deg);
+	transition: 0.1s;
+}
+.foldoutToggle.extended {
+	transform: rotate(45deg);
+	-webkit-transform: rotate(45deg);
+}
+
 /* Tooltips */
 mouse.tooltip {
 	font-weight: normal;
 	border-bottom: 1px dotted var(--tooltip-border);
+	cursor:help;
 }
 
 mouse.tooltip span:last-of-type {
@@ -117,6 +257,7 @@ mouse.tooltip span:last-of-type {
 	line-height: 20px;
 	border-radius: 2px;
 	box-shadow: 0px 0px 8px 4px var(--900);
+	cursor: default;
 }
 
 mouse.tooltip:hover span:last-of-type {
@@ -278,29 +419,12 @@ mouse.tooltip-tiny:hover span:last-of-type {
 	margin-bottom: 4px;
 }
 
-.fixedClose {
-	position: sticky;
-	z-index: 1;
-	top: 0;
-	width: auto;
-	height: auto;
-	margin: 0;
-	padding: 0;
-	border-bottom: 1px solid var(--000);
-	background-color: var(--850);
-}
-
 .macro-button:hover {
 	border: 1px solid var(--000);
 	background-color: var(--800);
 }
 
-.macro-button:active {
-	border: 1px solid var(--000);
-	background-color: var(--yellow);
-}
-
-.macro-button:focus {
+.macro-button:active, .macro-button-selected, .macro-button-selected:hover {
 	border: 1px solid var(--yellow);
 	background-color: var(--700);
 }
@@ -314,21 +438,30 @@ mouse.tooltip-tiny:hover span:last-of-type {
 	max-width: 100%;
 }
 
+.customOverlayContainer {
+	position: fixed;
+	z-index: 999;
+	top: 0;
+	right: 0;
+	width: -webkit-calc(100% - 17.6em);
+    width: -moz-calc(100% - 17.6em);
+    width: calc(100% - 17.6em);
+	height: 100%;
+	pointer-events: all;
+	backdrop-filter: blur(3px);
+}
+
 .customOverlay {
 	display: block;
-	position: fixed;
+	position: absolute;
 	z-index: 1000;
-	top: 20px;
-	right: 20px;
-	bottom: 20px;
-	left: 20px;
+	top: 10px;
+	right: 10px;
+	bottom: 10px;
+	left: 10px;
 	width: auto;
 	max-width: 1000px;
 	height: auto;
-	padding: 0 5px 3px;
-	overflow-y: scroll;
-	border: 2px var(--000) solid;
-	background-color: var(--850);
 	line-height: 1.32em;
 	text-align: left;
 }
@@ -341,22 +474,58 @@ mouse.tooltip-tiny:hover span:last-of-type {
 
 #customOverlayContent {
 	padding: 0.5rem;
+	margin: 0.5rem;
+	margin-top: 0;
+	border: 1px solid #ccc;
+	
+	border-top: 0;
+	background-color: var(--850);
+	overflow-y: scroll;
+	height: calc(100% - 60px);
 }
 
 #customOverlayTitle {
 	display: flex;
 	flex-wrap: wrap;
-	gap: 0.25rem;
 	align-items: center;
 	padding: 0.5rem;
+	padding-bottom: 0;
 }
 
-@media only screen and (min-width: 870px) {
+@media only screen and (max-width: 870px) {
 	.customOverlay {
-		left: 300px;
+		left: -17.6em;
 	}
 }
 
+.customOverlayClose {
+	position: absolute;
+	width: 24px;
+	height: 24px;
+	right: 12px;
+	cursor: pointer;
+	opacity: 0.5;
+  }
+  .customOverlayClose:hover {
+	/* background-color: var(--400); */
+	opacity: 1;
+  }
+  .customOverlayClose::before, .customOverlayClose::after {
+	position: absolute;
+	top: 0px;
+	left: 10px;
+	content: ' ';
+	height: 24px;
+	width: 3px;
+	background-color: var(--100);
+  }
+  .customOverlayClose:before {
+	transform: rotate(45deg);
+  }
+  .customOverlayClose:after {
+	transform: rotate(-45deg);
+  }  
+
 .unstowable {
 	visibility: visible;
 }
@@ -521,11 +690,10 @@ input#addEventsWidgets::placeholder {
 	border-radius: 50%;
 	display: inline-block;
 	margin: 3px;
-	position: absolute;
+	position: relative;
 }
 
 .featCoin {
-	position: absolute;
 	margin-top: 3px;
 	margin-left: 3px;
 }
@@ -1493,7 +1661,6 @@ span.suit {
 	position: relative;
 	left: 0%;
 	top: 0%;
-	z-index: -10;
 }
 
 #spray1 {
-- 
GitLab


From c157622974e6b3d4680260d3c3e0872a2e55bc29 Mon Sep 17 00:00:00 2001
From: Xao <33462-xao@users.noreply.gitgud.io>
Date: Sat, 3 Sep 2022 20:27:59 +0200
Subject: [PATCH 24/50] Fixed error when clicking on an overlay during startup

---
 game/base-system/caption.twee | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/game/base-system/caption.twee b/game/base-system/caption.twee
index c3fee2381e..69ba6ef0d8 100644
--- a/game/base-system/caption.twee
+++ b/game/base-system/caption.twee
@@ -1,5 +1,6 @@
 :: StoryCaption
 <div @class="(Errors.log.length==0?'hidden':'') + ' error-reporter-btn'" onclick="Errors.Reporter.toggle()"></div>
+<<run T.buttons = new window.Tab("overlayButtons", "macro-button-selected")>>
 <<if $intro is 0>>
 	<<if $debug is 1>>
 		<div id="debugOverlay" class="debugOverlay unstowable"></div>
@@ -225,10 +226,6 @@
 			<br><br>
 		<</if>>
 
-		<<script>>
-			T.buttons = new window.Tab("overlayButtons", "macro-button-selected");
-		<</script>>
-
 		<div id="overlayButtons">
 			<<button CHARACTERISTICS>>
 				<<overlayReplace "characteristics">>
@@ -296,17 +293,19 @@
 	<<if StartConfig.enableImages is true>>
 		<div id="startingPlayerImage" class="hidden"></div>
 	<</if>>
-	<div id="versioninfo"><<versioninfo>></div>
-		<<button SAVES>>
-			<<overlayReplace "saves">>
-		<</button>>
-	<div class="sidebarButtonSplit">
-		<<button OPTIONS>>
-			<<overlayReplace "options">>
-		<</button>>
-		<<button FEATS>>
-			<<overlayReplace "startFeats">>
-		<</button>>
+	<div id="overlayButtons">
+		<div id="versioninfo"><<versioninfo>></div>
+			<<button SAVES>>
+				<<overlayReplace "saves">>
+			<</button>>
+		<div class="sidebarButtonSplit">
+			<<button OPTIONS>>
+				<<overlayReplace "options">>
+			<</button>>
+			<<button FEATS>>
+				<<overlayReplace "startFeats">>
+			<</button>>
+		</div>
 	</div>
 <</if>>
 
-- 
GitLab


From 21d1ca7c1d8f959ba8d3e7ce08c7ef3369ba39bc Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Sat, 3 Sep 2022 11:48:41 -0400
Subject: [PATCH 25/50] backComp missing an `<</if>>`

---
 game/04-Variables/variables-versionUpdate.twee | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index f02d82cca7..32fb98ef09 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -3685,6 +3685,7 @@
 			skipStatisticsConfirmation: $skipStatisticsConfirmation !== undefined ? $skipStatisticsConfirmation : false,
 			showDebugRenderer: $showDebugRenderer !== undefined ? $showDebugRenderer : !!StartConfig.debug,
 		};>>
+	<</if>>
 
 	<!-- v0.3.11.4 creampie.npc.penis and tentacle fix -->
 	<!-- IMPORTANT NOTE: please REMOVE this section if these stats come back into use -->
@@ -3697,6 +3698,7 @@
 	<<if $tirednessmax>>
 		<<unset $tirednessmax>>
 	<</if>>
+	
 	<!-- v0.3.11.4 - Add $makeup.mascara_running -->
 	<<if $makeup.mascara_running is undefined>>
 		<<set $makeup.mascara_running = 0>>
-- 
GitLab


From 84609fd4d0b007398a1406a03906f5282a4499f5 Mon Sep 17 00:00:00 2001
From: TonyFox <the_tonyfox@yahoo.com>
Date: Fri, 2 Sep 2022 12:17:18 -0400
Subject: [PATCH 26/50] remove merge conflict lines...

---
 game/base-system/mirror.twee | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/game/base-system/mirror.twee b/game/base-system/mirror.twee
index f853059032..c2c0cc0dd4 100644
--- a/game/base-system/mirror.twee
+++ b/game/base-system/mirror.twee
@@ -1299,12 +1299,8 @@ __Makeup__
 	<<set $makeup.lipstick to 0>>
 	<<set $makeup.eyeshadow to 0>>
 	<<set $makeup.mascara to 0>>
-<<<<<<< game/base-system/mirror.twee
 	<<set $makeup.eyelenses to { left: 0, right: 0 }>>
-=======
 	<<set $makeup.mascara_running to 0>>
-	<<set $makeup.eyelenses to { "left": 0, "right": 0 }>>
->>>>>>> game/base-system/mirror.twee
 <</link>> |
 <<link [[Randomise|$passage]]>>
 	<<for _i to 0; _i lt _makeupNames.length; _i++>>
-- 
GitLab


From a213b48d920fa7b4b63577f96f7e0e5f3f21d342 Mon Sep 17 00:00:00 2001
From: Xao <33462-xao@users.noreply.gitgud.io>
Date: Sat, 3 Sep 2022 00:45:36 +0200
Subject: [PATCH 27/50] Reverted change

---
 game/overworld-town/loc-dance-studio/widgets.twee | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/game/overworld-town/loc-dance-studio/widgets.twee b/game/overworld-town/loc-dance-studio/widgets.twee
index abaf141aed..2560922ecc 100644
--- a/game/overworld-town/loc-dance-studio/widgets.twee
+++ b/game/overworld-town/loc-dance-studio/widgets.twee
@@ -3,16 +3,17 @@
 	<<wearoutfit>>
 	<<set _store_location to "dance_studio">>
 	<<storeon _store_location "check">>
+	<<set _clothes to clothingInStorage(_store_location)>>
 	<<if $wearoutfittext isnot undefined>>
 		<<if $wearoutfittext is 1>>
 			<<set _slots to _clothes.filter(item => setup.clothingLayer.torso.includes(item.slot))>>
 			<<set _arrayClothes to _slots.map(slot => slot.name)>>
 			<<set _them to ((_arrayClothes.length gt 1 or _slots[0].word is "n") ? "them" : "it")>>
 			<<set _hooks to (_arrayClothes.length gt 1 ? "the hooks" : "a hook")>>
-			<<set _clothes to formatList(_arrayClothes)>>
+			<<set _clothing to formatList(_arrayClothes)>>
 
 			<span class="purple">
-				You remove your _clothes, and hang _them on _hooks.
+				You remove your _clothing, and hang _them on _hooks.
 			</span>
 		<<else>>
 			<span class="purple">
@@ -22,7 +23,7 @@
 		<<unset $wearoutfittext>>
 	<</if>>
 	<<if _store_check is 1>>
-		<<set _clothes to clothingInStorage(_store_location)>>
+		
 		<<if _clothes.length gt 0>>
 			<<if _clothes.length gt 2>>
 				Your clothes are hanging on the hooks on the wall.
-- 
GitLab


From f019e724627a19893dc50dffac5737549e4c04b1 Mon Sep 17 00:00:00 2001
From: xao <33469-xao321@users.noreply.gitgud.io>
Date: Tue, 6 Sep 2022 21:01:17 +0000
Subject: [PATCH 28/50] Dev bug fixes

---
 game/03-JavaScript/save.js                    |  2 +-
 game/04-Variables/variables-start.twee        |  5 +-
 game/04-Variables/variables-static.twee       |  4 ++
 game/base-clothing/clothing-sets.twee         | 32 ++++++------
 game/base-clothing/storeActions.twee          |  4 +-
 game/base-clothing/widgets.twee               | 50 +++++++++++++------
 game/base-combat/speech.twee                  |  6 +--
 .../loc-dance-studio/widgets.twee             | 35 ++++++++++---
 .../loc-school/science-project.twee           |  6 +--
 .../special-kylar/abduction_events.twee       |  2 +-
 10 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/game/03-JavaScript/save.js b/game/03-JavaScript/save.js
index 7a478e1320..325e6c63bc 100644
--- a/game/03-JavaScript/save.js
+++ b/game/03-JavaScript/save.js
@@ -144,7 +144,7 @@ const DoLSave = ((Story, Save) => {
 						signature: V.ironmanmode ? IronMan.getSignature(save) : false,
 					});
 					V.currentOverlay = null;
-					overlayShowHide("customOverlay");
+					closeOverlay();
 					if (V.ironmanmode === true) Engine.restart();
 				}
 			}
diff --git a/game/04-Variables/variables-start.twee b/game/04-Variables/variables-start.twee
index 704d549434..7b05924f00 100644
--- a/game/04-Variables/variables-start.twee
+++ b/game/04-Variables/variables-start.twee
@@ -80,7 +80,7 @@
 
 <<set $dev to 0>>
 <<set $numberify_enabled to 1>>
-<<set $showDebugRenderer to !!StartConfig.debug>>
+<<set $options.showDebugRenderer to !!StartConfig.debug>>
 <<set $lastWardrobeSlot to "head">>
 
 <<set $gamemode to "normal">>
@@ -861,6 +861,9 @@
 	<<set $makeup.owned.custom_eyelenses to []>> /* pharmacy custom eye lenses */
 <</if>>
 
+<<set $leftEyeColour to "purple">>
+<<set $rightEyeColour to "purple">>
+
 <<set $pharmDaily to {}>>
 
 <<set $prepareSaveDetails to true>>
diff --git a/game/04-Variables/variables-static.twee b/game/04-Variables/variables-static.twee
index 51070cd8a7..0bd79676fd 100644
--- a/game/04-Variables/variables-static.twee
+++ b/game/04-Variables/variables-static.twee
@@ -185,6 +185,7 @@ and are required for processing for loops, default objects, etc.*/
 			"doggyactiveblush3":"img/sex/doggyRed/active/body/doggyactiveblush3.png",
 			"doggyactiveblush4":"img/sex/doggyRed/active/body/doggyactiveblush4.png",
 			"doggyactiveblush5":"img/sex/doggyRed/active/body/doggyactiveblush5.png",
+			"doggyactivemouth":"img/sex/doggyRed/active/body/doggyactivemouth.png",
 			"freckles":"img/sex/doggyRed/active/body/freckles.png",
 			"breastsTiny":"img/sex/doggyRed/active/body/doggyactivebreaststiny.png",
 			"breastsSmall":"img/sex/doggyRed/active/body/doggyactivebreastssmall.png",
@@ -234,6 +235,7 @@ and are required for processing for loops, default objects, etc.*/
 			"doggyactiveblush3":"img/sex/doggy/active/body/doggyactiveblush3.png",
 			"doggyactiveblush4":"img/sex/doggy/active/body/doggyactiveblush4.png",
 			"doggyactiveblush5":"img/sex/doggy/active/body/doggyactiveblush5.png",
+			"doggyactivemouth":"img/sex/doggy/active/body/doggyactivemouth.png",
 			"freckles":"img/sex/doggy/active/body/freckles.png",
 			"breastsSmall":"img/sex/doggy/active/body/doggyactivebreastssmall.png",
 			"breastsLarge":"img/sex/doggy/active/body/doggyactivebreastslarge.png",
@@ -287,6 +289,7 @@ and are required for processing for loops, default objects, etc.*/
 			"activeblush3":"img/sex/missionaryRed/active/body/activeblush3.png",
 			"activeblush4":"img/sex/missionaryRed/active/body/activeblush4.png",
 			"activeblush5":"img/sex/missionaryRed/active/body/activeblush5.png",
+			"activemouth":"img/sex/missionaryRed/active/body/activemouth.png",
 			"freckles":"img/sex/missionaryRed/active/body/freckles.png",
 			"breastsTiny":"img/sex/missionaryRed/active/body/activebreaststiny.png",
 			"breastsSmall":"img/sex/missionaryRed/active/body/activebreastssmall.png",
@@ -328,6 +331,7 @@ and are required for processing for loops, default objects, etc.*/
 			"activeblush3":"img/sex/missionary/active/body/activeblush3.png",
 			"activeblush4":"img/sex/missionary/active/body/activeblush4.png",
 			"activeblush5":"img/sex/missionary/active/body/activeblush5.png",
+			"activemouth":"img/sex/missionary/active/body/activemouth.png",
 			"freckles":"img/sex/missionary/active/body/freckles.png",
 			"breastsTiny":"img/sex/missionary/active/body/activebreaststiny.png",
 			"breastsSmall":"img/sex/missionary/active/body/activebreastssmall.png",
diff --git a/game/base-clothing/clothing-sets.twee b/game/base-clothing/clothing-sets.twee
index be517dc33e..baac6730c6 100644
--- a/game/base-clothing/clothing-sets.twee
+++ b/game/base-clothing/clothing-sets.twee
@@ -129,22 +129,26 @@
 			<<continue>>
 		<</if>>
 		<<capture _outfit>>
-			<<if !$wardrobe['under_lower'].find(item => item.variable is _outfit.variable)>>
+			<<if !$wardrobe.under_lower.find(item => item.variable is _outfit.variable)>>
 				<span class="grey"><<print _outfit.name>> (Broken)</span>
-			<<elseif _outfit.name is currentOutfit()>>
-				<span class="grey"><<print _outfit.name>> (Equipped)</span>
-			<<else>>
-				<<link [["Wear "+_outfit.name|$passage]]>>
-					<<if clothingInStorage(_store_location).length is 0>>
-						<<storesave _store_location>>
-						<<set $wearoutfittext to 1>>
-					<</if>>
-					<<set $eventskip to 1>>
-					<<set _item_index to $wardrobe[_slot].indexOf(_outfit)>>
-					<<generalWearFromWardrobe _slot _item_index>>
-				<</link>>
+				<br>
+			<<elseif _outfit.name isnot _prevName>>
+				<<set _prevName to _outfit.name>>
+				<<if _outfit.name is $worn.under_upper.name>>
+					<span class="grey"><<print _outfit.name>> (Equipped)</span>
+				<<else>>
+					<<link [["Wear "+_outfit.name|$passage]]>>
+						<<if clothingInStorage(_store_location).length is 0>>
+							<<storesave _store_location>>
+							<<set $wearoutfittext to 1>>
+						<</if>>
+						<<set $eventskip to 1>>
+						<<set _item_index to $wardrobe[_slot].indexOf(_outfit)>>
+						<<generalWearFromWardrobe _slot _item_index>>
+					<</link>>
+				<</if>>
+				<br>
 			<</if>>
-			<br>
 		<</capture>>
 	<</for>>
 <</widget>>
diff --git a/game/base-clothing/storeActions.twee b/game/base-clothing/storeActions.twee
index b79e7172a3..b00764a4ab 100644
--- a/game/base-clothing/storeActions.twee
+++ b/game/base-clothing/storeActions.twee
@@ -260,7 +260,7 @@
 
 <<if _temp_clothes_present is 1>>
 	<br>
-	<<link [[Get dressed|$passage]]>><<storeon _temp_strip>><<set $eventskip to 1>><</link>>
+	<<link [[Get dressed|$passage]]>><<storeon _temp_strip "noreplace">><<set $eventskip to 1>><</link>>
 	<br>
 <</if>>
 
@@ -398,4 +398,4 @@
 
 <<exposure>>
 
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/base-clothing/widgets.twee b/game/base-clothing/widgets.twee
index a8e00d89d0..6c74b30951 100644
--- a/game/base-clothing/widgets.twee
+++ b/game/base-clothing/widgets.twee
@@ -1183,22 +1183,44 @@
 /* args[0] specifies the location identifier */
 <<widget "storeload">>
 	<<if _args[0] isnot undefined and $outfitTmp[_args[0]] isnot undefined and Object.keys($outfitTmp[_args[0]]).length gt 0>>
-		<<for $_slot range setup.clothingLayer.all>>
-			<<set $_item to $outfitTmp[_args[0]][$_slot]>>
-			<<if $_item is undefined or $worn[$_slot].name isnot $_item.name>>
-				<<generalStrip $_slot>>
-				<<returnCarried>>
+		<<if _args[1] isnot undefined>>
+			<<set $_item to $outfitTmp[_args[0]][_args[1]]>>
+			<<storeloaditem $_item _args[1]>>
+			<<run delete V.outfitTmp[_args[0][_args[1]]]>>
+			<<if Object.keys(V.outfitTmp[_args[0]]).length is 0>>
+				<<run delete V.outfitTmp[_args[0]]>>
 			<</if>>
-			<<if $_item isnot undefined>>
-				<<set $_stored to $store[$_slot].find(item => item.name is $_item.name)>>
-				<<if $_stored>>
-					<<set $worn[$_slot] to clone($_item)>>
-					<<set $worn[$_slot].location to 0>>
-					<<set $store[$_slot].deleteAt($store[$_slot].indexOf($_stored))>>
+		<<else>>
+			<<for $_slot range setup.clothingLayer.all>>
+				<<set $_item to $outfitTmp[_args[0]][$_slot]>>
+				<<if $_item is undefined or $worn[$_slot].name isnot $_item.name>>
+					<<generalStrip $_slot>>
+					<<returnCarried>>
 				<</if>>
-			<</if>>
-		<</for>>
+				<<if $_item isnot undefined>>
+					<<set $_stored to $store[$_slot].find(item => item.name is $_item.name)>>
+					<<if $_stored>>
+						<<set $worn[$_slot] to clone($_item)>>
+						<<set $worn[$_slot].location to 0>>
+						<<set $store[$_slot].deleteAt($store[$_slot].indexOf($_stored))>>
+					<</if>>
+				<</if>>
+			<</for>>
 		<<run delete V.outfitTmp[_args[0]]>>
+		<</if>>
+	<</if>>
+<</widget>>
+
+<<widget "storeloaditem">>
+	<<set $_item to _args[0]>>
+	<<set $_slot to _args[1]>>
+	<<if $_item isnot undefined>>
+		<<set $_stored to $store[$_slot].find(item => item.name is $_item.name)>>
+		<<if $_stored>>
+			<<set $worn[$_slot] to clone($_item)>>
+			<<set $worn[$_slot].location to 0>>
+			<<set $store[$_slot].deleteAt($store[$_slot].indexOf($_stored))>>
+		<</if>>
 	<</if>>
 <</widget>>
 
@@ -1270,7 +1292,7 @@
 			<</if>>
 		<</if>>
 	/* Strips and returns clothing items that are not replaced */
-	<<elseif $worn[$_slot].name isnot "naked" and !_args[2]>>
+	<<elseif $worn[$_slot].name isnot "naked" and !_args[2] and _args[2] isnot "noreplace">>
 		<<generalStrip $_slot>>
 		<<returnCarried>>
 	<</if>>
diff --git a/game/base-combat/speech.twee b/game/base-combat/speech.twee
index aeea593d57..20fac1c021 100644
--- a/game/base-combat/speech.twee
+++ b/game/base-combat/speech.twee
@@ -2879,7 +2879,7 @@
 		<<if $rng lte 35>>
 			<<He>> speaks. "Your clit is so much fun to play with."
 		<<elseif $rng lte 70>>
-			<<He>> speaks. "I could hurt instead of pleasure you you know, best be a good <<girl>>."
+			<<He>> speaks. "I could hurt instead of pleasure you, you know, best be a good <<girl>>."
 		<<else>>
 			<<He>> speaks. "You don't want to annoy me, not with your clit vulnerable like this."
 		<</if>>
@@ -2933,7 +2933,7 @@
 		<<if $rng lte 35>>
 			<<He>> speaks. "Your dick is so much fun to play with."
 		<<elseif $rng lte 70>>
-			<<He>> speaks. "I could hurt instead of pleasure you you know, best be a good <<girl>>."
+			<<He>> speaks. "I could hurt instead of pleasure you, you know, best be a good <<girl>>."
 		<<else>>
 			<<He>> speaks. "You don't want to annoy me, not with your dick vulnerable like this."
 		<</if>>
@@ -2960,7 +2960,7 @@
 		<<if $rng lte 35>>
 			<<He>> speaks. "Your butt is so much fun to play with."
 		<<elseif $rng lte 70>>
-			<<He>> speaks. "I could hurt instead of pleasure you you know, best be a good <<girl>>."
+			<<He>> speaks. "I could hurt instead of pleasure you, you know, best be a good <<girl>>."
 		<<else>>
 			<<He>> speaks. "If you annoy me, I'll give you a spanking."
 		<</if>>
diff --git a/game/overworld-town/loc-dance-studio/widgets.twee b/game/overworld-town/loc-dance-studio/widgets.twee
index 2560922ecc..df7fc61804 100644
--- a/game/overworld-town/loc-dance-studio/widgets.twee
+++ b/game/overworld-town/loc-dance-studio/widgets.twee
@@ -42,14 +42,35 @@
 	<</if>>
 	<br>
 	<br>
-	<<if $wardrobe["under_upper"].filter(a => a.type.includes("dance")) lte 0>>
-		//You currently have no dancing clothes.//
-	<<else>>
-		//Dancing clothes://
+	<<if $worn.under_upper.type.includes("dance") and $worn.under_lower.type.includes("dance") 
+		and setup.clothingLayer.torso_outer.some(slot => $worn[slot].name isnot "naked" and ($worn[slot].one_piece isnot 1 or $worn[slot].outfitSecondary is undefined))
+		and clothingInStorage(_store_location).length is 0
+	>>
+		<<link [[Strip down to your dance clothes|$passage]]>>
+			<<if clothingInStorage(_store_location).length is 0>>
+					<<storesave _store_location>>
+					<<for _slot range setup.clothingLayer.all.except(setup.clothingLayer.torso_outer)>>
+						<<storeload _store_location _slot>>
+					<</for>>
+			<<else>>
+				<<for _slot range setup.clothingLayer.torso_outer>>
+					<<generalUndress _store_location _slot>>
+				<</for>>
+			<</if>>
+		<</link>>
+		<br>
+		<br>
+	<</if>>
+	<<if !$worn.under_upper.type.includes("dance") gt 0 or clothingInStorage(_store_location).length is 0>>
+		<<if $wardrobe.under_upper.filter(a => a.type.includes("dance")) lte 0>>
+			//You currently have no dancing clothes.//
+		<<else>>
+			//Dancing clothes://
+			<br>
+			<<listdancingclothes _store_location>>
+			<<temperature>>
+		<</if>>
 		<br>
-		<<listdancingclothes _store_location>>
-		<<temperature>>
 	<</if>>
-	<br>
 	<br>
 <</widget>>
diff --git a/game/overworld-town/loc-school/science-project.twee b/game/overworld-town/loc-school/science-project.twee
index 480a975ace..0a8f746ee5 100644
--- a/game/overworld-town/loc-school/science-project.twee
+++ b/game/overworld-town/loc-school/science-project.twee
@@ -87,7 +87,7 @@ You can only submit one project to the fair.
 	<<link [[Next|Science Project]]>><<set $phase to 0>><</link>>
 	<br>
 <<else>>
-	You glance at the time. You suddenly realise that <span class="red">the maths competition has already ended.</span>
+	You glance at the time. You suddenly realise that <span class="red">the science competition has already ended.</span>
 	<br><br>
 	It would be silly to continue your work at this point. You dump the now obsolete project in a bin, feeling somewhat bitter over the wasted effort.
 	<br><br>
@@ -119,7 +119,7 @@ You can only submit one project to the fair.
 	<<link [[Next|Science Project]]>><<set $phase to 0>><</link>>
 	<br>
 <<else>>
-	You glance at the time. You suddenly realise that <span class="red">the maths competition has already ended.</span>
+	You glance at the time. You suddenly realise that <span class="red">the science competition has already ended.</span>
 	<br><br>
 	It would be silly to continue your work at this point. You dump the now obsolete project in a bin, feeling somewhat bitter over the wasted effort.
 	<br><br>
@@ -145,7 +145,7 @@ The things you do for school.
 	<<link [[Next|Science Project]]>><<set $phase to 0>><</link>>
 	<br>
 <<else>>
-	You glance at the time. You suddenly realise that <span class="red">the maths competition has already ended.</span>
+	You glance at the time. You suddenly realise that <span class="red">the science competition has already ended.</span>
 	<br><br>
 	It would be silly to continue your work at this point. You dump the now obsolete project in a bin, feeling somewhat bitter over the wasted effort.
 	<br><br>
diff --git a/game/overworld-town/special-kylar/abduction_events.twee b/game/overworld-town/special-kylar/abduction_events.twee
index e750ebdd0e..d9d1e25ca9 100644
--- a/game/overworld-town/special-kylar/abduction_events.twee
+++ b/game/overworld-town/special-kylar/abduction_events.twee
@@ -658,7 +658,7 @@ You nod, and Kylar's pencil whirs into motion. <<He>> paces around you, glancing
 Kylar seems to ignore you. <<His>> pencil whirs into motion. <<He>> paces around you, glancing between the pad, until <<he>> at last rips off the top sheet of paper to show you.
 <br><br>
 <<if $rng gte 81>>
-	There's a sketch of you, bound at gagged at the foot of a dragon. An image of Kylar charges the dragon on the back of a unicorn.
+	There's a sketch of you, bound and gagged at the foot of a dragon. An image of Kylar charges the dragon on the back of a unicorn.
 <<elseif $rng gte 61>>
 	There's a sketch of you, lying naked atop a depiction of Kylar. One of your hands is around <<his>> throat, choking <<him>>, while <<he>> looks on with awe. Your body proportions are inhuman.
 <<elseif $rng gte 41>>
-- 
GitLab


From e0d8415383d6dfbcd3f9f4b6d7fa9ee210d526a8 Mon Sep 17 00:00:00 2001
From: Braymann <19001-Braymann@users.noreply.gitgud.io>
Date: Tue, 6 Sep 2022 21:14:11 +0000
Subject: [PATCH 29/50] Bug fixes

---
 .../04-Variables/variables-versionUpdate.twee | 25 ++++++++++++
 game/base-combat/swarm-effects.twee           |  5 ++-
 game/base-combat/widgets.twee                 |  1 +
 game/base-system/clamp.twee                   |  2 +
 game/base-system/named-npcs.twee              | 38 -------------------
 game/base-system/widgets.twee                 |  2 +-
 game/overworld-forest/loc-lake/main.twee      |  2 +
 game/overworld-town/loc-spa/widgets.twee      |  2 +-
 game/overworld-town/loc-spa/work.twee         |  2 +-
 9 files changed, 36 insertions(+), 43 deletions(-)

diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index 32fb98ef09..2905f2c015 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -3692,6 +3692,31 @@
 	<<if _version lte 31104>>
 		<<run delete $sexStats.creampie.npc.penis>>
 		<<run delete $sexStats.creampie.npc.tentacle>>
+
+		<!-- Fixing most named npcs missing all of their virginities -->
+		<!-- Resetting all virginities to defaults, keeping virginities already taken by player -->
+		<<if $NPCName[$NPCNameList.indexOf("Jordan")].virginity.penile is false>>
+			<<for $_i to 0; $_i lt $NPCNameList.length; $_i++>>
+				<<set $_takenVirginities to []>>
+				<<for $_virginity, $_status range $NPCName[$_i].virginity>>
+					<<if $_status is "player">>
+						<<set $_takenVirginities.push($_virginity)>>
+					<</if>>
+				<</for>>
+				<<if $NPCNameList[$_i] is "Sydney">>
+					<<set $NPCName[$_i].virginity to {"anal": true, "oral": true, "penile": true, "vaginal": true, "handholding": true, "temple": true, "kiss": true}>>
+				<<else>>
+					<<initNNPCVirginity $_i>>
+				<</if>>
+				<<set $_takenVirginities.forEach(taken => $NPCName[$_i].virginity[taken] = "player")>>
+			<</for>>
+		<</if>>
+
+		<!-- Fix for saves where people were able to change wraith's gender -->
+		<<if $per_npc.wraith and $per_npc.wraith.pronoun isnot "i">>
+			<<set $per_npc.wraith.pronoun to "i">>
+			<<generatePronouns $per_npc.wraith>>
+		<</if>>
 	<</if>>
 
 	<!-- v0.3.11.4 $tirednessmax change to C.tiredness.max -->
diff --git a/game/base-combat/swarm-effects.twee b/game/base-combat/swarm-effects.twee
index f34b31e5cb..df8f33d6d5 100644
--- a/game/base-combat/swarm-effects.twee
+++ b/game/base-combat/swarm-effects.twee
@@ -621,13 +621,15 @@
 
 	/* -------- Clothes -------- */
 	<<effectshandsclothes>>
+
+	
+	<<set $leftactiondefault to $leftaction>><<set $rightactiondefault to $rightaction>>
 	/* -------- Both arms -------- */
 	<<if $leftaction is "swim" and $rightaction is "swim">><<set $leftaction to 0>><<set $rightaction to 0>>
 		<<set $swimdistance -= 2>>
 		You paddle towards safety with both arms.
 	<</if>>
 	/* -------- Left Arm -------- */
-	<<set $leftactiondefault to $leftaction>>
 	<<if $leftaction is "leftwriggle">><<set $leftaction to 0>>
 		<<if $leftarm is "bound">>
 			<<unbind>><span class="green">You wriggle free from your bonds.</span>
@@ -698,7 +700,6 @@
 	<</if>>
 
 	/* -------- Right Arm -------- */
-	<<set $rightactiondefault to $rightaction>>
 	<<if $rightaction is "rightwriggle">><<set $rightaction to 0>>
 		<<if $rightarm is "bound">>
 			<<unbind>><span class="green">You wriggle free from your bonds.</span>
diff --git a/game/base-combat/widgets.twee b/game/base-combat/widgets.twee
index cdf0d8d08d..603da86575 100644
--- a/game/base-combat/widgets.twee
+++ b/game/base-combat/widgets.twee
@@ -181,6 +181,7 @@
 	<<if $_npc and $_vType and $_npc.virginity and $_npc.virginity[$_vType] and (!$wraith or $wraith.mimic isnot $_npc.nam) and !$_straponvirginityIgnore>>
 		/* note: virginity must be exactly equal to true; only true means that they still have their virginity. */
 		<<if $_npc.virginity[$_vType] is true>>
+			<<personselect $_npcId>>
 			<<set $_npc.virginity[$_vType] to "player">>
 			<<switch $_vType>>
 				<<case "vaginal">>
diff --git a/game/base-system/clamp.twee b/game/base-system/clamp.twee
index 03ab701597..5e2611bbff 100644
--- a/game/base-system/clamp.twee
+++ b/game/base-system/clamp.twee
@@ -45,6 +45,8 @@
 <<set $penileskill = Math.clamp($penileskill, 0, 1000)>>
 
 <<set $corruption_slime = Math.clamp($corruption_slime, 0, 100)>>
+<<set $milk_volume to Math.clamp($milk_volume, 24, $milk_max)>>
+<<set $semen_volume to Math.clamp($semen_volume, 0, $semen_max)>>
 <<set $semen_amount = Math.clamp($semen_amount, 0, $semen_volume)>>
 <<set $milk_amount = Math.clamp($milk_amount, 0, $milk_volume)>>
 <<set $lactation_pressure = Math.clamp($lactation_pressure, 0, 100)>>
diff --git a/game/base-system/named-npcs.twee b/game/base-system/named-npcs.twee
index f8034fdc09..940c3155d6 100644
--- a/game/base-system/named-npcs.twee
+++ b/game/base-system/named-npcs.twee
@@ -375,7 +375,6 @@ alternative way to write that:
 	<<set $NPCName[_i].state to "active">>
 	<<set $NPCName[_i].purity to 0>>
 	<<set $NPCName[_i].corruption to 0>>
-	<<set $NPCName[_i].virginity to setup.NPCVirginityTypes>>
 	<<set $NPCName[_i].chastity to {penis:"", vagina:"", anus:""}>>
 	<<generatePronouns $NPCName[_i]>>
 	<<initNNPCClothes _nam>>
@@ -385,9 +384,7 @@ alternative way to write that:
 	<<switch _nam>>
 	<<case Kylar>>
 		<<set $NPCName[$NPCNameList.indexOf("Kylar")].state to 0>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypesVirgin)>>
 	<<case Robin>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypesVirgin)>>
 		<<set $robinDaily to {}>>
 		<<set $robinSeen to []>>
 		<<set $NPCName[_i].cdquest to 0>>
@@ -411,10 +408,6 @@ alternative way to write that:
 		<<else>>
 			//Mason is the swimming teacher at the local school. She's the youngest teacher, only a few years older than some of the students. Her toned body is naturally shown off during class, but if she notices the way she's leered at, she gives no indication.//
 		<</if>>
-		<<set $NPCName[_i].virginity.penile to false>>
-		<<set $NPCName[_i].virginity.vaginal to false>>
-		<<set $NPCName[_i].virginity.kiss to false>>
-		<<set $NPCName[_i].virginity.handholding to false>>
 	<<case Winter>>
 		<<if $NPCName[_i].pronoun is "m">>
 			//Winter teaches history at the local school. He's an older gentleman, well-groomed and sophisticated.//
@@ -433,16 +426,12 @@ alternative way to write that:
 		<<else>>
 			//Sirris teaches science at the local school. She's calm and patient, which sometimes leads to a disordered classroom.//
 		<</if>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypes)>>
 	<<case Eden>>
 		<<if $NPCName[_i].pronoun is "m">>
 			<<set $NPCName[_i].title to "hunter">>
 		<<else>>
 			<<set $NPCName[_i].title to "huntress">>
 		<</if>>
-		<<set $NPCName[_i].virginity.penile to false>>
-		<<set $NPCName[_i].virginity.vaginal to false>>
-		<<set $NPCName[_i].virginity.kiss to false>>
 	<<case Avery>>
 		<<if $NPCName[_i].pronoun is "m">>
 			<<set $NPCName[_i].title to "businessman">>
@@ -455,42 +444,15 @@ alternative way to write that:
 		<<else>>
 			<<set $NPCName[_i].title to "nun">>
 		<</if>>
-		<<set $NPCName[_i].virginity.handholding to false>>
 	<<case Whitney>>
 		<<set $NPCName[$NPCNameList.indexOf("Whitney")].dom to 10>>
 		<<set $whitneyDaily to {}>>
 	<<case "Great Hawk">>
 		<<set $NPCName[$NPCNameList.indexOf("Great Hawk")].dom to 50>>
-	<<case "Black Wolf">>
-		<<set $NPCName[_i].virginity.penile to false>>
-		<<set $NPCName[_i].virginity.vaginal to false>>
-	<<case Gwylan>>
-		<<set $NPCName[_i].virginity.oral to false>>
-		<<set $NPCName[_i].virginity.handholding to false>>
-		<<set $NPCName[_i].virginity.penile to false>>
-		<<set $NPCName[_i].virginity.vaginal to false>>
-		<<set $NPCName[_i].virginity.anal to false>>
-		<<set $NPCName[_i].virginity.kiss to false>>
-	<<case Charlie>>
-		<<set $NPCName[_i].virginity.kiss to false>>
-		<<set $NPCName[_i].virginity.handholding to false>>
-	<<case Sam>>
-		<<set $NPCName[_i].virginity.penile to false>>
-		<<set $NPCName[_i].virginity.vaginal to false>>
-		<<set $NPCName[_i].virginity.kiss to false>>
-		<<set $NPCName[_i].virginity.handholding to false>>
 	<<case Alex>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypes)>>
 		<<set $alexDaily to {}>>
-	<<case Darryl>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypes)>>
-	<<case Briar>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypes)>>
-	<<case Wren>>
-		<<set $NPCName[_i].virginity to clone(setup.NPCVirginityTypes)>>
 	<<case Sydney>>
 		<<set $NPCName[_i].purity to 100>>
-		<<set $NPCName[_i].virginity to {anal:true, oral:true, penile:true, vaginal:true, temple:true, handholding:true, kiss:true}>>
 		<<set $NPCName[_i].chastity to {penis:"chastity belt", vagina:"chastity belt", anus:"anal shield"}>>
 		<<set $sydneySeen to []>>
 		<<set $sydneyFirstSeen to "">>
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 9f2a52e3c0..1ec3dd90e9 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -3162,7 +3162,7 @@ It
 	<<set $tip to $tip_add>>
 <</if>>
 
-<<if $tip gte 10000>>
+<<if $tip gte 10000 and _args[0] isnot "body">>
 	<<set $tip to 2000 * Math.round( $tip / 2000.0 )>>
 <<elseif $tip gte 1000>>
 	<<set $tip to 500 * Math.round( $tip / 500.0 )>>
diff --git a/game/overworld-forest/loc-lake/main.twee b/game/overworld-forest/loc-lake/main.twee
index 3ec6944989..e8d2fe0c7e 100644
--- a/game/overworld-forest/loc-lake/main.twee
+++ b/game/overworld-forest/loc-lake/main.twee
@@ -488,6 +488,7 @@ There's a rocky alcove where you could store your clothes.
 		<<parasite nipples urchin>><<garousal>><<arousal 600>>
 		<br><br>
 	<</if>>
+	<<exposure>>
 <</if>>
 <<if $phase is 2>>
 	<<set $phase to 0>>
@@ -503,6 +504,7 @@ There's a rocky alcove where you could store your clothes.
 		<<parasite clit urchin>><<garousal>><<arousal 600>>
 		<br><br>
 	<</if>>
+	<<exposure>>
 <</if>>
 <<set $danger to random(1, 10000)>><<set $dangerevent to 0>>
 <<if $stress gte $stressmax and !$possessed>>
diff --git a/game/overworld-town/loc-spa/widgets.twee b/game/overworld-town/loc-spa/widgets.twee
index cb823b22a4..a2121f9ee8 100644
--- a/game/overworld-town/loc-spa/widgets.twee
+++ b/game/overworld-town/loc-spa/widgets.twee
@@ -102,7 +102,7 @@ A <<person>> enters,
 		<<set $tipmod to _args[1]>>
 	<</if>>
 	<<print '<<set $tipmod += (Math.trunc($' + _args[0] + 'skill / 100) / 10)>>'>>
-	<<tipset>>
+	<<tipset "body">>
 <</widget>>
 
 <<widget "spa_breasts_strip">>
diff --git a/game/overworld-town/loc-spa/work.twee b/game/overworld-town/loc-spa/work.twee
index 2cfb5e87da..ee0df83ffa 100644
--- a/game/overworld-town/loc-spa/work.twee
+++ b/game/overworld-town/loc-spa/work.twee
@@ -1422,7 +1422,7 @@ Your hands are occupied. You need to use something else.
 		"How does this feel?" you ask, keeping <<him>> on a torturous edge. "I can keep you like this as long as I want."
 	<</if>>
 	<br><br>
-	"P-please," the <<person>> begs. "Whatever you want! J-just let me cum!" <<body_tip thigh add>><<set $tip_add to ($tip + random(500, 1500))>><<tip_up>>
+	"P-please," the <<person>> begs. "Whatever you want! J-just let me cum!" <<body_tip bottom add>><<set $tip_add to ($tip + random(500, 1500))>><<tip_up>>
 	<br><br>
 
 	<<link [[Finish|Spa Lewd Bottom Finish]]>><</link>>
-- 
GitLab


From 2be09d0ded10dd6d9e6062c546f485481b8c0e4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=B6st?= <35009-Host@users.noreply.gitgud.io>
Date: Fri, 9 Sep 2022 22:44:48 +0000
Subject: [PATCH 30/50] Icons for actions in orphanage bathroom (and more)

---
 game/04-Variables/colours.js                  |  11 ++
 game/base-clothing/clothing-neck.twee         |   2 +-
 game/base-clothing/clothing-sets.twee         |   4 +
 game/base-system/images.twee                  |  45 +++++++
 game/overworld-forest/loc-lake/widgets.twee   |   4 +-
 .../loc-dance-studio/widgets.twee             |   2 +-
 game/overworld-town/loc-home/main.twee        |  30 ++---
 .../loc-school/changing-rooms.twee            | 124 +++++++++---------
 .../loc-school/classes/swimming.twee          |  16 +--
 game/overworld-town/loc-school/main.twee      |   4 +-
 game/overworld-town/loc-school/widgets.twee   |   8 +-
 game/special-masturbation/main.twee           |   4 +-
 img/misc/icon/bath.png                        | Bin 0 -> 719 bytes
 img/misc/icon/dye.png                         | Bin 0 -> 361 bytes
 img/misc/icon/putinlocker.png                 | Bin 0 -> 214 bytes
 img/misc/icon/shave.png                       | Bin 0 -> 684 bytes
 img/misc/icon/shave_balls_m.png               | Bin 0 -> 540 bytes
 img/misc/icon/shave_clean_f.png               | Bin 0 -> 500 bytes
 img/misc/icon/shave_clean_m.png               | Bin 0 -> 503 bytes
 img/misc/icon/shave_heart_f.png               | Bin 0 -> 516 bytes
 img/misc/icon/shave_heart_m.png               | Bin 0 -> 532 bytes
 img/misc/icon/shave_strip_f.png               | Bin 0 -> 509 bytes
 img/misc/icon/shave_strip_m.png               | Bin 0 -> 523 bytes
 img/misc/icon/shave_triangle_f.png            | Bin 0 -> 517 bytes
 img/misc/icon/shave_triangle_m.png            | Bin 0 -> 520 bytes
 img/misc/icon/shave_trim_f.png                | Bin 0 -> 514 bytes
 img/misc/icon/shave_trim_m.png                | Bin 0 -> 507 bytes
 27 files changed, 157 insertions(+), 97 deletions(-)
 create mode 100644 img/misc/icon/bath.png
 create mode 100644 img/misc/icon/dye.png
 create mode 100644 img/misc/icon/putinlocker.png
 create mode 100644 img/misc/icon/shave.png
 create mode 100644 img/misc/icon/shave_balls_m.png
 create mode 100644 img/misc/icon/shave_clean_f.png
 create mode 100644 img/misc/icon/shave_clean_m.png
 create mode 100644 img/misc/icon/shave_heart_f.png
 create mode 100644 img/misc/icon/shave_heart_m.png
 create mode 100644 img/misc/icon/shave_strip_f.png
 create mode 100644 img/misc/icon/shave_strip_m.png
 create mode 100644 img/misc/icon/shave_triangle_f.png
 create mode 100644 img/misc/icon/shave_triangle_m.png
 create mode 100644 img/misc/icon/shave_trim_f.png
 create mode 100644 img/misc/icon/shave_trim_m.png

diff --git a/game/04-Variables/colours.js b/game/04-Variables/colours.js
index 49c5c8a336..df6b73a7a3 100644
--- a/game/04-Variables/colours.js
+++ b/game/04-Variables/colours.js
@@ -112,6 +112,17 @@ setup.colours = {
 			return '#ffffff';
 		}
 		return Renderer.lintRgbStaged(tan, gradient).toHexString();
+	},
+	/** 
+	 * Get CSS style filter that, when applied, transforms #FF0000 colour to a skin colour
+	 * @param {string} type - One of [ light, medium, dark, gyaru, ylight, ymedium, ydark, ygyaru ]
+	 * @param {number} tan - How tanned the skin is, where 0 = the lightest, 100 = full tan
+	 * @returns {string} - CSS filter value. Note: return string doesn't start with 'filter:', you have to prepend it yourself
+	 * Return example: 'hue-rotate(50deg) saturate(0.40) brightness(0.60)'
+	 */
+	getSkinCSSFilter(type, tan = 0) {
+		let slidersValues = setup.skinColor[type];
+		return skinColor(true, tan, slidersValues);
 	}
 };
 
diff --git a/game/base-clothing/clothing-neck.twee b/game/base-clothing/clothing-neck.twee
index 58ea24bf09..698602e02f 100644
--- a/game/base-clothing/clothing-neck.twee
+++ b/game/base-clothing/clothing-neck.twee
@@ -548,7 +548,7 @@
 	plural: 0,
 	colour: 0,
 	colour_options: [],
-	colour_sidebar: 1,
+	colour_sidebar: 0,
 	type: ["normal"],
 	gender: "m",
 	femininity: -200,
diff --git a/game/base-clothing/clothing-sets.twee b/game/base-clothing/clothing-sets.twee
index baac6730c6..e23046127c 100644
--- a/game/base-clothing/clothing-sets.twee
+++ b/game/base-clothing/clothing-sets.twee
@@ -24,12 +24,14 @@
 <<widget "listoutfitsPassage">>
 	<<set $wardrobe_location to _args[0]>>
 	<<set _store_location to _args[1] || _args[0]>>
+	<<set $_indent to _args[2] || false>>
 	<<wardrobeSelection true>>
 	<<for _index, _outfit range $outfit>>
 		<<if (_outfit.location and _outfit.location isnot $wardrobe_location) or _outfit.type.includes("swim") or _outfit.type.includes("sleep")>>
 			<<continue>>
 		<</if>>
 		<<capture _index _outfit>>
+			<<if $_indent>><<ind>><</if>>
 			<<if _outfit.name is currentOutfit()>>
 				<span class="grey"><<print _outfit.name>> (Equipped)</span>
 			<<else>>
@@ -97,12 +99,14 @@
 <<widget "listswimoutfits">>
 	<<set $wardrobe_location to _args[0]>>
 	<<set _store_location to _args[1] || _args[0]>>
+	<<set $_indent to _args[2] || false>>
 	<<wardrobeSelection true>>
 	<<for _index, _outfit range $outfit>>
 		<<if (_outfit.location and _outfit.location isnot $wardrobe_location) or !_outfit.type.includes("swim")>>
 			<<continue>>
 		<</if>>
 		<<capture _index _outfit>>
+			<<if $_indent>><<ind>><</if>>
 			<<if _outfit.name is currentOutfit()>>
 				<span class="grey"><<print _outfit.name>> (Equipped)</span>
 			<<else>>
diff --git a/game/base-system/images.twee b/game/base-system/images.twee
index 404237c6b6..337923ab86 100644
--- a/game/base-system/images.twee
+++ b/game/base-system/images.twee
@@ -698,6 +698,15 @@
 	<<icon "locker.png">>
 <</widget>>
 
+<<widget "poollockericon">>
+	<<icon "locker.png">>
+<</widget>>
+
+<<widget "putinlockericon">>
+	<!-- contains nuclear briefcase and a vodka bottle -->
+	<<icon "putinlocker.png">>
+<</widget>>
+
 <<widget "loitericon">>
 	<<icon "loiter.gif">>
 <</widget>>
@@ -865,6 +874,42 @@
 	<<icon "bathroom.png">>
 <</widget>>
 
+<<widget "bathicon">>
+	<<icon "bath.png">>
+<</widget>>
+
+<<widget "shaveicon">>
+	<<icon "shave.png">>
+<</widget>>
+
+<<widget "shavestyleicon">>
+	<<if $options.images is 1>>
+		<<set $_filter = setup.colours.getSkinCSSFilter($skinColor.natural, $skinColor.range)>>
+		<<set $_fileName = 'shave_' + _args[0] + '_' + ($player.penisExist ? 'm' : 'f') + '.png'>>
+		<<print '<span style="filter: ' + $_filter + '">' + `<<icon $_fileName>>` + '</span>'>>
+	<</if>>
+<</widget>>
+
+<<widget "dyeicon">>
+	<<icon "dye.png">>
+<</widget>>
+
+<<widget "dressasyouwereicon">>
+	<<if $options.images is 1>>
+		<span class="clothes-light-blue"><<icon "clothes/serafuku.png">></span>
+	<</if>>
+<</widget>>
+
+<<widget "towelicon">>
+	<<if $options.images is 1>>
+		<span class="clothes-off-white"><<icon "clothes/towel.png">></span>
+	<</if>>
+<</widget>>
+
+<<widget "bathrobeicon">>
+	<<icon "clothes/bathrobe.png">>
+<</widget>>
+
 <<widget "bedroomicon">>
 	<<icon "bedroom.png">>
 <</widget>>
diff --git a/game/overworld-forest/loc-lake/widgets.twee b/game/overworld-forest/loc-lake/widgets.twee
index e8eaead2e6..0de5d0056a 100644
--- a/game/overworld-forest/loc-lake/widgets.twee
+++ b/game/overworld-forest/loc-lake/widgets.twee
@@ -550,14 +550,14 @@ A pair of eyes stares at you from between the trees, then vanishes.
 					Your _clothes[0].name is lying on the ground behind a rock.
 					<br>
 				<</if>>
-				<<link [[Put on clothes|$passage]]>><<set $eventskip to 1>><<storeload _store_location>><</link>>
+				<<dressasyouwereicon>><<link [[Put on clothes|$passage]]>><<set $eventskip to 1>><<storeload _store_location>><</link>>
 				<br>
 			<</if>>
 		<</if>>
 		<br>
 		//Swimming sets://
 		<br>
-		<<listswimoutfits $wardrobe_location _store_location>>
+		<<listswimoutfits $wardrobe_location _store_location true>>
 		<<temperature>>
 		<br>
 	<</if>>
diff --git a/game/overworld-town/loc-dance-studio/widgets.twee b/game/overworld-town/loc-dance-studio/widgets.twee
index df7fc61804..3c6e5c0266 100644
--- a/game/overworld-town/loc-dance-studio/widgets.twee
+++ b/game/overworld-town/loc-dance-studio/widgets.twee
@@ -35,7 +35,7 @@
 				Your _clothes[0].name is hanging on one of the hooks.
 				<br>
 			<</if>>
-			<<link [[Change to your clothes|$passage]]>><<set $eventskip to 1>><<set $wearoutfittext to 2>><<storeload _store_location>><</link>>
+			<<dressasyouwereicon>><<link [[Change to your clothes|$passage]]>><<set $eventskip to 1>><<set $wearoutfittext to 2>><<storeload _store_location>><</link>>
 		<</if>>
 	<<else>>
 		You could equip a leotard or similar dance clothes here.
diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index 827fa6421c..e5d3dadc42 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -619,14 +619,14 @@ You are in the bathroom.
 <<else>>
 	<<if $leftarm is "bound" and $rightarm is "bound">>
 		<<set _clothed = ![V.worn.upper.name, V.worn.lower.name, V.worn.under_upper.name, V.worn.under_lower.name, V.worn.over_upper.name, V.worn.over_lower.name].every(x => x == 'naked')>>
-		<<ind>><<link [["Have a bath " + (_clothed ? " in clothes " : "") + "(0:30)"->Bath]]>><<water>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
+		<<bathicon>><<link [["Have a bath " + (_clothed ? " in clothes " : "") + "(0:30)"->Bath]]>><<water>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
 	<<else>>
-		<<ind>><<link [[Have a bath (0:30)->Bath]]>><<strip>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
+		<<bathicon>><<link [[Have a bath (0:30)->Bath]]>><<strip>><<pass 30>><<stress -6>><<set $hygiene to 0>><</link>><<lstress>>
 	<</if>>
 	<br>
 	<!-- Check if there's any hair-->
 	<<if $pbdisable is "f" and ($pblevel gte 2 or $pbstrip gte 1 or $pblevelballs gte 2)>>
-		<<ind>><<link [[Groom pubic hair->Shave]]>><</link>>
+		<<shaveicon>><<link [[Groom pubic hair->Shave]]>><</link>>
 		<br>
 	<</if>>
 	<<pregnancyTest "Bedroom">>
@@ -1360,9 +1360,9 @@ You wash until you're squeaky clean.<<wash>>
 <<if $leftarm is "bound" and $rightarm is "bound">>
 	<<link [[Next|Bathroom]]>><</link>>
 <<else>>
-	<<link [[Dress as you were|Bathroom]]>><<clotheson>><</link>>
+	<<dressasyouwereicon>><<link [[Dress as you were|Bathroom]]>><<clotheson>><</link>>
 	<br>
-	<<link [[Wrap yourself in a towel|Bathroom]]>>
+	<<towelicon>><<link [[Wrap yourself in a towel|Bathroom]]>>
 		<<if $player.gender == "f" or $player.breastsize > 0>>
 			<<set $wear_upper = "large_towel">>
 		<<else>>
@@ -1374,7 +1374,7 @@ You wash until you're squeaky clean.<<wash>>
 
 	<<if $wardrobe.upper.findIndex(x => x.name == "bathrobe") >= 0 or $carried.upper.name == "bathrobe">>
 		<br>
-		<<link [[Put on a bathrobe|Bathroom]]>>
+		<<bathrobeicon>><<link [[Put on a bathrobe|Bathroom]]>>
 			<<returnCarried>>
 			<<set $wear_upper = $wardrobe.upper.findIndex(x => x.name == "bathrobe")>>
 			<<wardrobewear>>
@@ -2738,33 +2738,33 @@ You grab your clothes and dress with haste.
 	<br>
 	<</if>>
 	<<if $pblevel gte 2 or $pbstrip gte 1 or $pblevelballs gte 2>>
-		<<link [[Shave clean (0:15)->Shave clean]]>><<pass 15>><<arousal 100>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<set $pbstrip to 0>><<set $makeup.pbcolour to 0>><</link>>
+		<<shavestyleicon 'clean'>><<link [[Shave clean (0:15)->Shave clean]]>><<pass 15>><<arousal 100>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<set $pbstrip to 0>><<set $makeup.pbcolour to 0>><</link>>
 		<br>
 	<</if>>
 	<<if $pblevel gte 5 or $pbstrip gte 2 or ($pbstrip is 1 and $pblevel gte 2)>>
-		<<link [[Form a landing strip (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat landing strip">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 1>><</link>>
+		<<shavestyleicon 'strip'>><<link [[Form a landing strip (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat landing strip">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 1>><</link>>
 		<br>
 	<</if>>
 	<<if $pblevel gte 5 or $pbstrip gte 3 or ($pbstrip gte 2 and $pblevel gte 2)>>
-		<<link [[Form a heart (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "cute heart shape">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 2>><</link>>
+		<<shavestyleicon 'heart'>><<link [[Form a heart (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "cute heart shape">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 2>><</link>>
 		<br>
 	<</if>>
 	<<if $pblevel gte 5 or $pbstrip gte 4 or ($pbstrip gte 3 and $pblevel gte 2)>>
-		<<link [[Form a triangle (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat triangle">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 3>><</link>>
+		<<shavestyleicon 'triangle'>><<link [[Form a triangle (0:15)->Shave strip]]>><<pass 15>><<arousal 100>><<set $pbstripName to "neat triangle">><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 3>><</link>>
 		<br>
 	<</if>>
 	<<if $player.ballsExist is true>>
 		<<if $pblevel gte 2 or $pbstrip gte 1>>
-			<<link [[Shave only pubis (0:10)->Shave pubis]]>><<pass 10>><<arousal 50>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 0>><<if $pblevelballs is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
+			<<shavestyleicon 'clean'>><<link [[Shave only pubis (0:10)->Shave pubis]]>><<pass 10>><<arousal 50>><<set $pblevel to 0>><<set $pbgrowth to 0>><<set $pbstrip to 0>><<if $pblevelballs is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
 			<br>
 		<</if>>
 		<<if $pblevelballs gte 3>>
-			<<link [[Shave only balls (0:05)->Shave balls]]>><<pass 5>><<arousal 50>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<if $pblevel is 0 and $pbstrip is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
+			<<shavestyleicon 'balls'>><<link [[Shave only balls (0:05)->Shave balls]]>><<pass 5>><<arousal 50>><<set $pblevelballs to 0>><<set $pbgrowthballs to 0>><<if $pblevel is 0 and $pbstrip is 0>><<set $makeup.pbcolour to 0>><</if>><</link>>
 			<br>
 		<</if>>
 	<</if>>
 	<<if $pblevel gt 5 or $pblevelballs gt 5>>
-		<<link [[Trim short (0:10)->Shave trim]]>><<pass 10>><<arousal 100>>
+		<<shavestyleicon 'trim'>><<link [[Trim short (0:10)->Shave trim]]>><<pass 10>><<arousal 100>>
 			<<if $pblevel gte 5>>
 				<<set $pblevel to 5>><<set $pbgrowth to 7>><<set $pbstrip to 0>>
 			<</if>>
@@ -2775,10 +2775,10 @@ You grab your clothes and dress with haste.
 		<br>
 	<</if>>
 	<<if $worn.genitals.name isnot "chastity belt">>
-		<<link [[Dye pubic hair->Dye pubic hair]]>><</link>>
+		<<dyeicon>><<link [[Dye pubic hair->Dye pubic hair]]>><</link>>
 		<br>
 	<</if>>
-	<<link [[Don't shave anything->Bathroom]]>><<clotheson>><<dontHideRevert>><</link>>
+	<<ind>><<link [[Don't shave anything->Bathroom]]>><<clotheson>><<dontHideRevert>><</link>>
 <</if>>
 <</if>>
 
diff --git a/game/overworld-town/loc-school/changing-rooms.twee b/game/overworld-town/loc-school/changing-rooms.twee
index 90a184905b..da48abf7b3 100755
--- a/game/overworld-town/loc-school/changing-rooms.twee
+++ b/game/overworld-town/loc-school/changing-rooms.twee
@@ -24,11 +24,11 @@ You are in the boys' changing room.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -40,7 +40,7 @@ You are in the boys' changing room.
 		<</if>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $exposed gte 2 and $malechance isnot 0>>
 			You peek around the corner. You see boys in various states of undress. They'd spot you if you tried to enter.
@@ -55,7 +55,7 @@ You are in the boys' changing room.
 				<<link [[Enter (0:05)|School Boy's Exhibitionism]]>><<generatesm1>><<pass 5>><<detention 3>><</link>><<gdelinquency>><<exhibitionist5>>
 				<br>
 			<</if>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 			<br>
 		<<elseif $boysroomentered is $hour and $malechance isnot 0>>
 			<<generatesm1>><<person1>>
@@ -105,11 +105,11 @@ You are in the boys' changing room.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -121,7 +121,7 @@ You are in the boys' changing room.
 		<</if>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $exposed gte 2 and $malechance isnot 0>>
 			You peek around the corner. You see boys in various states of undress. They'd spot you if you tried to enter.
@@ -136,7 +136,7 @@ You are in the boys' changing room.
 				<<link [[Enter (0:05)|School Boy's Exhibitionism]]>><<generatesm1>><<pass 5>><<detention 3>><</link>><<gdelinquency>><<exhibitionist5>>
 				<br>
 			<</if>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 			<br>
 		<<elseif $boysroomentered is $hour and $malechance isnot 0>>
 			<<generatesm1>><<person1>>
@@ -174,11 +174,11 @@ You are in the boys' changing room.
 	<<if $player.gender_appearance is "m">>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $swimall isnot 1>>
@@ -200,18 +200,18 @@ You are in the boys' changing room.
 		<<school_pool_swap>>
 		<<boy_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $player.gender is "f">>
 			Even alone, being here makes you feel naughty, as well as worried you'll be caught.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -225,18 +225,18 @@ You are in the boys' changing room.
 		<<school_pool_swap>>
 		<<boy_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $poolroomstate is "other">><!-- $changingroomstate is "empty" -->
 	It's currently empty, though you can hear activity in the pool proper.
 	<<if $player.gender_appearance is "m">>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -250,18 +250,18 @@ You are in the boys' changing room.
 		<<school_pool_swap>>
 		<<boy_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<<if $player.gender is "f">>
 			Even alone, being here makes you feel naughty, as well as worried you'll be caught.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -275,28 +275,28 @@ You are in the boys' changing room.
 		<<school_pool_swap>>
 		<<boy_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 	<</if>>
 <<else>><!-- $poolroomstate is "empty" and $changingroomstate is "empty" -->
 	<<if $player.gender is "m">>
 		It's empty.
 		<br><br>
-		<<link [[Leave|School Pool Entrance]]>><</link>>
+		<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 		<br>
 	<<else>>
 		It's empty. Even so, being here makes you feel naughty.
 		<br><br>
-		<<link [[Leave|School Pool Entrance]]>><</link>>
+		<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Boy Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Boy Wardrobe]]>><</link>>
 		<br>
 	<</if>>
 <</if>>
@@ -331,7 +331,7 @@ You are in the girls' changing room.
 				<<link [[Enter (0:05)|School Girl's Exhibitionism]]>><<generatesf1>><<pass 5>><<detention 3>><</link>><<gdelinquency>><<exhibitionist5>>
 				<br>
 			<</if>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 			<br>
 		<<elseif $girlsroomentered is $hour and $malechance isnot 100>>
 			<<generatesf1>><<person1>>
@@ -379,9 +379,9 @@ You are in the girls' changing room.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -393,7 +393,7 @@ You are in the girls' changing room.
 		<</if>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $changingroomstate is "other">>
 	<<if $player.gender_appearance is "m">>
@@ -410,7 +410,7 @@ You are in the girls' changing room.
 				<<link [[Enter (0:05)|School Girl's Exhibitionism]]>><<generatesf1>><<pass 5>><<detention 3>><</link>><<gdelinquency>><<exhibitionist5>>
 				<br>
 			<</if>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 			<br>
 		<<elseif $girlsroomentered is $hour and $malechance isnot 100>>
 			<<generatesf1>><<person1>>
@@ -460,11 +460,11 @@ You are in the girls' changing room.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -476,7 +476,7 @@ You are in the girls' changing room.
 		<</if>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $poolroomstate is "own">><!-- $changingroomstate is "empty" -->
 	It's currently empty, though you can hear activity in the pool proper. Your lesson is in session.
@@ -486,11 +486,11 @@ You are in the girls' changing room.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -504,15 +504,15 @@ You are in the girls' changing room.
 		<<school_pool_swap>>
 		<<girl_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $swimall isnot 1>>
@@ -534,7 +534,7 @@ You are in the girls' changing room.
 		<<school_pool_swap>>
 		<<girl_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<elseif $poolroomstate is "other">><!-- $changingroomstate is "empty" -->
 	It's currently empty, though you can hear activity in the pool proper.
@@ -544,11 +544,11 @@ You are in the girls' changing room.
 		<</if>>
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -562,15 +562,15 @@ You are in the girls' changing room.
 		<<school_pool_swap>>
 		<<girl_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<<else>><!-- $player.gender_appearance is "f" -->
 		<br><br>
 		<<if $exposed gte 2>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<elseif $exposed is 1>>
-			<<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance Exhibitionism]]>><</link>>
 		<<else>>
-			<<link [[Leave|School Pool Entrance]]>><</link>>
+			<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<</if>>
 		<br>
 		<<if $exposed gte 2 and $exhibitionism gte 75>>
@@ -584,28 +584,28 @@ You are in the girls' changing room.
 		<<school_pool_swap>>
 		<<girl_lockers>>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 	<</if>>
 <<else>><!-- $poolroomstate is "empty" and $changingroomstate is "empty" -->
 	<<if $player.gender is "m">>
 		It's empty. Even so, being here makes you feel naughty.
 		<br><br>
-		<<link [[Leave|School Pool Entrance]]>><</link>>
+		<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 		<br>
 	<<else>>
 		It's empty.
 		<br><br>
-		<<link [[Leave|School Pool Entrance]]>><</link>>
+		<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 		<br>
 		<<swimmingicon>><<link [[Enter the pool room|School Pool]]>><</link>>
 		<br>
 		<<schoolpoolclothes _store_location>>
-		<<link [[Locker|School Girl Wardrobe]]>><</link>>
+		<<poollockericon>><<link [[Locker|School Girl Wardrobe]]>><</link>>
 		<br>
 	<</if>>
 <</if>>
@@ -639,7 +639,7 @@ The students continue their lesson, unaware of what awaits.
 
 <<link [[Wait to witness the results|School Changing Wait]]>><<control 25>><<trauma -12>><<stress -12>><</link>><<ggcontrol>><<lltrauma>><<llstress>>
 <br>
-<<link [[Leave|School Pool Entrance]]>><</link>>
+<<ind>><<link [[Leave|School Pool Entrance]]>><</link>>
 <br>
 
 
@@ -798,7 +798,7 @@ You successfully pick one of the lockers, and rummage inside.
 <</if>>
 <br><br>
 
-<<link [[Leave|School Boy Changing Room]]>><</link>>
+<<ind>><<link [[Leave|School Boy Changing Room]]>><</link>>
 <br>
 
 :: School Girl Locker
@@ -859,7 +859,7 @@ You successfully pick one of the lockers, and rummage inside.
 <</if>>
 <br><br>
 
-<<link [[Leave|School Girl Changing Room]]>><</link>>
+<<ind>><<link [[Leave|School Girl Changing Room]]>><</link>>
 <br>
 
 
diff --git a/game/overworld-town/loc-school/classes/swimming.twee b/game/overworld-town/loc-school/classes/swimming.twee
index 94f5900b78..a8b5b94f84 100644
--- a/game/overworld-town/loc-school/classes/swimming.twee
+++ b/game/overworld-town/loc-school/classes/swimming.twee
@@ -690,9 +690,9 @@ You manage to get beneath the flimsy protection of the water, but not before the
 		<<femaleicon>><<link [[Girls' changing room|School Girl Changing Room]]>><</link>>
 		<br><br>
 	<<elseif $exposed gte 1>>
-		<<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
+		<<maleicon>><<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
 		<br>
-		<<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
+		<<femaleicon>><<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
 		<br><br>
 	<</if>>
 <<else>>
@@ -784,9 +784,9 @@ Mason seems displeased by your choice of activity.
 		<<femaleicon>><<link [[Girls' changing room|School Girl Changing Room]]>><</link>>
 		<br><br>
 	<<elseif $exposed gte 1>>
-		<<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
+		<<maleicon>><<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
 		<br>
-		<<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
+		<<femaleicon>><<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
 		<br><br>
 	<</if>>
 <<else>>
@@ -846,9 +846,9 @@ Mason seems displeased by your choice of activity.
 		<<femaleicon>><<link [[Girls' changing room|School Girl Changing Room]]>><</link>>
 		<br><br>
 	<<elseif $exposed gte 1>>
-		<<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
+		<<maleicon>><<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
 		<br>
-		<<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
+		<<femaleicon>><<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
 		<br><br>
 	<</if>>
 <<else>>
@@ -915,9 +915,9 @@ Mason seems displeased by your choice of activity.
 		<<femaleicon>><<link [[Girls' changing room|School Girl Changing Room]]>><</link>>
 		<br><br>
 	<<elseif $exposed gte 1>>
-		<<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
+		<<maleicon>><<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
 		<br>
-		<<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
+		<<femaleicon>><<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
 		<br><br>
 	<</if>>
 <<else>>
diff --git a/game/overworld-town/loc-school/main.twee b/game/overworld-town/loc-school/main.twee
index f04e47b78f..1b4ca9e426 100644
--- a/game/overworld-town/loc-school/main.twee
+++ b/game/overworld-town/loc-school/main.twee
@@ -202,7 +202,7 @@ The school gate is shut and sealed by a sturdy padlock.
 <<if $exposed gte 1>>
 	A stack of towels sits on a trolley beside the door.
 	<br><br>
-	<<link [[Grab some towels|School Pool Entrance]]>><<towelup>><</link>>
+	<<towelicon>><<link [[Grab some towels|School Pool Entrance]]>><<towelup>><</link>>
 	<br><br>
 <</if>>
 
@@ -2556,4 +2556,4 @@ The <<person>> studies your face. "I'll have to report you to the authorities,"
 <br><br>
 
 <<endevent>>
-<<playground>>
\ No newline at end of file
+<<playground>>
diff --git a/game/overworld-town/loc-school/widgets.twee b/game/overworld-town/loc-school/widgets.twee
index 49515f2fed..7731349d0f 100644
--- a/game/overworld-town/loc-school/widgets.twee
+++ b/game/overworld-town/loc-school/widgets.twee
@@ -2626,20 +2626,20 @@
 				Your _clothes[0].name is lying on the bench next to the lockers.
 				<br>
 			<</if>>
-			<<link [[Put on|$passage]]>><<storeload _args[0]>><<set $eventskip to 1>><<set $wearoutfittext to 1>><</link>>
+			<<dressasyouwereicon>><<link [[Put on|$passage]]>><<storeload _args[0]>><<set $eventskip to 1>><<set $wearoutfittext to 1>><</link>>
 			<br>
-			<<link [[Put away|$passage]]>><<storeon _args[0] "return">><<set $eventskip to 1>><<set $wearoutfittext to 2>><</link>>
+			<<putinlockericon>><<link [[Put away|$passage]]>><<storeon _args[0] "return">><<set $eventskip to 1>><<set $wearoutfittext to 2>><</link>>
 			<br>
 		<</if>>
 	<</if>>
 	<br>
 	//Swimming sets://
 	<br>
-	<<listswimoutfits $wardrobe_location _args[0]>>
+	<<listswimoutfits $wardrobe_location _args[0] true>>
 	<br>
 	//Normal sets://
 	<br>
-	<<listoutfitsPassage $wardrobe_location _args[0]>>
+	<<listoutfitsPassage $wardrobe_location _args[0] true>>
 	<br>
 	<<temperature>>
 <</widget>>
diff --git a/game/special-masturbation/main.twee b/game/special-masturbation/main.twee
index 2b0fd94e8e..8b652881b6 100644
--- a/game/special-masturbation/main.twee
+++ b/game/special-masturbation/main.twee
@@ -893,9 +893,9 @@ You fondle yourself. The other students are so near, they could so easily see wh
 			<<femaleicon>><<link [[Girls' changing room|School Girl Changing Room]]>><</link>>
 			<br><br>
 		<<elseif $exposed gte 1>>
-			<<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
+			<<maleicon>><<link [[Grab some towels and enter the boys' changing room|School Boy Changing Room]]>><<towelupm>><</link>>
 			<br>
-			<<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
+			<<femaleicon>><<link [[Grab some towels and enter the girls' changing room|School Girl Changing Room]]>><<towelup>><</link>>
 			<br><br>
 		<</if>>
 	<<else>>
diff --git a/img/misc/icon/bath.png b/img/misc/icon/bath.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2f8fb6f850229720af128bc5c6f1a2393de5424
GIT binary patch
literal 719
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z6#fU=$4S32_B-jg5_G%$Tus>C)-b
zrvu3)OO^o1Wy_WUxn^c&KsHcz+O%mv5g?c{WeS7=6rVeHE|3jWHfz=_Aa}un1wig%
zFo39;H*X$<0W<*!rcRv-<OT!;0JQ)a5EBdx4Cc?D4`eS|v}obNg%I^X66g$w8X)=q
z|NmRJZmn9m^25iE_wL=haN)v<6DQWLS+jQSTA*#qmoMMGef#=#>wpe8d-m*+BS$uF
z+z8Y@XU-g;!+;L{{Q2|i*RLNvdIYor=%k*Wo?pLyef|3N`Sa&DZ{ECm_3EWdmrk8J
zb^Q48f`Wo&-~JW=1I4@~$S;_od3)fQ@;EV}-CfH6emuHy{^*WXD;F=C(HG)rV`?b(
z=hK^KH?Lhivu|>HLv>+(nw^cdhN=`VOUWInd%*BD^K@|x(Kx^NTzYYnfy9B2%bOai
z^RvI-GrqWB)1BSB|NfI-B5=U0=u7B%dCtmr|JcQUurmq$Tah}&ZBD+ev*ihellu7z
z5dtn^|7I$*aO{v<I`vN|pLSxw(zN3_e8~s8OpCJwcE|;0`LHcLmYD6gnqA@AR+bHs
zOdS!QeZ3e2SUXQ1{GI48J!8M^s<^kjWvjK#&wr5ZS-$a5*!Fw@o#T`KeD$|;QJ$O7
z6W?o|Gw)iSn|Gcl^ZXe~UsB~G-sa!>*;lW=<K`Bz+Bw0eZ~b-2y}EbHyr3mN7p;H2
zHtcrHxn<t@$D19dzUnPZKKj{ZWy9J<c8dKQ1q+K(?tOSR{UNhO#m(9FP7ijO*v$85
zlhH{{58gJZlCjQGw)AOVj&b|D7cvso7gOv+7C8O<o5&Qga|eg__S>!z&H3x({LgBZ
S%*X;p0)wZkpUXO@geCw`-gl}1

literal 0
HcmV?d00001

diff --git a/img/misc/icon/dye.png b/img/misc/icon/dye.png
new file mode 100644
index 0000000000000000000000000000000000000000..591699a0028d5a0f579ac50fe188afaa9d11aeec
GIT binary patch
literal 361
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGIRQQ)u0Z<m;ltV4*;-m!E-o%S
zJUmQHOhCb?s3;)${P}Yrx$@wv|Ns9_TXXUL{rfSQjWai1WtjN?)vH$(ohumX9=6Te
z!|?h)L)8C84FBaA{+~Q~@;}2-S!Lb-{~1>OXJGix@IL`aFns*@F|+>s1E6u-B|(0{
z47_YXUgkR5DpD*=f7@pOg%^6dIEHAPKYQ_{RFeUZYvO^M(cTk{PQCfPfAOWT%)d_C
zi^@*!_ioB<DOczBZY;H3oO`{J|J+g+kJo~845t-b=xH(RZ~hs{vC>khau!Rt%p{w>
zxOY~E!}oT?ysJK3weP^w#DF=6r#wt34m@*a;$2_K9KF*s6Q35uYS$g}-mqhp$bGw|
zZoKBbk4gd`t+3p;OF8b4V0N9t0t@$?D^Kq??f=d+ajC%6dv|&DfsSSHboFyt=akR{
E0Fq^y(f|Me

literal 0
HcmV?d00001

diff --git a/img/misc/icon/putinlocker.png b/img/misc/icon/putinlocker.png
new file mode 100644
index 0000000000000000000000000000000000000000..416df9a2db1ee7110391e8c494238639ae6f82bd
GIT binary patch
literal 214
zcmeAS@N?(olHy`uVBq!ia0vp^av;pY3?xs=ZJr3?1o(uw0_n`GtjMq+KW`6)a)y}L
zScZ)Z41Ej+`ueuEw$bi~KLb@TmIV0)GdMiEkp|?XdAc};NL)@<5H^rzKFGpy-vkIQ
zF@)X{IhZcQ!j!Ua!lX$`T=4+{Q}r))1m9!yy~pZ%?=EBK`$vz0!kUhhdjml^!zWdP
z9~@sJ&K}O3&%Eom=Og7qhi5RF?%|p6!^^?J&xVnq(MFEx#Fk}mfi^ODy85}Sb4q9e
E04C=|tN;K2

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave.png b/img/misc/icon/shave.png
new file mode 100644
index 0000000000000000000000000000000000000000..90b4c25ae299e8d042638847b9bfeaa18f034e43
GIT binary patch
literal 684
zcmV;d0#p5oP)<h;3K|Lk000e1NJLTq0015U0015c0{{R34DMc#00036P)t-s0002i
z*4ozA+Re|@#mLSrOqoMopfggVF;JV5p29R!qKlcnn4r6#smB;RmpNCb9zmEkRh~On
zol$A3No1&1Y^t89#ILf(yur>dPopVHoG3}0I98uERHt8buvu}hG*X>OWT#VWsabHY
zke$KD%G1-+)?atlGE%oNQMO=t*j;wkx4_V~zRp!|%~Wp8V0gnNNWLUTy){(0UU=J*
zpu}Hz!-<%@DonIDRiYC&mm58mT6EMvU&D)<z=V{%I99kjSg$=<t1?cdZG+}lane_D
z(Nu5EZ-mQjgUd!@#*?DOG*P!MPq!mRwIW5cN@TE0WUntztS?WiElr&sJ&qeZj>n}5
zJ^%m!Cv;LyQvd`72Po0X^wA#iT}?3h^Xkyf$-u8uLo)vH;o8^3z`3rWmMa$unWsDk
z0003mNkl<ZD9^3Z=TgEz5CGsMQ3Mk}q}sdb2<e3)VDJ6?AH~fb63@h6y1C2E&NsWW
zH*@fB(cTpxBRDRH3l=I5VH0w3LVnzga~P;g=Jjn*A{mW@QI~tJ;gmBOP|dDBTq#1D
zN#|bI7;O|OvP@O?q65fc+Sv>4wlf)PUBe4*>=!X+h*!exis|a3$g=J6dkaul-h8|=
zhU<;m>-cFf713E1LdS`3Bzz3cCQ+RSmZAApMg?e1C(oK(KxZc}9RkV3P&=2bMdAtL
z$<cJ@UOSOav7X`NqBTXL&T!&+bd~l`Gme~>rH-Vavz*jhT1SmN&7@>imZ+yW-rQIJ
zIg>?sR)47~h2tMgkk;e;ej}T4S7r60zxMqh<2OHnuljwz4!;J!zqNM+e~eEcrXY^O
SQa@4v0000<MNUMnLSTZ;4nM{K

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_balls_m.png b/img/misc/icon/shave_balls_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf2c680d12fe1f4b8cdd005365ab0b63463a8927
GIT binary patch
literal 540
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGD*}8%T!AzkFfuZ#sj4zCGczzT
zF|e_T%gHhD@+kwQ+1VL*xEXkOG<kR!q@;i(Q00HHwmt@iISdRyH4zL9?->~OF)&<b
zU{GLSILE+{#J~Ww{xSmt3j@Pj28L7yhCl{}TMP^*85q_wFmy98v@tMLGcXh}Fvv47
z{A6Hw%E0iDf#D(p!(j%7Ees6H7#J!T7%~_bJQ*0A85ox5#sH-lgiC__f*HPieEpsM
z!R^!1x6ka_zIpNVCV^X<=L1b=6!3I$4AD5h_R`I=CIbPs1c!o`_s%&uEppQeU0rtn
z-v6^)o@y#5Ecd>wpZdQhy=PYEKUGgT70%KnVh>UmIvp2fsXUPIgJZ9Z`@av_^OxGM
zd!X{_jAq@OPh!?>jTU~d6xTgI!?)jY`qN8tW)>fA`fwB_J=<Jzrl;@v+;gXk{GPAh
z`0U3<-S2%X-y|L0xsP+L-A&^sZNj#D4{<e2S7i@))>zhA+3%kbtaQq$!%1mY_qS)E
zYF|RN!%Px0URN!u{FPjtxMRcD>Qz6xc#U^osR_QRC-tm{d)Mm!%gxIAs<S-)I7xT-
zE}UCaw&!bQ@@ebBngZ^!={x7zE^*u3J?onJ+_OQR_STE;e2Qt`-g@r(#rr>5C+8TM
Tr`hk@1&S<BS3j3^P6<r_$Ya9_

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_clean_f.png b/img/misc/icon/shave_clean_f.png
new file mode 100644
index 0000000000000000000000000000000000000000..31634fdb4e596a68304fbd59f2579b879eb278f3
GIT binary patch
literal 500
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TG^8<WBT!AzYFfuYi80=giEey=e
z3`|T6Jlr5QFCPOND+4<_5NY!8Fi1%ONl7_*pqBq2X@))qhU*LrXBimYGB8|bV7S1*
z5Xr#6$-r=mfgzQFA&`MVgMmSXfq{>K;Wh)qVFrfv3=At67`ho4+87wB7#NBe7~~lk
zo-!~zWMJ6Iz%ZGCA%lS-k%7UJfx(%9!Ac+!NHU0&1o;IseE9bIlZ5Pp+grJApE<c}
z@$@EH0U3_E{XqE-o-U3d8t2zex+&CTz~kzDwDvk%0b}9)^8f#DZ#iqS^uk5)^TIQY
z&2v3&#(!YqKEG|Lg^=W;8{Z7X#1tbQPCiknm3mlMS>|JeNQ9YhMf8<ugD4Ayw@dZr
z{<7Lr_L9Zteg0kXJX`nZxjVn^UA1NZ^rITe8*V(jTd}~8$>iDZV}*KC<)q~wH<ih~
zd)&agbiRIy7{Aqnuq^&pGZ|d2q=p6W`n$;VK>N~l^K_TKHu)|k(X4$oHhh<Rd6cK@
zv;R^rIYUkfh<-V`^!yU@$hjOTi?`M<VK>XUFx$3hORwLm^~cy#<z8)^xy+tdBslWL
cd%fRhrJvOpWi;M=%nynHPgg&ebxsLQ0Is^D!T<mO

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_clean_m.png b/img/misc/icon/shave_clean_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..01011f2bb8c9590326cc379a819abeba04668746
GIT binary patch
literal 503
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TG(*k@#T!AzKu(7GBsxmM$GjMW>
z%gHe_GqW&()HATLGO)8V@bGBz@GwY80ZB$i#{Xb#eGCjL3=EMB4Eq=u<}fgvWng&A
zz;Ky?A&r57lY!wn1H%OdhCl{}#|#X&7#L16Fl=IASi!*1&A`ycz);P=P{hFC#=s!Y
zz;Kv>VKM_l1p`AO1A_nqgZ_M8cA)vfB|(0{3|~IJzRmt%r}X#l-_D%eym)$(fW5It
z6j1uFr;B5V#`(3EZf<Ha;9*Nxv1necr$^&r4Y}`kzt>wX=Upjc^|<$cf#Z*5jJI6;
zJH7U5#8;;>_KGZhZ^5Sj|AnrdgLZpd@y9i1FF*SvWVQ3#+()ZUYws~;c@z<<xb9Jl
zWWQou!jA1OGY<KzY4)6<&V2ggF_C(OiAl1?%a=KbO#UsrdDH6S&mt4oPvXy5`@`nk
z9Rb7Z3|8(>#B+a!{1SiZ$>PxRDRa+j`QN+F^(s6q-C4i=kLRIV8^o3^e477qnqhkB
z&6^>;k!{f#pJgnJ4;xJ`KJK09w8S-5r}gn%=?(XfoPG1I*HkjhXy5w97f*-OSx@@&
k;)>gBr+51o9pB0LDbC>f6WztY0ApbAboFyt=akR{073S$=Kufz

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_heart_f.png b/img/misc/icon/shave_heart_f.png
new file mode 100644
index 0000000000000000000000000000000000000000..399e44ac6fa13b547c621c576d17031f1d671132
GIT binary patch
literal 516
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGGXs1=T!AzMuyJxSGBN_$?3|ox
zs;Uf3Obi?x3~X!+JlqUGab{))c6Lo39tJ5XAo(Axr;mX_nStRg1H)Mch8qkFsSFI4
z85qtpFhnvis4*~bGBBKEVA#jN5Xiv5$H4H1f#ER&!)*qJ!wd|Y7#LPCFw9|K=w@JO
zV_+y^V322Es9|8JU|{fMU~pz&&}LwGb7fi!&=#SRAirRSkFUkPeUW9qcl-3#9}jme
zp58P+ZgUC)10#p0i(`n!`L&a7<~17#xJEipTUX2|EVNDK>?O6k|NcLY;+GN^_pUrS
zaYD`W7fRA^?y}f#{g5ktrHgIFt#2A97d3?LyI`+(aKj#@gQ4p)kEEsP^d;9GnXks~
z_Is{(dEuq(H?g}Kf8T9-;lsAvXXP7}m9O5GXg2pu+_EQKcK^!>uic~LUYyK6W93!K
zP&NPbtV<nR&%YJAA+%NZ;x@OFx${duIL?YG-=}@|Y~=^J4f9T3YhVj#$jLob^)I!K
zx$dUNuQ{9JLX2)4{(NCpv3`WTBb$Dd_#`*^(pFCn(@WOV?@885ylSiBTl9GI&V<CI
zcW-{K+kVnnJ-S;hG33NX+lQ5Njk0A^{=SHP&OXykZ&8=0Y%eHYJYD@<);T3K0RRqm
BxZnT)

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_heart_m.png b/img/misc/icon/shave_heart_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..280bf97ec125d2863b38010fe849a9824e488845
GIT binary patch
literal 532
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGivoN?T!AzMFfuX%8EUGk49v_7
zOiT<s+~RU_3_w9%J_a^c26lEJ(&XV`kdgwDK*j&T+WHt6lo=Qz85rI$Fw9|KILpAW
zkAdL^1H%;t22KWs3k(dY3=DxlV;LAuGB9jnVCZIGXk%cgW?(2{V322Ec*nr-l!4(M
z1H)kkhE)s<%NQ6c7#K1b7!ny6JQ*0A85jf@82<G4H3RJuE(!7rX88E}+ZXl+x3^0F
zxP9j2uEo=v1k69}ieX@2<nwfK4AD5h_EKj4Ap;(^2lHfhoA36VeaVSidc*HO|Lb!%
z1ut(2dviLDQ}dg$`wp)U`kco43)ctcK2TWpO;-EECWrhAe)pU1?T5V^gddyod@8=j
zzn}M~Xm#5}3%=Qgd6TwC*GWD${Z>AISFGpafMYA1R$Y6QqRM-8;;ZCCb8G@8Uhbd5
ze`TltjK@7(F0XgaQS5#jXA>KE{>e_p6&oMDoM2hSeo8rMA!AA7jN)WzLx1~J;iWI$
zpPaW^^Yhc~Z(N)5Hm~P?7OB0ab8CTh^1g|;y-ufw^VzLBw&{qj%;)0k5kjYD*A(p$
z4C~0cD=Pgk<+<FA*jM-7ygQRsb(Q1z=gK`3wlbewd(L7Omt{PA{c~}VABMfl<JNrx
OMUtnhpUXO@geCxQSG;Qg

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_strip_f.png b/img/misc/icon/shave_strip_f.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5fd34c598909ded5ff771446043c858a1992d48
GIT binary patch
literal 509
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGa{_!qT!AzYFfuX%Np?<7b}lX;
zhk=O+B+9|Tz{bYF!|mwcz`)L~$-~1SB?TlQivNRDF!V7nyk%feW?(qWz;K0uA(esQ
z1_Q$d28Kum1~mo-P6mck3=I1i7}^;a0vQ<i7#RLAFg#{pxXr+Dn1Nvv149u5gFFMn
zDh7sS3=ESQ7-|?8Di|0%85o=y7_=D}SUj%10NNp3666=m@ZsAhS&29IU)(;um37zR
z=}iJ$3q^f_iWvTSx;TbtoL@WXX3=2<9#_M2^GdFk`k3h#PD*=u@Bjbp*D@~5IOG#o
zG*2MCMZoE9i^^w@8fy*SQiG-MH!Adt?s>xf_p#9nwe_8y%cqNMknTPjy&_&wO2o0`
z(vgzM=OP|UToygFxtG)b{7J*}pLepb-hODbZo2d8%WF;jyeBLTdwnLXDI@Ok?q~aQ
zzA@bpzG`}L-xJ2%%B;oy>ux{$Ba*9k{l7${ZCN<8)&YipSJmztvHjUteDV5`SD6pZ
z`U1GNezD#9%Q5aP>)m=`n^#hM?R*yS8`cWczIxR)WAf#fk#;vOZ@yxey>0XEW3j&9
re^oub71np$H|^$@#_0R2U;klJ-e$11XWEn`P-J+z`njxgN@xNAT4uIX

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_strip_m.png b/img/misc/icon/shave_strip_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..5aab4972941d0d816a3a7d938fba4754cfd1da62
GIT binary patch
literal 523
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TG^8<WBT!Az)P*YW9W@2VwW@cbw
zV&LHxmjmfy;N@drV`X4x2O>=#9tJ5XAj!zc_#dpZkAXpnf#D4ULnH&kJ_d$43=B6I
z7|t><0PViQz;J<qA(eq4kbyysf#D<r!zKoX6$}h*3=Gu_3`GnK?-&@KGBDg@U^vXc
zFqwg&lYyavfgyu|A(4T>lYzmRfk9s4Vh7L`k&+<4V1|ERKE7uE{^0gj>2J5soZPi|
zdXvDW7|Ht#42<laE{-7@=ht4kUDRYCz?Q)DXyx;=>81*Sj%&ZwRQ*qXtuot}*Wj}B
zf9-!iZ=@)Ao}09$W71J8Bhxuc%r-veTBKtrrS_u5ZTaEXCw4t%t1_JKSa|=r?LR{v
zm4a(Lg_ED1`C)Y=`px>->wm9us&FrI)zE#NVti)4@bQ<6g&ziVP1(7D_2Oom!_vji
zmW8ia6Kz`K@LqEMarPTFieXX?;T?PaH~OdkVwG`aacJ3>x2$h{ea(80o8?;Z``62y
zk4o%iSkZcW=40!p)hA<4#oe91YNO6a1>V;9hRxezet(jwQ1|h=cy0RJf+`;IH;Vk_
z-zpByx^Hsm@z0t)Q_lOTeBV`YaodT{xu5Fm7^h?yee3*o<q0TaJYD@<);T3K0RUQI
ByNdt-

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_triangle_f.png b/img/misc/icon/shave_triangle_f.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c8714e757839017607738f99d57ec828b6e4297
GIT binary patch
literal 517
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TG^8<WBT!AzcFfp-naWOJ7G5`?-
zu(2`la639UF!1s*u(NCO@GwY80ZB<Yd5|&&hW}t?eGClB3=EMB3<V4fXBZf+Gca6c
zU^vgfkjB99hJoQI1H(QBhCl`e4F(1d28P=V44W7jRxmJhGcdF<FjO%x$TKhqFfed4
zFuY@6c*?-=kbz+`14AMMgC_%nGXukcgI7Veh?E5R1v7m4cu(T{8`&49x3b>ewRn1y
ztN_>bDGPlVfG+lQaSYKozjo5iqC*BeuENe5-ru7-H#?jN%2-(a`~Uqg6<0O2c@JBS
zD?3V_RXtJN!J$<aux{>_neQfUUDxhp{p3N*_g^i4m&nIu9h0xW&U|lO|HHQd`43lY
zWnUfo_HyZt7l*Rv$2HgII+i$vrcUAu4qTjQ9hIqMI@fn+T(3v_`iLnnj!wH#$r*V(
zf?+{Ax5-)aY}c1fwztH%ytFS}p6h0J!JISAJL}Cdn_K;FSd4ycF~0TYd>pgPhU=fL
zm2Lfhv9nGMIXmZztjA-?QoXAW0;U(3w&g6?U-Rqot6u+nm-dyl3H|=x&Mp(YebiTX
su`B;$jp@1UhxT@IHn;w{&-VN$`-LyY7RCYz<)A3>boFyt=akR{0N1jz)c^nh

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_triangle_m.png b/img/misc/icon/shave_triangle_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..5584f93ca5ba446077c891286d889d938ca9ec6d
GIT binary patch
literal 520
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TG(*k@#T!AzkFflQysj4zCGczzT
zF|e_T%gHhD@-eWpGw^UT@bGBz@GwY80ZB$i#{XbFN(>Br3=EMB4Eq=u@);Od7#QX-
zFx+5Z0NVPNf#C`R!x;vKGzNwX3=CBa41o*`Y77j=7#LPCFmy98v@tLgF)%!3V7SM?
zu!VtPJp;pJ28Kii22TbCX9k9E69py$tq>{+@(X78^6~W#_6N65OW)qLee>e!O#)&Y
zq`4Uw82LS2978nDuf240Qj>uIYk)(+%-UVfNdh8_rE_Zk{eQm9YOY&z$j?W$pS~Fe
zD0b#eQsJM}Vx?(bFwIxeYMtT<uI8g$Y=M(MAH98`?X>p}kIL)X@ANDC)!Qb1nX@JN
z&M`^jcgHH)AD^Gb@p)NqnBA=%j>oOm9!y=iS8wO_;Nu^qr*_3`S#(k{?c7R*Nt=}}
zJ(+D;xcYj=Nl$OP1<r?_Uu0P7q_f3vm&2Mn3myi~{L64$i*>=2H=E~K&inr}PQ&}Z
zX3gKZ)^%@MOqmvly_1u%kG{{ld15)Q{VKQQ4HMfA$=7XAoo4;>-skBXHidE4a~(ha
zuW4`E-?_HS*4(Vso}(xB(rcTnXI#m<MJrFdU;d)%AESeTe#h$nm5QLa@pScbS?83{
F1OVJAy50Z)

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_trim_f.png b/img/misc/icon/shave_trim_f.png
new file mode 100644
index 0000000000000000000000000000000000000000..df00fe33bac04d5445a3dc52799ced8c39d498ee
GIT binary patch
literal 514
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGa{_!qT!AzYFfuYi80=giEeuRd
z3>+K`Y-|iX+#oJ9GXp!jCJzsTloXJZl#>Ul{|}O2NM&H?V_@iHV0g#CaFT)HIs*eI
z1H)woh6@Y~XBikG85l|!7y=m>R2Uc@Gcep{U^vXcu!(_T1p|XR1A{yRg8&1=UIvEA
z3=BOC3^fc484L`G3=EzO49*M;+6)Yr5^7w4b_kaQ`2{n4`1bmfgzUZBr?+xF+_iXm
zldM2P`leW*)0sS7978nDuf24$tXV;TEy3Y(&fRp8i$_*uZhLq7_x|Y91rn-7w`Tu4
z&OP&ekAlKKRU>{SXWvy)Y%5n^C}ef?;+f@NFfG_9Cyx2grMQC{{hRmwG<e4Rjc204
zX|rRwuV$AUnw_}ccdR&_z4f9@@QqU!Uz#YNV^gf#t>S0uyR`c1v9P$Hq^XyERzyw=
z`@E(@wRHWB(x-eL-j9|r&bsp}JiVG*YmeHI&E--TzrSRhp5tZn|4H(J`5!*koaq#w
ztN$i|qvq4%$4x)l%HJL=s@#`-CVS6}1lvcsJ=@RxR+KKdS?wpiFX6lQzRkTwyY^)L
uy>#WS%hZ3{ThG5$Tb}dg!2bB|{hxW~+%ovGPqo_!6eFIlelF{r5}E*!_P4D7

literal 0
HcmV?d00001

diff --git a/img/misc/icon/shave_trim_m.png b/img/misc/icon/shave_trim_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..049aa13fccd1299764576750af80535ba60a5bfe
GIT binary patch
literal 507
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGlLLH0T!AzSU}IxoW@Z4AJlx`P
za=g5}%*@OzOw0`I?3z403{p}+l97?|KUhyH14ADJLni}6Bm;vA1H(H8hW!i-Cm9%S
zFfd$UV3@<ez{$XHfq~&H14AGK!wLq5Y6gZP1_pTshNlb+_ZS$qFfgnKx`KhBf`K8C
zfx(l3!I^<UfPq0cHs?Fge4&yczhH*X?_Ykq{owRgX^!vTcP*aYB;dJWjuQg|Bde#2
zV~EE2wU@3>YBu0u4amAx#+@TMX~Kj}d;k2ut}8a};6dZcld^IX&T$-5-Q_vylJ}eJ
zTW^kP{8sxYVRq=W)Sic%cburS;oHr~^tgA%6a8|oc1`(&1i_BSOLz;VKNpBTlA7Ua
za3+H*)_Z!?Y`$+++8y129o>?JIxoYE0wQPk*-l@x#J;hFE5U01&5WwYF=l@mPu5xe
z6;j((th$@sA^7nOq38Ga2)V2kteETSXY+sSS21hGJGVZi`|WW^ON}sm-1MV!f7sVE
z(Ka_jSVLLe3s2^6+h}~I{L|Hs?8Zz9x!vW@emv2;ar)HVo59y!zgn2OFJABcwLNb-
kKCkiWGGg6t?{@t&zmk={N6}^5`=IFXboFyt=akR{03Uv^;{X5v

literal 0
HcmV?d00001

-- 
GitLab


From 894d1f14e787a6ebd3c9b7a1dbeb172fec02284f Mon Sep 17 00:00:00 2001
From: ChexAndBalances <34724-ChexAndBalances@users.noreply.gitgud.io>
Date: Sat, 10 Sep 2022 23:15:41 +0000
Subject: [PATCH 31/50] Misc typos

---
 game/base-system/pregnancy/childrenEvents.twee | 8 ++++----
 game/overworld-forest/loc-cabin/events.twee    | 4 ++--
 game/overworld-town/loc-brothel/main.twee      | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/game/base-system/pregnancy/childrenEvents.twee b/game/base-system/pregnancy/childrenEvents.twee
index 911bb87c8b..2b0e4238e0 100644
--- a/game/base-system/pregnancy/childrenEvents.twee
+++ b/game/base-system/pregnancy/childrenEvents.twee
@@ -249,14 +249,14 @@
 		You sit down next to <<childname>> and begin to converse with the talkative <<childtype>>. Although you can't understand one another <<childhe>> smiles at your presence and begins to attempt to make similar sounds as you talk to <<childhim>>. Soon enough however <<childhe>> becomes distracted by <<childhis>> own hands and falls silent while you get back on your feet. <<llstress>><<stress -10>>
 		<<set $children[$childActivityEvent.childid].localVariables.activity to "thumbSucking">>
 	<<case "nappyChange">>
-		You notice <<childname>> looking uncomfortable and notice a telling stink coming from <<childhim>>. You fetch a spare nappy and go over to <<childhim>>, laying him flat and removing the old nappy. You clean the <<childtype>>'s bottom diligently and place the fresh nappy on <<childhim>>. Freshly cleaned and changed, <<childname>> looks up at you and smiles before you go to dispose of the dirty nappy. <<gstress>><<stress 5>>
+		You notice <<childname>> looking uncomfortable and notice a telling stink coming from <<childhim>>. You fetch a spare nappy and go over to <<childhim>>, laying <<childhim>> flat and removing the old nappy. You clean the <<childtype>>'s bottom diligently and place the fresh nappy on <<childhim>>. Freshly cleaned and changed, <<childname>> looks up at you and smiles before you go to dispose of the dirty nappy. <<gstress>><<stress 5>>
 		<<set $children[$childActivityEvent.childid].localVariables.activity to "sleeping">>
 	<<case "crawlingAttempt">>
 		Walking over to <<childname>> you see that <<childhe>> is stuck on <<childhis>> belly and is trying to move <<childhimself>> forward. You sit down next to the <<childtype>> and take <<childhis>> hands in your, place them on the floor and hold them there to give <<childhim>> leverage. Soon enough <<childname>> is pulling <<childhimself>> across the floor with your help, bewildered and amused at <<childhis>> own mobility. After a while <<childhe>> seems to get the hang of it and you leave <<childhim>> clumsily crawling on <<childhis>> own. <<lstress>><<stress -5>>
 		<<set $children[$childActivityEvent.childid].localVariables.activity to "sleeping">>
 		<<set $children[$childActivityEvent.childid].localVariables.crawling++>>
 	<<case "crawlingAttempt2">>
-		Taking the <<childtype>>'s hands in yours you hoist <<childhim>> up by them, leaving only <<childhis>> feet on the ground. Confused at first <<childname>> flails <<childhis>> legs until <<childhe>> snags the ground with a kick and propels <<childhimself>> forward. <<childname's>> eyes go wide at the revelation and soon enough, with some effort and failed triesm, you have <<childhim>> moving with <<childhis>> own legs, and your help keeping him upright of course. After a while of this exercise <<childhe>> grows tired and you let <<childhim>> down again. <<llstress>><<stress -10>>
+		Taking the <<childtype>>'s hands in yours you hoist <<childhim>> up by them, leaving only <<childhis>> feet on the ground. Confused at first, <<childname>> flails <<childhis>> legs until <<childhe>> snags the ground with a kick and propels <<childhimself>> forward. <<childname's>> eyes go wide at the revelation and soon enough, with some effort and failed tries, you have <<childhim>> moving with <<childhis>> own legs, and your help keeping <<childhim>> upright of course. After a while of this exercise, <<childhe>> grows tired and you let <<childhim>> down again. <<llstress>><<stress -10>>
 		<<set $children[$childActivityEvent.childid].localVariables.activity to "sleeping">>
 	<<case "grumpyChild">>
 		<<childname>> sits alone and wears a scowl on <<childhis>> infant face. You walk over and sit down next to <<childhim>> but <<childhe>> seems to ignore you. Unable to help but smile at the grumpy child's expression you begin to tickle <<childhim>>. While perhaps not ticklish at this age <<childname>> is still deeply amused by your teasing fingers and the silly noises you make as you playfully attack <<childhis>> sides. Soon enough the scowl is gone and the <<childtype>> is giggling and smiling. Mission accomplished, you stand back up. <<lstress>><<stress -5>>
@@ -342,9 +342,9 @@
 	<<case "hungeryWolf">>
 		You move over to <<childname>> and see that <<childhe>>'s trying to find a way through the other pups to reach the female wolf's nipples to feed.
 		<br><br>
-		You pick <<childhim>> up and pet him gently, keeping the poor <<childcry>> <<childtype>>'s attention off <<childhis>> hunger. Soon enough several of the feeding pups finish and you put down <<childname>> in front of the female wolf's belly, the <<childtype>> eagerly latching on to one of her nipples and sucking greedily. <<lstress>><<stress -5>>
+		You pick <<childhim>> up and pet <<childhim>> gently, keeping the poor <<childcry>> <<childtype>>'s attention off <<childhis>> hunger. Soon enough several of the feeding pups finish and you put down <<childname>> in front of the female wolf's belly, the <<childtype>> eagerly latching on to one of her nipples and sucking greedily. <<lstress>><<stress -5>>
 		<<set $children[$childActivityEvent.childid].localVariables.activity to "sleeping">>
 <</switch>>
 <br><br>
 
-<<link [[next|Childrens Home]]>><<unset $childActivityEvent>><<endevent>><</link>>
\ No newline at end of file
+<<link [[next|Childrens Home]]>><<unset $childActivityEvent>><<endevent>><</link>>
diff --git a/game/overworld-forest/loc-cabin/events.twee b/game/overworld-forest/loc-cabin/events.twee
index d86444f0b9..56158a05c2 100644
--- a/game/overworld-forest/loc-cabin/events.twee
+++ b/game/overworld-forest/loc-cabin/events.twee
@@ -974,7 +974,7 @@ You nod slightly. Eden looks worried, but doesn't push you. <<His>> hold seems s
 :: Eden Cuddle Trauma Honest
 <<set $outside to 0>><<set $location to "cabin">><<effects>>
 
-You tell Eden about your grievances. It starts out small at first. You begin by describing how you've been continuously approached. Somehow, in the minutes that pass, the conversation spirals into you detailing about the suffering you've went through.
+You tell Eden about your grievances. It starts out small at first. You begin by describing how you've been continuously approached. Somehow, in the minutes that pass, the conversation spirals into you detailing about the suffering you've gone through.
 About how you're so overwhelmed by everything. You're vaguely aware that you've started crying.
 <br><br>
 
@@ -3514,4 +3514,4 @@ Grabbing a cup of water from the kitchen, you walk over to Eden and gently shake
 "No promises," <<he>> replies, standing up. As <<he>> walks past you, <<he>> pulls you close and lays a quick kiss on your forehead. "Thanks," <<he>> says, walking off and leaving you by the dining table.
 <br><br>
 
-<<link [[Next|Eden Cabin]]>><<endevent>><</link>>
\ No newline at end of file
+<<link [[Next|Eden Cabin]]>><<endevent>><</link>>
diff --git a/game/overworld-town/loc-brothel/main.twee b/game/overworld-town/loc-brothel/main.twee
index b029fe5a11..df9352bfa7 100644
--- a/game/overworld-town/loc-brothel/main.twee
+++ b/game/overworld-town/loc-brothel/main.twee
@@ -1100,7 +1100,7 @@ Someone sticks their $NPCList[0].penisdesc through the hole, and against your li
 
 <<link [[Next|Brothel Punishment Gloryhole]]>><</link>>
 <<else>>
-The <<person>> recoils from the hole. You hear <<him>> shout at someone, then silence. <<endevent>><<npc Briar>><<person1>>A minute later Briar opens your cell. "I was so trying to be nice," <<he>> says. "But if you're going to behave so poorly, there's only one option." <<He>> unclips your neck, then pulls a level at the base of the wall. The hole expands several times in size. <<He>> shoves you through the hole, leaving your legs and bottom exposed, before clipping you in place once more. "There. Now our customers get to enjoy a less violent part of you." <<He>> slams the door shut this time.
+The <<person>> recoils from the hole. You hear <<him>> shout at someone, then silence. <<endevent>><<npc Briar>><<person1>>A minute later Briar opens your cell. "I was so trying to be nice," <<he>> says. "But if you're going to behave so poorly, there's only one option." <<He>> unclips your neck, then pulls a lever at the base of the wall. The hole expands several times in size. <<He>> shoves you through the hole, leaving your legs and bottom exposed, before clipping you in place once more. "There. Now our customers get to enjoy a less violent part of you." <<He>> slams the door shut this time.
 <br><br>
 <<endcombat>>
 <<set $punishmenthole += 1>><<pass 1>><<set $punishmentposition to "wall">>
-- 
GitLab


From 662885a050d49d758d3ad8b0c694d6a321d871ea Mon Sep 17 00:00:00 2001
From: hwp <22502-hwp@users.noreply.gitgud.io>
Date: Sat, 10 Sep 2022 23:25:33 +0000
Subject: [PATCH 32/50] Hypnotism improvements, school widgets-events
 formatting, relationshiptext cleanup

---
 game/base-combat/man-combat.twee              | 189 ++--
 game/base-combat/widgets.twee                 |  68 +-
 game/base-system/named-npcs.twee              |  95 +-
 game/base-system/text.twee                    |  77 +-
 .../loc-school/widgets-events.twee            | 867 +++++++++---------
 game/overworld-town/special-kylar/main.twee   |   3 +-
 6 files changed, 606 insertions(+), 693 deletions(-)

diff --git a/game/base-combat/man-combat.twee b/game/base-combat/man-combat.twee
index 693ccc351f..791f77bd5a 100644
--- a/game/base-combat/man-combat.twee
+++ b/game/base-combat/man-combat.twee
@@ -12,6 +12,16 @@
 	<</if>>
 <</widget>>
 
+<!-- pass "left" or "right" for which NPC tool this is called for -->
+<<widget "combat-reset-tool">>
+	<<if _args[0] is "both">>
+		<<set $NPCList[_n].lefttool to 0>>
+		<<set $NPCList[_n].righttool to 0>>
+	<<else>>
+		<<set $NPCList[_n][_args[0]+"tool"] to 0>>
+	<</if>>
+<</widget>>
+
 <!-- pass "left" or "right" for which NPC hand this is called for, and the name of the targeted PC body part -->
 <<widget "combat-set-hand-target">>
 	<<set $NPCList[_n][_args[0]+"hand"] to _args[1]>>
@@ -770,128 +780,95 @@ Hands are 'inverted': NPC holds PC's left hand with their right one, and vice ve
 <</widget>>
 
 <<widget "combat-hand-hypnosis">>
-<<rng>>
-<<if $rng gte 76 and ($hypnosis_traits.scream is undefined or $hypnosis_traits.scream lt 5)>>
-	<<if _args[0] is "left">>
-		<<He>> waves the <<print $NPCList[_n].lefttool>> at you.
-		<<set $NPCList[_n].lefthand to "hypnosis_scream">>
-	<<else>>
-		<<He>> waves the <<print $NPCList[_n].righttool>> at you.
-		<<set $NPCList[_n].righthand to "hypnosis_scream">>
-	<</if>>
-	<<His>> voice echoes in your mind. <span class="purple"><i><span class="red">From when I click my fingers,</span> should you try to scream, you will beg for rougher treatment instead.</i></span>
-<<elseif $rng gte 51 and ($hypnosis_traits.cover is undefined or $hypnosis_traits.cover lt 5)>>
-	<<if _args[0] is "left">>
-		<<He>> waves the <<print $NPCList[_n].lefttool>> at you.
-		<<set $NPCList[_n].lefthand to "hypnosis_cover">>
-	<<else>>
-		<<He>> waves the <<print $NPCList[_n].righttool>> at you.
-		<<set $NPCList[_n].righthand to "hypnosis_cover">>
-	<</if>>
-	<<His>> voice echoes in your mind. <span class="purple"><i><span class="red">From when I click my fingers,</span> should you try to cover your body, you will display it for all to see instead.</i></span>
-<<else>>
-	<<if random(1, 2) is 2>>
-		<<His>> voice echoes in your mind. <span class="purple"><i>When I click my fingers, you will be overcome by arousal, and climax at once.</i></span>
-		<<if _args[0] is "left">>
-			<<He>> waves the <<print $NPCList[_n].lefttool>> at you.
-			<<set $NPCList[_n].lefthand to "hypnosis_orgasm">>
-		<<else>>
-			<<He>> waves the <<print $NPCList[_n].righttool>> at you.
-			<<set $NPCList[_n].righthand to "hypnosis_orgasm">>
-		<</if>>
+	<<rng>>
+	<<set _tool to (_args[0] is "left" ? $NPCList[_n].lefttool : $NPCList[_n].righttool)>>
+	<<set $_hand to _args[0] + "hand">>
+	<<if $rng gte 76 and ($hypnosis_traits.scream is undefined or $hypnosis_traits.scream lt 5)>>
+		<<He>> waves the _tool at you.
+		<<set $NPCList[_n][$_hand] to "hypnosis_scream">>
+		<<His>> voice echoes in your mind. <span class="purple"><i><span class="red">From when I click my fingers,</span> should you try to scream, you will beg for rougher treatment instead.</i></span>
+	<<elseif $rng gte 51 and ($hypnosis_traits.cover is undefined or $hypnosis_traits.cover lt 5)>>
+		<<He>> waves the _tool at you.
+		<<set $NPCList[_n][$_hand] to "hypnosis_cover">>
+		<<His>> voice echoes in your mind. <span class="purple"><i><span class="red">From when I click my fingers,</span> should you try to cover your body, you will display it for all to see instead.</i></span>
 	<<else>>
-		<<His>> voice echoes in your mind. <span class="purple"><i>When I click my fingers, you will lust for the pleasure of pain.</i></span>
-		<<if _args[0] is "left">>
-			<<He>> waves the <<print $NPCList[_n].lefttool>> at you.
-			<<set $NPCList[_n].lefthand to "hypnosis_masochism">>
+		<<if random(1, 2) is 2>>
+			<<His>> voice echoes in your mind. <span class="purple"><i>When I click my fingers, you will be overcome by arousal, and climax at once.</i></span>
+			<<set $NPCList[_n][$_hand] to "hypnosis_orgasm">>
 		<<else>>
-			<<He>> waves the <<print $NPCList[_n].righttool>> at you.
-			<<set $NPCList[_n].righthand to "hypnosis_masochism">>
+			<<His>> voice echoes in your mind. <span class="purple"><i>When I click my fingers, you will lust for the pleasure of pain.</i></span>
+			<<set $NPCList[_n][$_hand] to "hypnosis_masochism">>
 		<</if>>
+		<<He>> waves the _tool at you.
 	<</if>>
-<</if>>
 <</widget>>
 
 <<widget "combat-hand-hypnosis-orgasm">>
-<<He>> clasps <<his>> palm around the
-<<if _args[0] is "left">>
-	<<print $NPCList[_n].lefttool>>,
-	<<set $NPCList[_n].lefttool to 0>>
-<<else>>
-	<<print $NPCList[_n].righttool>>,
-	<<set $NPCList[_n].righttool to 0>>
-<</if>>
-and clicks <<his>> fingers. A deep yearning blooms,
-<<if $uncomfortable.hypnosis is false>>
-	nurtured by a lewd part of you. <span class="lewd">Your mind immediately accepts it.</span> Feelings of arousal overwhelm you. <<He>> flashes you a satisfied smile. <<arousal 10000>>
-<<elseif $willpower gte random(1, 1000)>>
-	nurtured by a traitorous part of you. <span class="lblue">You will it away.</span> <<He>> frowns.
-<<else>>
-	unbeckoned. <span class="pink">You can't resist it.</span> Feelings of arousal overwhelm you. <<He>> flashes you a satisfied smile. <<arousal 10000>><<willpower 1>><<gwillpower>>
-<</if>>
-<<combat-reset-hand _args[0]>>
+	<<set _tool to (_args[0] is "left" ? $NPCList[_n].lefttool : $NPCList[_n].righttool)>>
+	<<He>> clasps <<his>> palm around the _tool, and clicks <<his>> fingers.
+
+	A deep yearning blooms,
+	<<if $uncomfortable.hypnosis is false>>
+		nurtured by a lewd part of you. <span class="lewd">Your mind immediately accepts it.</span> Feelings of arousal overwhelm you. <<He>> flashes you a satisfied smile.
+		<<arousal 10000>>
+	<<elseif $willpower gte random(1, 1000)>>
+		nurtured by a traitorous part of you. <span class="lblue">You will it away.</span> <<He>> frowns.
+	<<else>>
+		unbeckoned. <span class="pink">You can't resist it.</span> Feelings of arousal overwhelm you. <<He>> flashes you a satisfied smile.
+		<<arousal 10000>><<willpower 1>><<gwillpower>>
+	<</if>>
+	<<combat-reset-tool _args[0]>>
+	<<combat-reset-hand _args[0]>>
 <</widget>>
 
 <<widget "combat-hand-hypnosis-masochism">>
-<<He>> clasps <<his>> palm around the
-<<if _args[0] is "left">>
-	<<print $NPCList[_n].lefttool>>,
-	<<set $NPCList[_n].lefttool to 0>>
-<<else>>
-	<<print $NPCList[_n].righttool>>,
-	<<set $NPCList[_n].righttool to 0>>
-<</if>>
-and clicks <<his>> fingers. A deep yearning blooms,
-<<if $uncomfortable.hypnosis is false>>
-	nurtured by a lewd part of you. <span class="lewd">Your mind immediately accepts it.</span> You long for pain. <<He>> flashes you a satisfied smile. <<masochism 10>>
-<<elseif $willpower gte random(1, 1000)>>
-	nurtured by a traitorous part of you. <span class="lblue">You will it away.</span> <<He>> frowns.
-<<else>>
-	unbeckoned. <span class="pink">You can't resist it.</span> You long for pain. <<He>> flashes you a satisfied smile. <<masochism 10>><<willpower 1>><<gwillpower>>
-<</if>>
-<<combat-reset-hand _args[0]>>
+	<<set _tool to (_args[0] is "left" ? $NPCList[_n].lefttool : $NPCList[_n].righttool)>>
+	<<He>> clasps <<his>> palm around the _tool, and clicks <<his>> fingers.
+
+	A deep yearning blooms,
+	<<if $uncomfortable.hypnosis is false>>
+		nurtured by a lewd part of you. <span class="lewd">Your mind immediately accepts it.</span> You long for pain. <<He>> flashes you a satisfied smile.
+		<<masochism 10>>
+	<<elseif $willpower gte random(1, 1000)>>
+		nurtured by a traitorous part of you. <span class="lblue">You will it away.</span> <<He>> frowns.
+	<<else>>
+		unbeckoned. <span class="pink">You can't resist it.</span> You long for pain. <<He>> flashes you a satisfied smile.
+		<<masochism 10>><<willpower 1>><<gwillpower>>
+	<</if>>
+	<<combat-reset-tool _args[0]>>
+	<<combat-reset-hand _args[0]>>
 <</widget>>
 
 <<widget "combat-hand-hypnosis-scream">>
-<<He>> clasps <<his>> palm around the
-<<if _args[0] is "left">>
-	<<print $NPCList[_n].lefttool>>,
-	<<set $NPCList[_n].lefttool to 0>>
-<<else>>
-	<<print $NPCList[_n].righttool>>,
-	<<set $NPCList[_n].righttool to 0>>
-<</if>>
-and clicks <<his>> fingers.
-<span class="pink">You feel something shift in your consciousness.</span>
-<<if !$hypnosis_traits.scream>>
-	You've gained the <span class="pink">Hypnotic Yearning</span> trait.
-	<<set $hypnosis_traits.scream to 1>>
-<<elseif $hypnosis_traits.scream lt 5>>
-	Your hypnotic yearning has deepened.
-	<<set $hypnosis_traits.scream += 1>>
-<</if>>
-<<combat-reset-hand _args[0]>>
+	<<set _tool to (_args[0] is "left" ? $NPCList[_n].lefttool : $NPCList[_n].righttool)>>
+	<<He>> clasps <<his>> palm around the _tool, and clicks <<his>> fingers.
+	
+	<span class="pink">You feel something shift in your consciousness.</span>
+	<<if !$hypnosis_traits.scream>>
+		You've gained the <span class="pink">Hypnotic Yearning</span> trait.
+		<<set $hypnosis_traits.scream to 1>>
+	<<elseif $hypnosis_traits.scream lt 5>>
+		Your hypnotic yearning has deepened.
+		<<set $hypnosis_traits.scream += 1>>
+	<</if>>
+	<<combat-reset-tool _args[0]>>
+	<<combat-reset-hand _args[0]>>
 <</widget>>
 
 <<widget "combat-hand-hypnosis-cover">>
-<<He>> clasps <<his>> palm around the
-<<if _args[0] is "left">>
-	<<print $NPCList[_n].lefttool>>,
-	<<set $NPCList[_n].lefttool to 0>>
-<<else>>
-	<<print $NPCList[_n].righttool>>,
-	<<set $NPCList[_n].righttool to 0>>
-<</if>>
-and clicks <<his>> fingers.
-<span class="pink">You feel something shift in your consciousness.</span>
-<<if !$hypnosis_traits.cover>>
-	You've gained the <span class="pink">Hypnotic Flaunting</span> trait.
-	<<set $hypnosis_traits.cover to 1>>
-<<elseif $hypnosis_traits.cover lt 5>>
-	Your hypnotic flaunting has deepened.
-	<<set $hypnosis_traits.cover += 1>>
-<</if>>
-<<combat-reset-hand _args[0]>>
+	<<set _tool to (_args[0] is "left" ? $NPCList[_n].lefttool : $NPCList[_n].righttool)>>
+	<<He>> clasps <<his>> palm around the _tool, and clicks <<his>> fingers.
+
+	<span class="pink">You feel something shift in your consciousness.</span>
+	<<if !$hypnosis_traits.cover>>
+		You've gained the <span class="pink">Hypnotic Flaunting</span> trait.
+		<<set $hypnosis_traits.cover to 1>>
+	<<elseif $hypnosis_traits.cover lt 5>>
+		Your hypnotic flaunting has deepened.
+		<<set $hypnosis_traits.cover += 1>>
+	<</if>>
+	<<combat-reset-tool _args[0]>>
+	<<combat-reset-hand _args[0]>>
 <</widget>>
 
 <<widget "combat-hand-on-mouth">>
diff --git a/game/base-combat/widgets.twee b/game/base-combat/widgets.twee
index 603da86575..8693327aec 100644
--- a/game/base-combat/widgets.twee
+++ b/game/base-combat/widgets.twee
@@ -112,57 +112,27 @@
 <</widget>>
 
 <<widget "takeKissVirginityNamed">>
-<<switch _args[0]>>
-	<<case "Robin">>
-		<<if $robinromance is 1>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Whitney">>
-		<<if $whitneyromance is 1>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Kylar">>
-		<<if $kylarenglish gte 1>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Sydney">>
-		<<if $sydneyromance is 1>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Eden">>
-		<<if $syndromeeden is 1>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Avery">>
-		<<if $dateCount.Avery gte 3>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Black Wolf">>
-		<<if $syndromewolves is 1 and $deviancy gte 35>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Great Hawk">>
-		<<if $syndromebird is 1>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<case "Alex">>
-		<<if $farm_stage gte 7 and $alex_countdown is undefined>>
-			<<set _loveInterest to true>>
-		<</if>>
-	<<default>>
-		<<set _loveInterest to false>>
-<</switch>>
-<<if _loveInterest is true>>
-	<<if $consensual is 1 or _args[2]>>
-		<<takeKissVirginity _args[0] "loveInterest">>
+	<<switch _args[0]>>
+		<<case "Robin">>      <<set $_isLoveInterest to ($robinromance is 1)>>
+		<<case "Whitney">>    <<set $_isLoveInterest to ($whitneyromance is 1)>>
+		<<case "Kylar">>      <<set $_isLoveInterest to ($kylarenglish gte 1)>>
+		<<case "Sydney">>     <<set $_isLoveInterest to ($sydneyromance is 1)>>
+		<<case "Eden">>       <<set $_isLoveInterest to ($syndromeeden is 1)>>
+		<<case "Avery">>      <<set $_isLoveInterest to ($dateCount.Avery gte 3)>>
+		<<case "Black Wolf">> <<set $_isLoveInterest to ($syndromewolves is 1 and $deviancy gte 35)>>
+		<<case "Great Hawk">> <<set $_isLoveInterest to ($syndromebird is 1)>>
+		<<case "Alex">>       <<set $_isLoveInterest to ($farm_stage gte 7 and $alex_countdown is undefined)>>
+		<<default>>           <<run throw new Error("wrong argument passed to takeKissVirginityNamed: ", _args)>>
+	<</switch>>
+
+	<<set $_isConsensual to _args[1] or ($consensual is 1)>>
+
+	<<if $_isLoveInterest>>
+		<<set $_kissType to ($_isConsensual ? "loveInterest" : "loveRape")>>
 	<<else>>
-		<<takeKissVirginity _args[0] "loveRape">>
+		<<set $_kissType to ($_isConsensual ? "consensual" : "rape")>>
 	<</if>>
-<<elseif ($consensual is 1 or _args[2])>>
-	<<takeKissVirginity _args[0] "consensual">>
-<<else>>
-	<<takeKissVirginity _args[0] "rape">>
-<</if>>
+	<<takeKissVirginity _args[0] $_kissType>>
 <</widget>>
 
 /* Argument 0 is the npc, argument 1 is their virginity. */
diff --git a/game/base-system/named-npcs.twee b/game/base-system/named-npcs.twee
index 940c3155d6..c016d1c01a 100644
--- a/game/base-system/named-npcs.twee
+++ b/game/base-system/named-npcs.twee
@@ -984,17 +984,13 @@ alternative way to write that:
 <</widget>>
 
 <<widget "npcrelationship">>
-<!-- Robin, Avery, Kylar are unique and are treated differently -->
-<<set _nam to _args[0]>>
-<<set _i to $NPCNameList.indexOf(_nam)>>
-<<if $NPCName[_i].init is 1>>
-	<<set $npctextlove to $NPCName[_i].love>>
-	<<set $npctextdom to $NPCName[_i].dom>>
-	<<set $npctextname to _nam>>
-	<<set $npctextdescription to $NPCName[_i].title>>
-	<<relationshiptext _nam>>
-	<br>
-<</if>>
+	<!-- Robin, Avery, Kylar are unique and are treated differently -->
+	<<set _npc to _args[0]>>
+	<<set _i to $NPCNameList.indexOf(_npc)>>
+	<<if $NPCName[_i].init is 1>>
+		<<relationshiptext>>
+		<br>
+	<</if>>
 <</widget>>
 
 <<widget "npcincr">>
@@ -1114,8 +1110,6 @@ alternative way to write that:
 <</widget>>
 
 <<widget "relationshiptext">>
-<<set _npc to _args[0]>>
-<<set _i to $NPCNameList.indexOf(_npc)>>
 <!-- Special cases for Robin, Avery, Kylar -->
 <<switch _npc>>
 	<<case Robin>>
@@ -1147,7 +1141,7 @@ alternative way to write that:
 		<</if>>
 	<<case Avery>>
 		Avery
-		<<if $NPCName[$NPCNameList.indexOf("Avery")].state is "dismissed">>
+		<<if $NPCName[_i].state is "dismissed">>
 			<span class="red">has moved on.</span>
 		<<elseif $NPCName[_i].rage gte 96>>
 			<span class="red">has given up on you.</span>
@@ -1178,7 +1172,7 @@ alternative way to write that:
 		<</if>>
 	<<case Kylar>>
 		Kylar
-		<<if $NPCName[$NPCNameList.indexOf("Kylar")].state is "prison" and $location isnot "prison">>
+		<<if $NPCName[_i].state is "prison" and $location isnot "prison">>
 				<span class="red"> is imprisoned.</span>
 		<<elseif $NPCName[_i].love gte 90>>
 			<<if $NPCName[_i].rage gte 90>>
@@ -1223,28 +1217,28 @@ alternative way to write that:
 		<</if>>
 	<<case Whitney>>
 		Whitney
-		<<if $NPCName[$NPCNameList.indexOf("Whitney")].state is "dungeon">>
+		<<if $NPCName[_i].state is "dungeon">>
 			<span class="red">is gone.</span>
-		<<elseif $npctextlove gte $npclovehigh>>
-			<<if $npctextdom gte $npcdomhigh>>
+		<<elseif $NPCName[_i].love gte $npclovehigh>>
+			<<if $NPCName[_i].dom gte $npcdomhigh>>
 				thinks you're <span class="green">adorable.</span>
-			<<elseif $npctextdom lte $npcdomlow>>
+			<<elseif $NPCName[_i].dom lte $npcdomlow>>
 				thinks you're <span class="green">inspiring.</span>
 			<<else>>
 				thinks you're <span class="green">delightful.</span>
 			<</if>>
-		<<elseif $npctextlove lte $npclovelow>>
-			<<if $npctextdom gte $npcdomhigh>>
+		<<elseif $NPCName[_i].love lte $npclovelow>>
+			<<if $NPCName[_i].dom gte $npcdomhigh>>
 				thinks you're <span class="red">pathetic.</span>
-			<<elseif $npctextdom lte $npcdomlow>>
+			<<elseif $NPCName[_i].dom lte $npcdomlow>>
 				thinks you're <span class="red">irritating.</span>
 			<<else>>
 				thinks you're <span class="red">terrible.</span>
 			<</if>>
 		<<else>>
-			<<if $npctextdom gte $npcdomhigh>>
+			<<if $NPCName[_i].dom gte $npcdomhigh>>
 				thinks you're <span class="pink">cute.</span>
-			<<elseif $npctextdom lte $npcdomlow>>
+			<<elseif $NPCName[_i].dom lte $npcdomlow>>
 				<span class="teal">looks up to you.</span>
 			<<else>>
 				has no strong opinion of you.
@@ -1379,31 +1373,32 @@ alternative way to write that:
 			has no strong opinion of you.
 		<</if>>
 
-<!-- Default cases for all other NNPCs -->
+	<!-- Default cases for all other NNPCs -->
 	<<default>>
-		<<if $npctextlove gte $npclovehigh>>
-			<<if $npctextdom gte $npcdomhigh>>
-			$npctextname thinks you're <span class="green">adorable.</span>
-			<<elseif $npctextdom lte $npcdomlow>>
-			$npctextname thinks you're <span class="green">inspiring.</span>
+		_npc
+		<<if $NPCName[_i].love gte $npclovehigh>>
+			<<if $NPCName[_i].dom gte $npcdomhigh>>
+				thinks you're <span class="green">adorable.</span>
+			<<elseif $NPCName[_i].dom lte $npcdomlow>>
+				thinks you're <span class="green">inspiring.</span>
 			<<else>>
-			$npctextname thinks you're <span class="green">delightful.</span>
+				thinks you're <span class="green">delightful.</span>
 			<</if>>
-		<<elseif $npctextlove lte $npclovelow>>
-			<<if $npctextdom gte $npcdomhigh>>
-			$npctextname thinks you're <span class="red">pathetic.</span>
-			<<elseif $npctextdom lte $npcdomlow>>
-			$npctextname thinks you're <span class="red">irritating.</span>
+		<<elseif $NPCName[_i].love lte $npclovelow>>
+			<<if $NPCName[_i].dom gte $npcdomhigh>>
+				thinks you're <span class="red">pathetic.</span>
+			<<elseif $NPCName[_i].dom lte $npcdomlow>>
+				thinks you're <span class="red">irritating.</span>
 			<<else>>
-			$npctextname thinks you're <span class="red">terrible.</span>
+				thinks you're <span class="red">terrible.</span>
 			<</if>>
 		<<else>>
-			<<if $npctextdom gte $npcdomhigh>>
-			$npctextname thinks you're <span class="pink">cute.</span>
-			<<elseif $npctextdom lte $npcdomlow>>
-			$npctextname <span class="teal">looks up to you.</span>
+			<<if $NPCName[_i].dom gte $npcdomhigh>>
+				thinks you're <span class="pink">cute.</span>
+			<<elseif $NPCName[_i].dom lte $npcdomlow>>
+				<span class="teal">looks up to you.</span>
 			<<else>>
-			$npctextname has no strong opinion of you.
+				has no strong opinion of you.
 			<</if>>
 		<</if>>
 <</switch>>
@@ -1413,21 +1408,9 @@ alternative way to write that:
 <!-- Can be used in any situation to let all active named NPCs known the player's gender -->
 <!-- Use _args[0] to ignore clothing -->
 <!-- Won't ignore the chastity belt's "hidden" property (for now) -->
-<<if _args[0]>>
+<<if _args[0] or $exposed gte 2>>
 	<<if !$worn.genitals.type.includes("hidden")>>
-		<<if $npc.length gt 0>>
-			<<for _i to 0; _i lt $npc.length; _i++>>
-				<<set $genderknown.pushUnique($npc[_i])>>
-			<</for>>
-		<</if>>
-	<</if>>
-<<else>>
-	<<if $exposed gte 2 and !$worn.genitals.type.includes("hidden")>>
-		<<if $npc.length gt 0>>
-			<<for _i to 0; _i lt $npc.length; _i++>>
-				<<set $genderknown.pushUnique($npc[_i])>>
-			<</for>>
-		<</if>>
+		<<run $npc.forEach(npc => $genderknown.pushUnique(npc))>>
 	<</if>>
 <</if>>
 <</widget>>
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index 2265dc8570..801d2db12d 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -1205,6 +1205,12 @@
 	<<combatperson>><<capitalise>>
 <</silently>><<print _text_output>><</widget>>
 
+<<widget "genderswapPlayer">>
+	<!-- Note: You'll want to call this again when you're done, because its effects are visible on the sidebar caption if you leave it swapped, and we don't want that. -->
+	<!-- Note 2: gender_appearance is recalculated at the start of each passage, so don't expect the effects to stick around. -->
+	<<set $player.gender_appearance to ($player.gender_appearance is "f" ? "m" : "f")>>
+<</widget>>
+
 <<widget "genderswap">>
 	<!-- Changes the current pronoun, without modifying the NPC it's referencing. Useful for crossdressing NPC dialogue. -->
 	<!-- Usage: <<person1>><<genderswap>><<he>> -->
@@ -1375,52 +1381,45 @@
 <</silently>><<print _text_output>><</widget>>
 
 <<widget "genitalsensitivity">><<silently>>
-<<if $genitalsensitivity > 5>>
-	<<set _text_output2 to "sensitive ">>
-<<elseif $genitalsensitivity >= 3>>
-	<<set _text_output2 to "tender ">>
-<<elseif $genitalsensitivity >= 1.5>>
-	<<set _text_output2 to "receptive ">>
-<<else>>
-	<<set _text_output2 to "">>
-<</if>>
-<</silently>><<print _text_output2>><</widget>>
-
-<<widget "genitals">><<silently>>
-<<if $worn.genitals.type.includes("chastity") and _args[0] is undefined and _chastityBreak isnot 1>>
-	<<set _text_output to $worn.genitals.name>>
-<<else>>
-	<<set _text_output to "">>
 	<<if $genitalsensitivity > 5>>
-		<<set _text_output += "sensitive ">>
+		<<set _text_output2 to "sensitive ">>
 	<<elseif $genitalsensitivity >= 3>>
-		<<set _text_output += "tender ">>
+		<<set _text_output2 to "tender ">>
 	<<elseif $genitalsensitivity >= 1.5>>
-		<<set _text_output += "receptive ">>
-	<</if>>
-	<<if $player.penisExist>>
-		<<if $player.virginity.penile is true and _args[0] isnot 2>>
-			<<set _text_output += "virgin ">>
-		<</if>>
-		<<set _text_output += "penis">>
-	<</if>>
-	<<if $player.penisExist and $player.vaginaExist>>
-		<<set _text_output += " and ">>
+		<<set _text_output2 to "receptive ">>
+	<<else>>
+		<<set _text_output2 to "">>
 	<</if>>
-	<<if $player.vaginaExist>>
-		<<if $player.virginity.vaginal is true and _args[0] isnot 2>>
-			<<set _text_output += "virgin ">>
+<</silently>><<print _text_output2>><</widget>>
+
+<<widget "genitals">><<silently>>
+	<<if $worn.genitals.type.includes("chastity") and _args[0] is undefined and _chastityBreak isnot 1>>
+		<<set _text_output to $worn.genitals.name>>
+	<<else>>
+		<<genitalsensitivity>><<set _text_output to _text_output2>>
+		<<if $player.penisExist>>
+			<<if $player.virginity.penile is true and _args[0] isnot 2>>
+				<<set _text_output += "virgin ">>
+			<</if>>
+			<<set _text_output += "penis">>
 		<</if>>
-		<<if $pblevel gte 8 and $vaginaWetness gte 75 and $pbdisable is "f">>
-			<<set _text_output += "visibly aroused and bushy ">>
-		<<elseif $vaginaWetness gte 75>>
-			<<set _text_output += "visibly aroused ">>
-		<<elseif $pblevel gte 8 and $pbdisable is "f">>
-			<<set _text_output += "bushy ">>
+		<<if $player.vaginaExist>>
+			<<if $player.penisExist>>
+				<<set _text_output += " and ">>
+			<</if>>
+			<<if $player.virginity.vaginal is true and _args[0] isnot 2>>
+				<<set _text_output += "virgin ">>
+			<</if>>
+			<<if $vaginaWetness gte 75 and $pbdisable is "f" and $pblevel gte 8>>
+				<<set _text_output += "visibly aroused and bushy ">>
+			<<elseif $vaginaWetness gte 75>>
+				<<set _text_output += "visibly aroused ">>
+			<<elseif $pbdisable is "f" and $pblevel gte 8>>
+				<<set _text_output += "bushy ">>
+			<</if>>
+			<<set _text_output += ["pussy", "pussy", "pussy", "quim"].pluck()>>
 		<</if>>
-		<<set _text_output += ["pussy", "pussy", "pussy", "quim"].pluck()>>
 	<</if>>
-<</if>>
 <</silently>><<print _text_output>><</widget>>
 
 <!-- optionally takes 2 parameters: what to add after the text for singular/plural -->
diff --git a/game/overworld-town/loc-school/widgets-events.twee b/game/overworld-town/loc-school/widgets-events.twee
index c066e4c3dc..73e63f44a7 100644
--- a/game/overworld-town/loc-school/widgets-events.twee
+++ b/game/overworld-town/loc-school/widgets-events.twee
@@ -341,20 +341,20 @@
 
 	<<else>>
 		<<if $cool gte 400>>
-		You pass by a group of students. They drop their conversation and surround you, vying for your attention, each wanting to be seen with you.
-		<<ltrauma>><<lstress>><<trauma -6>><<stress -12>>
-		<br><br>
+			You pass by a group of students. They drop their conversation and surround you, vying for your attention, each wanting to be seen with you.
+			<<ltrauma>><<lstress>><<trauma -6>><<stress -12>>
+			<br><br>
 
-		<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
-		<br>
+			<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
+			<br>
 
 		<<elseif $cool gte 160>>
-		You pass a group of students who smile and greet you.
-		<<ltrauma>><<trauma -6>>
-		<br><br>
+			You pass a group of students who smile and greet you.
+			<<ltrauma>><<trauma -6>>
+			<br><br>
 
-		<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
-		<br>
+			<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
+			<br>
 
 		<<elseif $cool gte 120>>
 			<<if $schoolrep.herm gte 5 and !$worn.face.type.includes("mask")>>
@@ -364,10 +364,10 @@
 			<<else>>
 				You pass by a group of students who completely ignore you. You might as well be invisible to them.
 			<</if>>
-		<br><br>
+			<br><br>
 
-		<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
-		<br>
+			<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
+			<br>
 
 		<<elseif $cool gte 40>>
 			<<if $schoolrep.herm gte 5 and !$worn.face.type.includes("mask")>>
@@ -377,20 +377,20 @@
 			<<else>>
 				You pass a group of students who mock and laugh at you.
 			<</if>>
-		<<gstress>><<stress 6>>
-		<br><br>
+			<<gstress>><<stress 6>>
+			<br><br>
 
-		<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
-		<br>
+			<<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
+			<br>
 
 		<<else>>
-		You see a group of students up ahead. With your reputation and no teachers near, you're afraid to go near them.
-		<br><br>
+			You see a group of students up ahead. With your reputation and no teachers near, you're afraid to go near them.
+			<br><br>
 
-		<<link [[Take a detour (0:05)|Hallways]]>><<set $eventskip to 1>><<pass 5>><</link>>
-		<br>
-		<<link [[I can't waste the time. Walk past them.|Hallways Low Status]]>><</link>><<gtrauma>><<gstress>>
-		<br>
+			<<link [[Take a detour (0:05)|Hallways]]>><<set $eventskip to 1>><<pass 5>><</link>>
+			<br>
+			<<link [[I can't waste the time. Walk past them.|Hallways Low Status]]>><</link>><<gtrauma>><<gstress>>
+			<br>
 
 		<</if>>
 	<</if>>
@@ -622,7 +622,7 @@
 		<</if>>
 	<<elseif _selectedRumour is "rape">>
 		<<if $cool gte 120>>
-			"I don't know the details,” you overhear the <<person1>><<person>> saying. "But I heard a student has been assaulted."<br>
+			"I don't know the details," you overhear the <<person1>><<person>> saying. "But I heard a student has been assaulted."<br>
 			"A rape? In this town?" <<person2>><<He>> rolls <<his>> eyes. "Never heard that before."<br>
 			"Yeah, I guess you're right."
 		<<else>>
@@ -706,16 +706,12 @@
 		<</if>>
 
 		<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
-			<<if $worn.under_lower.type.includes("naked")>>
-				<<if $exhibitionism gte 55>>
-					<<link [[Flash|Hallways Lewd Flash]]>><</link>><<exhibitionist4>>
-					<br>
-				<</if>>
-			<<else>>
-				<<if $exhibitionism gte 15>>
-					<<link [[Flash|Hallways Flash]]>><</link>><<exhibitionist2>>
-					<br>
-				<</if>>
+			<<if $worn.under_lower.type.includes("naked") and $exhibitionism gte 55>>
+				<<link [[Flash|Hallways Lewd Flash]]>><</link>><<exhibitionist4>>
+				<br>
+			<<elseif $exhibitionism gte 15>>
+				<<link [[Flash|Hallways Flash]]>><</link>><<exhibitionist2>>
+				<br>
 			<</if>>
 		<</if>>
 		<<link [[Flirt|Hallways Catcall Flirt]]>><</link>><<promiscuous1>>
@@ -816,7 +812,7 @@
 <<widget "eventsplayground">>
 <!-- Jimmy TODO: Convert this to use the macros: <<cleareventpool>>, <<addinlineevent>> and <<runeventpool>>. -->
 <<if !["early", "late", "earlynoschool", "latenoschool", "daynoschool"].includes($schoolstate)>>
-
+	<<set _whitney to $NPCName[$NPCNameList.indexOf("Whitney")]>>
 	<<if $exposed gte 1>>
 		Some students spot your head poking out and wave. You <<nervously>> wave back, your heart racing. You don't think they noticed anything odd.
 		<<gstress>><<stress 6>><<garousal>><<arousal 600>>
@@ -826,14 +822,14 @@
 
 		<<playground>>
 
-	<<elseif $NPCName[$NPCNameList.indexOf("Whitney")].love gte 20 and $whitneyromance isnot 1 and $NPCName[$NPCNameList.indexOf("Whitney")].state isnot "dungeon" and $pillory_tenant.special.name isnot "Whitney">>
+	<<elseif _whitney.love gte 20 and $whitneyromance isnot 1 and _whitney.state isnot "dungeon" and $pillory_tenant.special.name isnot "Whitney">>
 		<<set $whitneyromance to 1>>
 		<<npc Whitney>><<person1>>
 
 		Whitney approaches you. <<He>> shoves you against a wall. <<He>> looks more angry than usual.
 		<br><br>
 		<<takeKissVirginity "Whitney" "loveInterest">>
-		"Stupid slut," <<he>> says. <<He>> pins you with <<his>> arms. "You've been asking for this, don't try to deny it." <<He>> kisses you with surprising tenderness. "You're my <<if $player.gender_appearance is "m">>boy<<else>>girl<</if>>friend now. You better be grateful." <<He>> kisses you again, this time biting your lip. <<He>> pulls away and leaves without looking back.
+		"Stupid slut," <<he>> says. <<He>> pins you with <<his>> arms. "You've been asking for this, don't try to deny it." <<He>> kisses you with surprising tenderness. "You're my <<girlfriend>> now. You better be grateful." <<He>> kisses you again, this time biting your lip. <<He>> pulls away and leaves without looking back.
 		<<npcincr Whitney lust 5>><<glust>>
 		<br><br>
 
@@ -906,10 +902,10 @@
 		<<endevent>>
 		<<playground>>
 
-	<<elseif $NPCName[$NPCNameList.indexOf("Whitney")].state isnot "dungeon" and $bullytimeroutside gte $rng and $hour gte 15 and $NPCName[$NPCNameList.indexOf("Whitney")].init is 1 and $pillory_tenant.special.name isnot "Whitney">>
-	<<set $bullytimeroutside to 0>>
+	<<elseif _whitney.state isnot "dungeon" and $bullytimeroutside gte $rng and $hour gte 15 and _whitney.init is 1 and $pillory_tenant.special.name isnot "Whitney">>
+		<<set $bullytimeroutside to 0>>
 
-	<<schoolbullyoutside>>
+		<<schoolbullyoutside>>
 
 	<<elseif $panty_thief is undefined and $days gte 7>>
 		<<generate1>><<person1>><<npcClothesType $NPCList[0] "default">>
@@ -950,68 +946,62 @@
 		<br>
 	<<else>>
 		<<if $rng gte 91 and $worn.face.type.includes("cool") and $schoolstate isnot "afternoon">>
-		<<npc River>><<person1>>"You, <<girl>>. Stop." You hear River's voice behind you. You turn to see <<him>> marching closer. "Those are definitely not prescription glasses. Give them to me this instant." A group of students watch nearby.
-		<br><br>
+			<<npc River>><<person1>>"You, <<girl>>. Stop." You hear River's voice behind you. You turn to see <<him>> marching closer. "Those are definitely not prescription glasses. Give them to me this instant." A group of students watch nearby.
+			<br><br>
 
-		<<link [[Hand them over|Events Shades Hand]]>><<status -10>><<trauma 6>><<faceruined>><<npcincr River dom 1>><</link>><<lcool>><<gtrauma>>
-		<br>
-		<<link [[Flip the bird|Events Shades Flip]]>><<status 1>><<trauma -6>><<detention 4>><<npcincr River dom -1>><<npcincr River love -1>><</link>><<gcool>><<ltrauma>><<gdelinquency>>
-		<br>
+			<<link [[Hand them over|Events Shades Hand]]>><<status -10>><<trauma 6>><<faceruined>><<npcincr River dom 1>><</link>><<lcool>><<gtrauma>>
+			<br>
+			<<link [[Flip the bird|Events Shades Flip]]>><<status 1>><<trauma -6>><<detention 4>><<npcincr River dom -1>><<npcincr River love -1>><</link>><<gcool>><<ltrauma>><<gdelinquency>>
+			<br>
 
 		<<elseif $rng gte 91 and $worn.face.type.includes("glasses")>>
-		<<generatey1>><<person1>>A hand reaches from behind you and snatches the glasses from your face.<<facestrip>>
-		<br><br>
-
-		You turn and see a <<person>> holding them. "Where did you get these? They must be ancient," <<he>> says. <<He>> drops them on the ground. "Wow. They didn't break." <<He>> hovers <<his>> foot above them. "I could change that. Unless you convince me not to.
+			<<generatey1>><<person1>>A hand reaches from behind you and snatches the glasses from your face.<<facestrip>>
+			<br><br>
 
-			<<if $player.gender_appearance is "f">>
-			Show me your knickers."
+			You turn and see a <<person>> holding them. "Where did you get these? They must be ancient," <<he>> says. <<He>> drops them on the ground. "Wow. They didn't break." <<He>> hovers <<his>> foot above them.
+			"I could change that. Unless you convince me not to. Show me your <<print ($player.gender_appearance is "f" ? "knickers" : "undies")>>."
+			<br><br>
+			<<if $worn.under_lower.type.includes("naked")>>
+				<<link [[Say you're not wearing any|Glasses No Underwear]]>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>>
 			<<else>>
-			Show me your undies."
+				<<link [[Show|Glasses Underwear]]>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>>
 			<</if>>
-		<br><br>
-			<<if $worn.under_lower.type.includes("naked")>>
-			<<link [[Say you're not wearing any|Glasses No Underwear]]>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>>
 			<br>
-			<<else>>
-			<<link [[Show|Glasses Underwear]]>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>>
+			<<link [[Refuse|Glasses Refuse]]>><</link>>
 			<br>
-			<</if>>
-		<<link [[Refuse|Glasses Refuse]]>><</link>>
-		<br>
 		<<elseif $rng gte 81 and $player.gender_appearance is "f" and $player.perceived_breastsize gte 3>>
 			<<generates1>><<person1>>Footsteps approach from behind. Before you can turn, someone runs into you, almost pushing you over. Fingers grope at your back.
 			<<if $worn.under_upper.type.includes("naked") or $worn.under_upper.type.includes("sticky")>>
-			"I can't find a strap," The <<person>> responsible exclaims. "She's not wearing a bra or anything." <<He>> runs back to <<his>> giggling friends. Your cheeks flush.
-			<<gpain>><<pain 1>><<trauma 6>><<stress 6>><<gtrauma>><<gstress>><<fameexhibitionism 3>>
-			<br><br>
+				"I can't find a strap," The <<person>> responsible exclaims. "She's not wearing a bra or anything." <<He>> runs back to <<his>> giggling friends. Your cheeks flush.
+				<<gpain>><<pain 1>><<trauma 6>><<stress 6>><<gtrauma>><<gstress>><<fameexhibitionism 3>>
+				<br><br>
 
-			<<endevent>>
+				<<endevent>>
 
-			<<playground>>
+				<<playground>>
 			<<elseif setup.clothes.under_upper[clothesIndex('under_upper', $worn.under_upper)].strap is 1>>
-			Your $worn.under_upper.name comes loose in your $worn.upper.name. They undid the strap.
-			<br><br>
+				Your $worn.under_upper.name comes loose in your $worn.upper.name. They undid the strap.
+				<br><br>
 
-			The culprit, a <<person>>, runs back to <<his>> giggling friends.
-			<<gpain>><<pain 1>><<trauma 6>><<stress 6>><<gtrauma>><<gstress>>
-			<br><br>
+				The culprit, a <<person>>, runs back to <<his>> giggling friends.
+				<<gpain>><<pain 1>><<trauma 6>><<stress 6>><<gtrauma>><<gstress>>
+				<br><br>
 
-			<<link [[Find somewhere quiet to fix your clothes|Bra Strap Quiet]]>><</link>>
-			<br>
-				<<if $exhibitionism gte 55>>
-				<<link [[Fix your clothes right here|Bra Strap Exhibitionism]]>><</link>><<exhibitionist4>>
+				<<link [[Find somewhere quiet to fix your clothes|Bra Strap Quiet]]>><</link>>
 				<br>
+				<<if $exhibitionism gte 55>>
+					<<link [[Fix your clothes right here|Bra Strap Exhibitionism]]>><</link>><<exhibitionist4>>
+					<br>
 				<</if>>
 			<<else>>
-			The <<person>> responsible shoves you away. "She's wearing a vest or something," <<he>> says. <<His>> friends look disappointed.
-			<<gpain>><<pain 1>>
-			<br><br>
+				The <<person>> responsible shoves you away. "She's wearing a vest or something," <<he>> says. <<His>> friends look disappointed.
+				<<gpain>><<pain 1>>
+				<br><br>
 
-			<<link [[Turn the other cheek|Bra Strap Turn]]>><<stress 6>><</link>><<gstress>>
-			<br>
-			<<link [[Get angry|Bra Strap Angry]]>><<stress -6>><<detention 2>><<def 1>><</link>><<gdelinquency>><<lstress>>
-			<br>
+				<<link [[Turn the other cheek|Bra Strap Turn]]>><<stress 6>><</link>><<gstress>>
+				<br>
+				<<link [[Get angry|Bra Strap Angry]]>><<stress -6>><<detention 2>><<def 1>><</link>><<gdelinquency>><<lstress>>
+				<br>
 			<</if>>
 		<<elseif $rng gte 71>>
 			<<if $beauty gte random(($beautymax / 2), ($beautymax + 1000))>>
@@ -1037,8 +1027,8 @@
 					<br><br>
 				<<else>><<set $phase to 4>>
 					<<He>> points to a bench where a <<person1>><<person>> sits, staring at <<his>> lap. "<<Hes>> too shy to say anything." <<person2>><<He>> pauses, waiting for your response.
-					<<ltrauma>><<trauma -6>>
-					<br><br>
+				<<ltrauma>><<trauma -6>>
+				<br><br>
 				<</if>>
 
 				<<link [[Flirt (0:05)|Playground Crush Flirt]]>><<pass 5>><<status 1>><</link>><<promiscuous1>><<gcool>>
@@ -1093,21 +1083,21 @@
 				<<if $rng gte 96 and $NPCName[$NPCNameList.indexOf("Robin")].init is 1>>
 					The <<person1>><<person>> admits to having a thing for Robin.
 					<br><br>
-						<<if $robinromance gte 1>>
-							You feel a twinge of jealousy.
-							<br><br>
-
-							<<link [[Get angry|Playground Crush Robin Angry]]>><<status 1>><<def 1>><</link>><<gcool>>
-							<br>
-							<<link [[Ignore|Playground Crush Robin Ignore]]>><<stress 6>><</link>><<gstress>>
-						<<else>>
-							<<endevent>>
-							<<npc Robin>><<person1>>
-							You wonder if Robin knows <<he>> has admirers.
-							<br><br>
-							<<endevent>>
-							<<playground>>
-						<</if>>
+					<<if $robinromance gte 1>>
+						You feel a twinge of jealousy.
+						<br><br>
+
+						<<link [[Get angry|Playground Crush Robin Angry]]>><<status 1>><<def 1>><</link>><<gcool>>
+						<br>
+						<<link [[Ignore|Playground Crush Robin Ignore]]>><<stress 6>><</link>><<gstress>>
+					<<else>>
+						<<endevent>>
+						<<npc Robin>><<person1>>
+						You wonder if Robin knows <<he>> has admirers.
+						<br><br>
+						<<endevent>>
+						<<playground>>
+					<</if>>
 				<<elseif $rng gte 81 and $NPCName[$NPCNameList.indexOf("Whitney")].init is 1>>
 					The <<person1>><<person>> admits to having a thing for Whitney.
 					<br><br>
@@ -1202,20 +1192,14 @@
 			<<if $cool lt 120>>
 				<<generatey1>><<person1>>A <<person>> points at you and whispers to <<his>> friends. They burst into laughter.
 				<<gstress>><<stress 6>>
-				<br><br>
-
-				<<endevent>>
-
-				<<playground>>
 			<<else>>
 				Some students recognise you and wave. You wave back.
 				<<lstress>><<stress -6>>
-				<br><br>
-
-				<<endevent>>
-
-				<<playground>>
 			<</if>>
+			<br><br>
+
+			<<endevent>>
+			<<playground>>
 		<</if>>
 	<</if>>
 <<else>>
@@ -1935,370 +1919,371 @@
 
 <<widget "schoolbullyoutside">>
 
-<<if $whitneyReunionScene isnot undefined>>
-	<<npc Whitney>><<person1>>
-	<<unset $whitneyReunionScene>>
-	As you step onto the playground, something grabs your arm. Before you can react, you're yanked backwards and find yourself face-to-face with Whitney. <<His>> goons flank you, preventing escape. "There you are, bitch," Whitney says, looking aggravated. "What? You didn't think I'd notice when my favourite slut goes missing?" You're unable to respond as <<he>> presses <<his>> lips against your mouth, kissing you.<<takeKissVirginity "Whitney" "loveInterest">>
-	<br><br>
-
-	Whitney's arm wraps around your waist as <<he>> holds the back of your head still. <<He>> leans forward, forcing you to bend backward. Jeers erupt from <<his>> goons as they watch in anticipation.
-	<br><br>
-
-	"Fuck <<phim>>!"
-	<br>
-	"Beat <<phim>>!"
-	<br>
-	"Take <<pher>> clothes!"
-	<br><br>
-
-	Whitney glares at you, <<his>> grip the only thing keeping you from falling. You swear you see the faintest trace of a tear in <<his>> eye. Before it goes any further, <<he>> drops you on the floor.
-	<br><br>
-
-	Whitney's breathing is heavier. <<He>> speaks, "Only... I get to kidnap you. Got it?" <<He>> roughly shoves you through the gate, not taking <<his>> eyes off you.<<npcincr Whitney dom 3>><<stress 6>><<gstress>><<ggdom>>
-	<br><br>
-
-	<<endevent>><<set $eventskip to 1>>
-	<<playground>>
-<<elseif $bullyeventoutside is 0>><<set $bullyeventoutside += 1>>
-<<npc Whitney>><<person1>>You walk round a corner, straight into Whitney and <<his>> gang. "Look who it is," <<he>> says. <<His>> friends crowd around, penning you in. "Good timing. We're just leaving school. You should come." <<He>> grabs your arm.
-<br><br>
-
-<<link [[Let it happen (0:20)|Bully Theft]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-<br>
-<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-<br>
-
-<<elseif $bullyeventoutside is 1>>
-<<set $bullyeventoutside += 1>>
-
-<<npc Whitney>><<person1>>You hear running footsteps approach. Whitney and <<his>> gang encircle you. "Look who it is," <<he>> says. "Just who I was looking for." <<He>> grabs your arm.
-<br><br>
-
-<<link [[Let it happen (0:20)|Bully Light]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-<br>
-<<link [[Fight|Bully Outside Fight]]>><<sub 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-<br>
-
-<<elseif $bullyeventoutside is 2>>
-<<set $bullyeventoutside += 1>>
-
-	<<if $whitneyromance is 1>>
-	<<npc Whitney>><<person1>>Whitney marches towards you. <<He>> pushes you against a wall. <<His>> friends flank <<him>>. "Hey <<girl>>," <<he>> says. "Time for your duties." <<He>> grabs your arm.
-	<br><br>
-
-	<<link [[Let it happen (0:20)|Bully Romance]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-	<br>
-	<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-	<br>
-
-	<<else>>
-	<<npc Whitney>><<person1>>You hear running footsteps approach. Whitney slams into you, knocking you to the ground. <<He>> sits on your back and rests <<his>> shoes on your head. "This is comfy," <<he>> says. "Shame we can't stay." <<He>> stands up. "Later slut."
-	<<gtrauma>><<gstress>><<gpain>><<trauma 6>><<stress 6>><<pain 15>><<npcincr Whitney lust 5>><<glust>>
-	<br><br>
-
-	<<tearful>> you climb to your feet.
-	<br><br>
-
-	<<endevent>>
-	<<set $eventskip to 1>>
-	<<playground>>
-	<</if>>
-
-<<elseif $bullyeventoutside is 3>>
-<<set $bullyeventoutside += 1>>
-<<npc Whitney>><<person1>>
-You see Whitney as you approach the gate. <<He>> grins and pushes past one of <<his>> friends, moving towards you.
-<br><br>
-
-"Hey, <<girl>>," <<he>> says. "You're coming with us." <<He>> wraps an arm around your shoulder and tries to pull you through the gate. <<His>> friends flank you.
-<br><br>
-
-<<link [[Let it happen (0:20)|Bully Strip Theft]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-<br>
-<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-<br>
-
-<<elseif $bullyeventoutside is 4>>
-<<set $bullyeventoutside += 1>>
-
-<<npc Whitney>><<person1>>Someone grabs your hair. It's Whitney. "Come on slut," <<he>> says as <<he>> tugs. "You've got somewhere to be."
-<br><br>
-
-<<link [[Let it happen (0:20)|Bully Whore]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-<br>
-<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-<br>
-
-<<else>>
-<<set $bullyeventoutside to 0>>
-<<npc Whitney>><<person1>>
-Whitney looms around a corner and rests <<his>> arm on your shoulder. <<His>> friends appear a moment later, trapping you against the wall.
-<br><br>
-"Just the slut I wanted to see," <<he>> says.
-	<<if $skin.forehead.special is "Whitney" and $skin.forehead.pen is "tattoo" and $bodywritingLvl gte 2>>
-		<<He>> examines your <span class="lewd">"<<print $skin.forehead.writing>>" tattoo</span>
-		"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-		<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-		<<if $whitneyromance isnot 1>>
-			<<gtrauma>><<trauma 6>>
-		<</if>>
-		<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+	<<if $whitneyReunionScene isnot undefined>>
+		<<npc Whitney>><<person1>>
+		<<unset $whitneyReunionScene>>
+		As you step onto the playground, something grabs your arm. Before you can react, you're yanked backwards and find yourself face-to-face with Whitney. <<His>> goons flank you, preventing escape. "There you are, bitch," Whitney says, looking aggravated. "What? You didn't think I'd notice when my favourite slut goes missing?" You're unable to respond as <<he>> presses <<his>> lips against your mouth, kissing you.<<takeKissVirginity "Whitney" "loveInterest">>
 		<br><br>
-		<<endevent>><<set $eventskip to 1>>
-		<<playground>>
-	<<elseif $skin.left_cheek.special is "Whitney" and $skin.left_cheek.pen is "tattoo" and $bodywritingLvl gte 2>>
-		<<if $worn.face.type.includes("mask")>>
-			<<He>> pulls your mask aside and examines your <span class="lewd">"<<print $skin.left_cheek.writing>>" tattoo.</span>
-		<<else>>
-			<<He>> examines your <span class="lewd">"<<print $skin.left_cheek.writing>>" tattoo</span>
-		<</if>>
-		"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-		<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-		<<if $whitneyromance isnot 1>>
-		<<gtrauma>><<trauma 6>>
-		<</if>>
-		<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+
+		Whitney's arm wraps around your waist as <<he>> holds the back of your head still. <<He>> leans forward, forcing you to bend backward. Jeers erupt from <<his>> goons as they watch in anticipation.
 		<br><br>
-		<<endevent>><<set $eventskip to 1>>
-		<<playground>>
 
-	<<elseif $skin.right_cheek.special is "Whitney" and $skin.right_cheek.pen is "tattoo" and $bodywritingLvl gte 2>>
-		<<if $worn.face.type.includes("mask")>>
-			<<He>> pulls your mask aside and examines your <span class="lewd">"<<print $skin.right_cheek.writing>>" tattoo.</span>
-		<<else>>
-			<<He>> examines your <span class="lewd">"<<print $skin.right_cheek.writing>>" tattoo</span>
-		<</if>>
-		"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-		<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-		<<if $whitneyromance isnot 1>>
-		<<gtrauma>><<trauma 6>>
-		<</if>>
-		<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+		"Fuck <<phim>>!"
+		<br>
+		"Beat <<phim>>!"
+		<br>
+		"Take <<pher>> clothes!"
 		<br><br>
-		<<endevent>><<set $eventskip to 1>>
-		<<playground>>
 
-	<<elseif $skin.left_shoulder.special is "Whitney" and $skin.left_shoulder.pen is "tattoo" and $bodywritingLvl gte 2>>
-		<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-			<<He>> examines your <span class="lewd">"<<print $skin.left_shoulder.writing>>" tattoo.</span>
-		<<else>>
-			<<He>> jerks your $worn.upper.name down and examines your <span class="lewd">"<<print $skin.left_shoulder.writing>>" tattoo.</span>
-		<</if>>
-		"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-		<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-		<<if $whitneyromance isnot 1>>
-		<<gtrauma>><<trauma 6>>
-		<</if>>
-		<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+		Whitney glares at you, <<his>> grip the only thing keeping you from falling. You swear you see the faintest trace of a tear in <<his>> eye. Before it goes any further, <<he>> drops you on the floor.
 		<br><br>
-		<<endevent>><<set $eventskip to 1>>
-		<<playground>>
-	<<elseif $skin.right_shoulder.special is "Whitney" and $skin.right_shoulder.pen is "tattoo" and $bodywritingLvl gte 2>>
-		<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-			<<He>> examines your <span class="lewd">"<<print $skin.right_shoulder.writing>>" tattoo.</span>
-		<<else>>
-			<<He>> jerks your $worn.upper.name down and examines your <span class="lewd">"<<print $skin.right_shoulder.writing>>" tattoo.</span>
-		<</if>>
-		"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-		<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-		<<if $whitneyromance isnot 1>>
-		<<gtrauma>><<trauma 6>>
-		<</if>>
-		<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+
+		Whitney's breathing is heavier. <<He>> speaks, "Only... I get to kidnap you. Got it?" <<He>> roughly shoves you through the gate, not taking <<his>> eyes off you.<<npcincr Whitney dom 3>><<stress 6>><<gstress>><<ggdom>>
 		<br><br>
+
 		<<endevent>><<set $eventskip to 1>>
 		<<playground>>
-	<<elseif $skin.forehead.special is "Whitney" and $bodywritingLvl gte 2>>
-		<<He>> strokes your forehead. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-		<br><br>
-		<<set $phase to 2>>
-		<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-		<br>
-		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-		<br>
-	<<elseif ($skin.left_cheek.special is "Whitney" or $skin.right_cheek.special is "Whitney") and $bodywritingLvl gte 2>>
-		<<if $worn.upper.type.includes("mask")>>
-			<<He>> pulls your mask aside and strokes your cheek. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-		<<else>>
-			<<He>> strokes your cheek. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-		<</if>>
-		<br><br>
-		<<set $phase to 2>>
-		<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-		<br>
-		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-		<br>
-	<<elseif ($skin.left_shoulder.special is "Whitney" or $skin.right_shoulder.special is "Whitney") and $bodywritingLvl gte 2>>
-		<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-			<<He>> strokes your shoulder. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-		<<else>>
-			<<He>> tugs your $worn.upper.name down and strokes your shoulder. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-		<</if>>
-		<br><br>
-		<<set $phase to 2>>
-		<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-		<br>
-		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-		<br>
-	<<elseif $skin.forehead.pen is "pen" and $bodywritingLvl gte 2>>
-		<<bodywriting_clear forehead>>
-		<<He>> leans in and licks your forehead, then wipes it with <<his>> sleeve. "I've thought of something better." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+	<<elseif $bullyeventoutside is 0>>
+		<<set $bullyeventoutside += 1>>
+		<<npc Whitney>><<person1>>You walk round a corner, straight into Whitney and <<his>> gang. "Look who it is," <<he>> says. <<His>> friends crowd around, penning you in. "Good timing. We're just leaving school. You should come." <<He>> grabs your arm.
 		<br><br>
-		<<set $phase to 1>>
-		<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+
+		<<link [[Let it happen (0:20)|Bully Theft]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
 		<br>
 		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
 		<br>
-	<<elseif ($skin.left_cheek.pen is "pen" or $skin.right_cheek.pen is "pen" or $skin.left_cheek.pen is "lipstick" or $skin.right_cheek.pen is "lipstick" or $skin.left or $skin.left_cheek.pen is "mud" or $skin.right_cheek.pen is "pen" or $skin.left) and $bodywritingLvl gte 2>>
-		<<if $skin.left_cheek.pen is "pen" or $skin.left_cheek is "lipstick" or $skin.left_cheek is "mud">>
-			<<bodywriting_clear left_cheek>>
-		<<else>>
-			<<bodywriting_clear right_cheek>>
-		<</if>>
-		<<if $worn.face.type.includes("mask")>>
-			<<He>> leans in, pulls your mask aside, and licks your cheek.
-		<<else>>
-			<<He>> leans in and licks your cheek.
-		<</if>>
-		"I've thought of something better." <<He>> rubs your face with <<his>> sleeve while pulling a pen from <<his>> pocket. "Hold still."
+
+	<<elseif $bullyeventoutside is 1>>
+		<<set $bullyeventoutside += 1>>
+
+		<<npc Whitney>><<person1>>You hear running footsteps approach. Whitney and <<his>> gang encircle you. "Look who it is," <<he>> says. "Just who I was looking for." <<He>> grabs your arm.
 		<br><br>
-		<<set $phase to 1>>
-		<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+
+		<<link [[Let it happen (0:20)|Bully Light]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
 		<br>
-		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+		<<link [[Fight|Bully Outside Fight]]>><<sub 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
 		<br>
 
-	<<elseif ($skin.left_shoulder.pen is "pen" or $skin.right_shoulder.pen is "pen" or $skin.left_shoulder.pen is "lipstick" or $skin.right_shoulder.pen is "lipstick" or $skin.left_shoulder.pen is "mud" or $skin.right_shoulder.pen is "mud") and $bodywritingLvl gte 2>>
-		<<if $skin.left_shoulder.pen is "pen" or $skin_left_shoulder is "lipstick" or $skin.left_shoulder is "mud">>
-			<<bodywriting_clear left_shoulder>>
-		<<else>>
-			<<bodywriting_clear right_shoulder>>
-		<</if>>
-		<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-			<<He>> leans in and licks your shoulder, while pulling a pen from <<his>> pocket. "I've thought of something better." <<He>> rubs your shoulder with <<his>> sleeve. "Hold still."
+	<<elseif $bullyeventoutside is 2>>
+		<<set $bullyeventoutside += 1>>
+
+		<<if $whitneyromance is 1>>
+			<<npc Whitney>><<person1>>Whitney marches towards you. <<He>> pushes you against a wall. <<His>> friends flank <<him>>. "Hey <<girl>>," <<he>> says. "Time for your duties." <<He>> grabs your arm.
+			<br><br>
+
+			<<link [[Let it happen (0:20)|Bully Romance]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+
 		<<else>>
-			<<He>> leans in, pulls your $worn.upper.name aside, and licks your shoulder "I've thought of something better." <<He>> pulls a pen from <<his>> pocket while rubbing your shoulder with <<his>> sleeve. "Hold still."
+			<<npc Whitney>><<person1>>You hear running footsteps approach. Whitney slams into you, knocking you to the ground. <<He>> sits on your back and rests <<his>> shoes on your head. "This is comfy," <<he>> says. "Shame we can't stay." <<He>> stands up. "Later slut."
+			<<gtrauma>><<gstress>><<gpain>><<trauma 6>><<stress 6>><<pain 15>><<npcincr Whitney lust 5>><<glust>>
+			<br><br>
+
+			<<tearful>> you climb to your feet.
+			<br><br>
+
+			<<endevent>>
+			<<set $eventskip to 1>>
+			<<playground>>
 		<</if>>
-		<br><br>
-		<<set $phase to 1>>
-		<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-		<br>
-		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-		<br>
 
-	<<elseif !$skin.forehead.pen and $bodywritingLvl gte 2>>
-		<<He>> leans in and licks your forehead. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+	<<elseif $bullyeventoutside is 3>>
+		<<set $bullyeventoutside += 1>>
+		<<npc Whitney>><<person1>>
+		You see Whitney as you approach the gate. <<He>> grins and pushes past one of <<his>> friends, moving towards you.
 		<br><br>
-		<<set $phase to 1>>
-		<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-		<br>
-		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-		<br>
-	<<elseif (!$skin.left_cheek.pen or !$skin.right_cheek.pen) and $bodywritingLvl gte 2>>
-		<<He>> leans in and licks your cheek. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+
+		"Hey, <<girl>>," <<he>> says. "You're coming with us." <<He>> wraps an arm around your shoulder and tries to pull you through the gate. <<His>> friends flank you.
 		<br><br>
-		<<set $phase to 1>>
-		<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+
+		<<link [[Let it happen (0:20)|Bully Strip Theft]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
 		<br>
 		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
 		<br>
-	<<elseif (!$skin.left_shoulder.pen or !$skin.right_shoulder.pen) and $bodywritingLvl gte 2>>
-		<<He>> leans in and licks your shoulder. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+
+	<<elseif $bullyeventoutside is 4>>
+		<<set $bullyeventoutside += 1>>
+
+		<<npc Whitney>><<person1>>Someone grabs your hair. It's Whitney. "Come on slut," <<he>> says as <<he>> tugs. "You've got somewhere to be."
 		<br><br>
-		<<set $phase to 1>>
-		<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+
+		<<link [[Let it happen (0:20)|Bully Whore]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
 		<br>
 		<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
 		<br>
+
 	<<else>>
-	<<He>> grasps your hair, pulls your head back, and assaults your face with <<his>> tongue. <<He>> shoves you away before you can respond.
-	<br><br>
-	"Later slut." <<He>> saunters away with <<his>> friends.
-	<<glust>>
-		<<if $whitneyromance isnot 1>>
-		<<gtrauma>><<trauma 6>>
+		<<set $bullyeventoutside to 0>>
+		<<npc Whitney>><<person1>>
+		Whitney looms around a corner and rests <<his>> arm on your shoulder. <<His>> friends appear a moment later, trapping you against the wall.
+		<br><br>
+		"Just the slut I wanted to see," <<he>> says.
+		<<if $skin.forehead.special is "Whitney" and $skin.forehead.pen is "tattoo" and $bodywritingLvl gte 2>>
+			<<He>> examines your <span class="lewd">"<<print $skin.forehead.writing>>" tattoo</span>
+			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
+			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
+			<<if $whitneyromance isnot 1>>
+				<<gtrauma>><<trauma 6>>
+			<</if>>
+			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+			<br><br>
+			<<endevent>><<set $eventskip to 1>>
+			<<playground>>
+		<<elseif $skin.left_cheek.special is "Whitney" and $skin.left_cheek.pen is "tattoo" and $bodywritingLvl gte 2>>
+			<<if $worn.face.type.includes("mask")>>
+				<<He>> pulls your mask aside and examines your <span class="lewd">"<<print $skin.left_cheek.writing>>" tattoo.</span>
+			<<else>>
+				<<He>> examines your <span class="lewd">"<<print $skin.left_cheek.writing>>" tattoo</span>
+			<</if>>
+			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
+			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
+			<<if $whitneyromance isnot 1>>
+				<<gtrauma>><<trauma 6>>
+			<</if>>
+			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+			<br><br>
+			<<endevent>><<set $eventskip to 1>>
+			<<playground>>
+
+		<<elseif $skin.right_cheek.special is "Whitney" and $skin.right_cheek.pen is "tattoo" and $bodywritingLvl gte 2>>
+			<<if $worn.face.type.includes("mask")>>
+				<<He>> pulls your mask aside and examines your <span class="lewd">"<<print $skin.right_cheek.writing>>" tattoo.</span>
+			<<else>>
+				<<He>> examines your <span class="lewd">"<<print $skin.right_cheek.writing>>" tattoo</span>
+			<</if>>
+			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
+			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
+			<<if $whitneyromance isnot 1>>
+				<<gtrauma>><<trauma 6>>
+			<</if>>
+			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+			<br><br>
+			<<endevent>><<set $eventskip to 1>>
+			<<playground>>
+
+		<<elseif $skin.left_shoulder.special is "Whitney" and $skin.left_shoulder.pen is "tattoo" and $bodywritingLvl gte 2>>
+			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
+				<<He>> examines your <span class="lewd">"<<print $skin.left_shoulder.writing>>" tattoo.</span>
+			<<else>>
+				<<He>> jerks your $worn.upper.name down and examines your <span class="lewd">"<<print $skin.left_shoulder.writing>>" tattoo.</span>
+			<</if>>
+			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
+			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
+			<<if $whitneyromance isnot 1>>
+				<<gtrauma>><<trauma 6>>
+			<</if>>
+			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+			<br><br>
+			<<endevent>><<set $eventskip to 1>>
+			<<playground>>
+		<<elseif $skin.right_shoulder.special is "Whitney" and $skin.right_shoulder.pen is "tattoo" and $bodywritingLvl gte 2>>
+			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
+				<<He>> examines your <span class="lewd">"<<print $skin.right_shoulder.writing>>" tattoo.</span>
+			<<else>>
+				<<He>> jerks your $worn.upper.name down and examines your <span class="lewd">"<<print $skin.right_shoulder.writing>>" tattoo.</span>
+			<</if>>
+			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
+			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
+			<<if $whitneyromance isnot 1>>
+				<<gtrauma>><<trauma 6>>
+			<</if>>
+			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
+			<br><br>
+			<<endevent>><<set $eventskip to 1>>
+			<<playground>>
+		<<elseif $skin.forehead.special is "Whitney" and $bodywritingLvl gte 2>>
+			<<He>> strokes your forehead. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
+			<br><br>
+			<<set $phase to 2>>
+			<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<elseif ($skin.left_cheek.special is "Whitney" or $skin.right_cheek.special is "Whitney") and $bodywritingLvl gte 2>>
+			<<if $worn.upper.type.includes("mask")>>
+				<<He>> pulls your mask aside and strokes your cheek. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
+			<<else>>
+				<<He>> strokes your cheek. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
+			<</if>>
+			<br><br>
+			<<set $phase to 2>>
+			<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<elseif ($skin.left_shoulder.special is "Whitney" or $skin.right_shoulder.special is "Whitney") and $bodywritingLvl gte 2>>
+			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
+				<<He>> strokes your shoulder. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
+			<<else>>
+				<<He>> tugs your $worn.upper.name down and strokes your shoulder. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
+			<</if>>
+			<br><br>
+			<<set $phase to 2>>
+			<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<elseif $skin.forehead.pen is "pen" and $bodywritingLvl gte 2>>
+			<<bodywriting_clear forehead>>
+			<<He>> leans in and licks your forehead, then wipes it with <<his>> sleeve. "I've thought of something better." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+			<br><br>
+			<<set $phase to 1>>
+			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<elseif ($skin.left_cheek.pen is "pen" or $skin.right_cheek.pen is "pen" or $skin.left_cheek.pen is "lipstick" or $skin.right_cheek.pen is "lipstick" or $skin.left or $skin.left_cheek.pen is "mud" or $skin.right_cheek.pen is "pen" or $skin.left) and $bodywritingLvl gte 2>>
+			<<if $skin.left_cheek.pen is "pen" or $skin.left_cheek is "lipstick" or $skin.left_cheek is "mud">>
+				<<bodywriting_clear left_cheek>>
+			<<else>>
+				<<bodywriting_clear right_cheek>>
+			<</if>>
+			<<if $worn.face.type.includes("mask")>>
+				<<He>> leans in, pulls your mask aside, and licks your cheek.
+			<<else>>
+				<<He>> leans in and licks your cheek.
+			<</if>>
+			"I've thought of something better." <<He>> rubs your face with <<his>> sleeve while pulling a pen from <<his>> pocket. "Hold still."
+			<br><br>
+			<<set $phase to 1>>
+			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+
+		<<elseif ($skin.left_shoulder.pen is "pen" or $skin.right_shoulder.pen is "pen" or $skin.left_shoulder.pen is "lipstick" or $skin.right_shoulder.pen is "lipstick" or $skin.left_shoulder.pen is "mud" or $skin.right_shoulder.pen is "mud") and $bodywritingLvl gte 2>>
+			<<if $skin.left_shoulder.pen is "pen" or $skin_left_shoulder is "lipstick" or $skin.left_shoulder is "mud">>
+				<<bodywriting_clear left_shoulder>>
+			<<else>>
+				<<bodywriting_clear right_shoulder>>
+			<</if>>
+			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
+				<<He>> leans in and licks your shoulder, while pulling a pen from <<his>> pocket. "I've thought of something better." <<He>> rubs your shoulder with <<his>> sleeve. "Hold still."
+			<<else>>
+				<<He>> leans in, pulls your $worn.upper.name aside, and licks your shoulder "I've thought of something better." <<He>> pulls a pen from <<his>> pocket while rubbing your shoulder with <<his>> sleeve. "Hold still."
+			<</if>>
+			<br><br>
+			<<set $phase to 1>>
+			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+
+		<<elseif !$skin.forehead.pen and $bodywritingLvl gte 2>>
+			<<He>> leans in and licks your forehead. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+			<br><br>
+			<<set $phase to 1>>
+			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<elseif (!$skin.left_cheek.pen or !$skin.right_cheek.pen) and $bodywritingLvl gte 2>>
+			<<He>> leans in and licks your cheek. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+			<br><br>
+			<<set $phase to 1>>
+			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<elseif (!$skin.left_shoulder.pen or !$skin.right_shoulder.pen) and $bodywritingLvl gte 2>>
+			<<He>> leans in and licks your shoulder. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+			<br><br>
+			<<set $phase to 1>>
+			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+			<br>
+			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+			<br>
+		<<else>>
+			<<He>> grasps your hair, pulls your head back, and assaults your face with <<his>> tongue. <<He>> shoves you away before you can respond.
+			<br><br>
+			"Later slut." <<He>> saunters away with <<his>> friends.
+			<<glust>>
+			<<if $whitneyromance isnot 1>>
+				<<gtrauma>><<trauma 6>>
+			<</if>>
+			<<gstress>><<garousal>><<stress 6>><<arousal 600>><<npcincr Whitney lust 1>>
+			<br><br>
+			<<endevent>><<set $eventskip to 1>>
+			<<playground>>
 		<</if>>
-	<<gstress>><<garousal>><<stress 6>><<arousal 600>><<npcincr Whitney lust 1>>
-	<br><br>
-	<<endevent>><<set $eventskip to 1>>
-	<<playground>>
 	<</if>>
-<</if>>
 
 <</widget>>
 
 <<widget "kylarhallways">>
-<<run statusCheck("Kylar")>>
-<<rng>>
-<<if _kylarStatus.includes("Love")>>
-	<<if $rng gte 60>>
-		<<npc Kylar>><<person1>>Kylar appears beside you and clutches your arm. "Hey," <<he>> says, smiling. <<He>> spots a <<generatey2>><<person2>><<person>> watching, and waves at <<him>>. "This is my <<if $player.gender_appearance is "m">>boyfriend<<else>>girlfriend<</if>>," <<person1>><<he>> announces. More turn to look. Someone snickers.
-		<<status -10>><<lcool>>
-		<br><br>
+	<<run statusCheck("Kylar")>>
+	<<rng>>
+	<<if _kylarStatus.includes("Love")>>
+		<<if $rng gte 60>>
+			<<npc Kylar>><<person1>>Kylar appears beside you and clutches your arm. "Hey," <<he>> says, smiling. <<He>> spots a <<generatey2>><<person2>><<person>> watching, and waves at <<him>>. "This is my <<girlfriend>>," <<person1>><<he>> announces. More turn to look. Someone snickers.
+			<<status -10>><<lcool>>
+			<br><br>
 
-		<<He>> turns to you, "I want everyone to know how much we love each other." <<He>> hugs your arm tight, then strolls down the hallway.
-		<<glove>><<npcincr Kylar love 1>>
-		<br><br>
+			<<He>> turns to you, "I want everyone to know how much we love each other." <<He>> hugs your arm tight, then strolls down the hallway.
+			<<glove>><<npcincr Kylar love 1>>
+			<br><br>
 
-		<<link [[Next|Hallways]]>><<set $eventskip to 1>><<endevent>><</link>>
-		<br>
-	<<elseif $rng gte 20>>
+			<<link [[Next|Hallways]]>><<set $eventskip to 1>><<endevent>><</link>>
+			<br>
+		<<elseif $rng gte 20>>
 
-		<<npc Kylar>><<person1>>Kylar tugs on your arm. <<He>> nods towards an open cupboard.
-		<br><br>
+			<<npc Kylar>><<person1>>Kylar tugs on your arm. <<He>> nods towards an open cupboard.
+			<br><br>
 
-		<<link [[Go with Kylar (0:05)|Kylar Cupboard]]>><<pass 5>><</link>><<promiscuous1>>
-		<br>
-		<<link [[Refuse|Kylar Refuse]]>><<npcincr Kylar love -1>><<npcincr Kylar lust 5>><<npcincr Kylar rage 5>><</link>><<llove>><<gglust>><<ggksuspicion>>
-		<br>
+			<<link [[Go with Kylar (0:05)|Kylar Cupboard]]>><<pass 5>><</link>><<promiscuous1>>
+			<br>
+			<<link [[Refuse|Kylar Refuse]]>><<npcincr Kylar love -1>><<npcincr Kylar lust 5>><<npcincr Kylar rage 5>><</link>><<llove>><<gglust>><<ggksuspicion>>
+			<br>
 
-	<<else>>
+		<<else>>
 
-		<<npc Kylar>><<person1>><<generatey2>>You hear Kylar up ahead. "It's true," <<he>> says. "<<pShes>> my <<if $player.gender_appearance is "m">>boyfriend<<else>>girlfriend<</if>>." <<Hes>> talking to a <<person2>><<person>> and <<his>> friends. They don't look convinced.
-		<br><br>
+			<<npc Kylar>><<person1>><<generatey2>>You hear Kylar up ahead. "It's true," <<he>> says. "<<pShes>> my <<girlfriend>>." <<Hes>> talking to a <<person2>><<person>> and <<his>> friends. They don't look convinced.
+			<br><br>
 
-		Kylar rushes over to you. "T-tell them," <<person1>><<he>> says. "Tell them it's true."
-		<br><br>
+			Kylar rushes over to you. "T-tell them," <<person1>><<he>> says. "Tell them it's true."
+			<br><br>
 
-		<<link [[Say it's true|Kylar True]]>><<npcincr Kylar love 5>><<npcincr Kylar rage -5>><<status -10>><</link>><<lcool>><<gglove>>
-		<br>
-		<<link [[Say it's a lie|Kylar Lie]]>><<npcincr Kylar love -5>><<npcincr Kylar rage 5>><<status 1>><</link>><<lllove>><<ggksuspicion>><<gcool>>
-		<br>
-		<<link [[Walk away|Kylar Walk 2]]>><<npcincr Kylar love -1>><<npcincr Kylar rage 1>><</link>><<llove>><<gksuspicion>>
-		<br>
-		<<if $syndromekylar gte 1>>
-			<<link [[Seize Kylar and kiss|Kylar Kiss]]>><<npcincr Kylar love 10>><<npcincr Kylar rage -10>><<status -20>><</link>><<kissvirginitywarning>><<llcool>><<ggglove>>
+			<<link [[Say it's true|Kylar True]]>><<npcincr Kylar love 5>><<npcincr Kylar rage -5>><<status -10>><</link>><<lcool>><<gglove>>
+			<br>
+			<<link [[Say it's a lie|Kylar Lie]]>><<npcincr Kylar love -5>><<npcincr Kylar rage 5>><<status 1>><</link>><<lllove>><<ggksuspicion>><<gcool>>
 			<br>
+			<<link [[Walk away|Kylar Walk 2]]>><<npcincr Kylar love -1>><<npcincr Kylar rage 1>><</link>><<llove>><<gksuspicion>>
+			<br>
+			<<if $syndromekylar gte 1>>
+				<<link [[Seize Kylar and kiss|Kylar Kiss]]>><<npcincr Kylar love 10>><<npcincr Kylar rage -10>><<status -20>><</link>><<kissvirginitywarning>><<llcool>><<ggglove>>
+				<br>
+			<</if>>
 		<</if>>
-	<</if>>
-<<else>>
-	<<if $rng gte 50>>
+	<<else>>
+		<<if $rng gte 50>>
 
-		You see a figure watching you from down the corridor.<<npc Kylar>><<person1>> It's Kylar. <<He>> hides when you look at <<him>>.
-		<br><br>
+			You see a figure watching you from down the corridor.<<npc Kylar>><<person1>> It's Kylar. <<He>> hides when you look at <<him>>.
+			<br><br>
 
-		<<link [[Greet|Kylar Greet]]>><<npcincr Kylar love 1>><</link>><<glove>>
-		<br>
-		<<link [[Ignore|Hallways]]>><<set $eventskip to 1>><<endevent>><</link>>
-		<br>
+			<<link [[Greet|Kylar Greet]]>><<npcincr Kylar love 1>><</link>><<glove>>
+			<br>
+			<<link [[Ignore|Hallways]]>><<set $eventskip to 1>><<endevent>><</link>>
+			<br>
 
-	<<else>>
+		<<else>>
 
-		<<npc Kylar>><<person1>>You hear laughter. You walk around the corner and find a crowd. <<generatey2>>Kylar is there, <<his>> arms held up against the lockers by a <<person2>><<person>>.<<person1>> Kylar's own locker is open beside <<him>>. The laughter redoubles when the crowd sees you.
-		<<gstress>><<stress 6>>
-		<br><br>
+			<<npc Kylar>><<person1>>You hear laughter. You walk around the corner and find a crowd. <<generatey2>>Kylar is there, <<his>> arms held up against the lockers by a <<person2>><<person>>.<<person1>> Kylar's own locker is open beside <<him>>. The laughter redoubles when the crowd sees you.
+			<<gstress>><<stress 6>>
+			<br><br>
 
-		You step closer and see why. Inside Kylar's locker is a lewd statuette. A pencil portrait is stuck to the face. The drawing is good, and it's clear it's a picture of you. Flowers are arranged in a circular pattern at its base. It looks like a shrine.
-		<br><br>
+			You step closer and see why. Inside Kylar's locker is a lewd statuette. A pencil portrait is stuck to the face. The drawing is good, and it's clear it's a picture of you. Flowers are arranged in a circular pattern at its base. It looks like a shrine.
+			<br><br>
 
-		<<link [[Bully Kylar|Kylar Bully]]>><<npcincr Kylar love -5>><<status 1>><</link>><<lllove>><<gcool>>
-		<br>
-		<<link [[Defend Kylar|Kylar Defend]]>><<npcincr Kylar love 5>><<status -10>><</link>><<lcool>><<gglove>>
-		<br>
-		<<link [[Walk away|Kylar Walk]]>><<npcincr Kylar love -1>><</link>><<llove>>
-		<br>
+			<<link [[Bully Kylar|Kylar Bully]]>><<npcincr Kylar love -5>><<status 1>><</link>><<lllove>><<gcool>>
+			<br>
+			<<link [[Defend Kylar|Kylar Defend]]>><<npcincr Kylar love 5>><<status -10>><</link>><<lcool>><<gglove>>
+			<br>
+			<<link [[Walk away|Kylar Walk]]>><<npcincr Kylar love -1>><</link>><<llove>>
+			<br>
+		<</if>>
 	<</if>>
-<</if>>
 
 <</widget>>
 
@@ -2306,46 +2291,46 @@ Whitney looms around a corner and rests <<his>> arm on your shoulder. <<His>> fr
 <<rng>>
 <<if $rng gte 51>>
 
-A gust of wind blows over you.
+	A gust of wind blows over you.
 
 	<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
 		<<if $schoolstate is "lunch" or $schoolstate is "morning" or $schoolstate is "afternoon">>
-		The breeze lifts your $worn.lower.name and exposes your <<undies>> until you push the fabric back down between your thighs. You don't think anyone saw.
-		<<gstress>><<garousal>><<stress 1>><<arousal 600>>
-		<br><br>
+			The breeze lifts your $worn.lower.name and exposes your <<undies>> until you push the fabric back down between your thighs. You don't think anyone saw.
+			<<gstress>><<garousal>><<stress 1>><<arousal 600>>
+			<br><br>
 		<<else>>
-		The breeze lifts your $worn.lower.name and exposes your <<undies>> until you push the fabric back down between your thighs.
-		<br><br>
+			The breeze lifts your $worn.lower.name and exposes your <<undies>> until you push the fabric back down between your thighs.
+			<br><br>
 		<</if>>
 	<<else>>
-	The air is cool on your skin.
-	<<lstress>><<stress -1>>
-	<br><br>
+		The air is cool on your skin.
+		<<lstress>><<stress -1>>
+		<br><br>
 	<</if>>
 
 	<<if $schoolstate isnot "late">>
-	<<link [[Keep relaxing (0:10)|School Stump]]>><<pass 10>><<stress -1>><<tiredness -1>><</link>><<ltiredness>><<lstress>>
-	<br>
+		<<link [[Keep relaxing (0:10)|School Stump]]>><<pass 10>><<stress -1>><<tiredness -1>><</link>><<ltiredness>><<lstress>>
+		<br>
 	<</if>>
-<<link [[Stop|School Rear Playground]]>><</link>>
-<br>
+	<<link [[Stop|School Rear Playground]]>><</link>>
+	<br>
 
 <<else>>
 
-<<generate1>><<person1>>"Hey," a voice says in a hushed tone. "You on the stump." You open your eyes. A <<person>> stands on the other side of the fence, in an alley beside the school. "What you got under those clothes?"
-<br><br>
+	<<generate1>><<person1>>"Hey," a voice says in a hushed tone. "You on the stump." You open your eyes. A <<person>> stands on the other side of the fence, in an alley beside the school. "What you got under those clothes?"
+	<br><br>
 
-<<link [[Ignore|School Stump Ignore]]>><<stress 1>><</link>><<gstress>>
-<br>
+	<<link [[Ignore|School Stump Ignore]]>><<stress 1>><</link>><<gstress>>
+	<br>
 	<<if $worn.under_lower.type.includes("naked") or $worn.genitals.type.includes("chastity")>>
 		<<if $exhibitionism gte 75>>
-		<<link [[Flash|School Stump Genital Flash]]>><</link>><<exhibitionist5>>
-		<br>
+			<<link [[Flash|School Stump Genital Flash]]>><</link>><<exhibitionist5>>
+			<br>
 		<</if>>
 	<<else>>
 		<<if $exhibitionism gte 15>>
-		<<link [[Flash|School Stump Flash]]>><</link>><<exhibitionist2>>
-		<br>
+			<<link [[Flash|School Stump Flash]]>><</link>><<exhibitionist2>>
+			<br>
 		<</if>>
 	<</if>>
 
diff --git a/game/overworld-town/special-kylar/main.twee b/game/overworld-town/special-kylar/main.twee
index 656ebe6649..56c84626af 100644
--- a/game/overworld-town/special-kylar/main.twee
+++ b/game/overworld-town/special-kylar/main.twee
@@ -578,8 +578,7 @@
 		"I've thought up names for our children," Kylar says with a smile. <<He>> rattles off several names for boys and girls. You recognise some as anime characters. You suspect the ones you don't recognise are as well.
 		<br><br>
 
-		<<set $_breed to (playerCanBreedWith("Kylar") ? "breed" : "adopt kids")>>
-		<<link [[`Inform Kylar that you wouldn't ${$_breed} with ${_kylar.pronouns.him} if ${_kylar.pronouns.he} were the last ${_kylar.pronouns.boy} on earth`|Kylar Abduction Kids Insult]]>><</link>>
+		<<link [[`Inform Kylar that you wouldn't raise a family with ${_kylar.pronouns.him} if ${_kylar.pronouns.he} were the last ${_kylar.pronouns.boy} on earth`|Kylar Abduction Kids Insult]]>><</link>>
 		<br>
 		<<link [[Say the names are nice|Kylar Abduction Kids Nice]]>><</link>>
 		<br>
-- 
GitLab


From 0338d38c2ebd44b73c3542ea7a91f7f28229aaf8 Mon Sep 17 00:00:00 2001
From: note leven <21133-noteleven@users.noreply.gitgud.io>
Date: Sun, 11 Sep 2022 21:49:54 +0000
Subject: [PATCH 33/50] js linting and cleanup

---
 .../02-version/waiting-room.twee              |    1 -
 game/01-config/sugarcubeConfig.js             |  306 +-
 game/03-JavaScript/00-libs/mousetrap.min.js   |   11 +
 game/03-JavaScript/EventDebug.js              |    7 +-
 game/03-JavaScript/IronMan.js                 |   15 +-
 game/03-JavaScript/UI.js                      |  544 +--
 game/03-JavaScript/base-clothing.js           |  173 +-
 game/03-JavaScript/base.js                    |  560 ++-
 game/03-JavaScript/bedroomPills.js            | 1043 +++---
 game/03-JavaScript/canvasmodel.js             |   16 +
 game/03-JavaScript/clothing-shop-v2.js        |  510 +--
 game/03-JavaScript/debugMenu.js               | 3207 ++++++-----------
 game/03-JavaScript/ingame.js                  | 1736 ++++-----
 game/03-JavaScript/save.js                    |   96 +-
 .../04-Variables/variables-passageHeader.twee |    1 -
 .../04-Variables/variables-versionUpdate.twee |    4 -
 game/base-system/caption.twee                 |   41 +-
 game/base-system/overlays/featsUI.twee        |    2 +-
 game/base-system/settings.twee                |   17 +-
 game/base-system/widgets.js                   |  313 +-
 game/overworld-town/loc-shop/clothing-v2.twee |    2 +-
 21 files changed, 3822 insertions(+), 4783 deletions(-)
 create mode 100644 game/03-JavaScript/00-libs/mousetrap.min.js

diff --git a/game/00-framework-tools/02-version/waiting-room.twee b/game/00-framework-tools/02-version/waiting-room.twee
index 736d7ab828..803ee286b5 100644
--- a/game/00-framework-tools/02-version/waiting-room.twee
+++ b/game/00-framework-tools/02-version/waiting-room.twee
@@ -9,7 +9,6 @@ Remember to update your save if things appear to be working.
 <<pregnancyVar>>
 
 <<if $reducedLineHeight is true>><<addclass "#passages" "reducedLineHeight">><</if>>
-<<if $zoom isnot 100>><<run zoom($zoom)>><</if>>
 <<set $runWardrobeSanityChecker to true>>
 <</silently>>
 
diff --git a/game/01-config/sugarcubeConfig.js b/game/01-config/sugarcubeConfig.js
index 5c77914310..29560c8fff 100644
--- a/game/01-config/sugarcubeConfig.js
+++ b/game/01-config/sugarcubeConfig.js
@@ -2,44 +2,44 @@ Config.history.controls = false;
 Config.saves.slots = 9;
 Config.history.maxStates = 1;
 
-State.prng.init()
+State.prng.init();
 
 window.versionUpdateCheck = true;
 window.onLoadUpdateCheck = false;
 
-Save.onLoad.add(function(save) {
+Save.onLoad.add(save => {
 	window.onLoadUpdateCheck = true;
 });
 
 let isReloading = true;
 let pageLoading = false;
 
-Save.onLoad.add(function(save) {
-	pageLoading = true
+Save.onLoad.add(save => {
+	pageLoading = true;
 });
 
-
-Save.onSave.add(function(save) {
-	new Wikifier(null, '<<updateFeats>>');
-	prepareSaveDetails();
+Save.onSave.add(save => {
+	Wikifier.wikifyEval("<<updateFeats>>");
+	// eslint-disable-next-line no-undef
+	prepareSaveDetails(); // defined in save.js
 });
 
-/*LinkNumberify and images will enable or disable the feature completely*/
-/*debug will enable or disable the feature only for new games*/
-/*sneaky will enable the Sneaky notice banner on the opening screen and save display*/
+/* LinkNumberify and images will enable or disable the feature completely */
+/* debug will enable or disable the feature only for new games */
+/* sneaky will enable the Sneaky notice banner on the opening screen and save display */
 window.StartConfig = {
-	"debug": false,
-	"enableImages": true,
-	"enableLinkNumberify": true,
-	"version": "0.3.11.4",
-	"sneaky" : false,
-}
+	debug: false,
+	enableImages: true,
+	enableLinkNumberify: true,
+	version: "0.3.11.4",
+	sneaky: false,
+};
 
 /* convert version string to numeric value */
-let tmpver = StartConfig.version.replace(/[^0-9.]+/g, "").split(".");
-window.StartConfig.version_numeric = tmpver[0]*1000000 + tmpver[1]*10000 + tmpver[2]*100 + tmpver[3]*1;
+const tmpver = StartConfig.version.replace(/[^0-9.]+/g, "").split(".");
+window.StartConfig.version_numeric = tmpver[0] * 1000000 + tmpver[1] * 10000 + tmpver[2] * 100 + tmpver[3] * 1;
 
-config.saves.autosave = "autosave";
+Config.saves.autosave = "autosave";
 
 Config.saves.isAllowed = function () {
 	if (tags().includes("nosave")) {
@@ -48,21 +48,21 @@ Config.saves.isAllowed = function () {
 	return true;
 };
 
-$(document).on(':passagestart', function(ev) {
-	if (ev.passage.title === 'Start2') {
+$(document).on(":passagestart", function (ev) {
+	if (ev.passage.title === "Start2") {
 		jQuery.event.trigger({
-			type    : ':start2',
-			content : ev.content,
-			passage : ev.passage
+			type: ":start2",
+			content: ev.content,
+			passage: ev.passage,
 		});
 	}
 });
 
 importStyles("style.css")
 	.then(function () {
-		console.log("External Style Sheet Active")
+		console.log("External Style Sheet Active");
 	})
-	.catch(function (err) {
+	.catch(function () {
 		console.log("External Style Sheet Missing");
 	});
 
@@ -85,7 +85,7 @@ importScripts([
 })
 .catch(function (err) {
 	console.log(err);
-});*/
+}); */
 
 // Runs before a passage load, returning a string redirects to the new passage name.
 Config.navigation.override = function (dest) {
@@ -98,145 +98,145 @@ Config.navigation.override = function (dest) {
 		if (lastVersion > currVersion) {
 			isReloading = false;
 			V.bypassHeader = true;
-			return 'Downgrade Waiting Room';
+			return "Downgrade Waiting Room";
 		}
 	}
 
 	isReloading = false;
-	pageLoading = false
+	pageLoading = false;
 
 	switch (dest) {
-		case 'Downgrade Waiting Room':
+		case "Downgrade Waiting Room":
 			return V.passage;
-		case 'Pharmacy Select Custom Lenses':
-			return isLoading ? 'Pharmacy Ask Custom Lenses' : false;
-		case 'Forest Shop Outfit':
-		case 'Forest Shop Upper':
-		case 'Forest Shop Lower':
-		case 'Forest Shop Under Outfit':
-		case 'Forest Shop Under Upper':
-		case 'Forest Shop Under Lower':
-		case 'Forest Shop Head':
-		case 'Forest Shop Face':
-		case 'Forest Shop Neck':
-		case 'Forest Shop Legs':
-		case 'Forest Shop Feet':
-			return 'Forest Shop';
+		case "Pharmacy Select Custom Lenses":
+			return isLoading ? "Pharmacy Ask Custom Lenses" : false;
+		case "Forest Shop Outfit":
+		case "Forest Shop Upper":
+		case "Forest Shop Lower":
+		case "Forest Shop Under Outfit":
+		case "Forest Shop Under Upper":
+		case "Forest Shop Under Lower":
+		case "Forest Shop Head":
+		case "Forest Shop Face":
+		case "Forest Shop Neck":
+		case "Forest Shop Legs":
+		case "Forest Shop Feet":
+			return "Forest Shop";
 
-		case 'Over Outfit Shop':
-		case 'Outfit Shop':
-		case 'Top Shop':
-		case 'Bottom Shop':
-		case 'Under Outfit Shop':
-		case 'Under Top Shop':
-		case 'Under Bottom Shop':
-		case 'Head Shop':
-		case 'Face Shop':
-		case 'Neck Shop':
-		case 'Hands Shop':
-		case 'Legs Shop':
-		case 'Shoe Shop':
-			return 'Clothing Shop';
-
-		case 'Penis Inspection Flaunt Crossdress':
-			return 'Penis Inspection Flaunt No Penis';
-
-		case 'Pussy Inspection2':
-			return 'Pussy Inspection 2';
-
-		case 'Pussy Inspection Penis':
-			return 'Pussy Inspection Flaunt No Pussy';
-
-		case 'Forest Plant Sex No Tentacles':
-			return 'Forest Plant Sex';
-
-		case 'Forest Plant Sex No Tentacles Finish':
-			return 'Forest Plant Sex Finish';
-
-		case 'Forest Plant Passout No Tentacles':
-			return 'Forest';
-
-		case 'Moor Plant Sex No Tentacles':
-			return 'Moor Plant Sex';
-
-		case 'Moor Plant Sex No Tentacles Finish':
-			return 'Moor Plant Sex Finish';
-
-		case 'Underground Plant Molestation No Tentacles':
-			return 'Underground Plant Molestation';
-
-		case 'Underground Plant Molestation No Tentacles Finish':
-			return 'Underground Plant Molestation Finish';
-
-		case 'Evens Swimming Endure':
-			return 'Events Swimming Swim Endure';
-
-		case 'Domus House Work':
-			return 'Domus Gutters Intro';
-
-		case 'Trash Boys':
-			return 'Trash Compare';
-
-		case 'Trash Boys Spy':
-			return 'Trash Compare Spy';
-
-		case 'Trash Boys Greet':
-			return 'Trash Compare Greet';
-
-		case 'Trash Boys Refuse':
-			return 'Trash Compare Refuse';
-
-		case 'Trash Boys Compare':
-			return 'Trash Compare Others';
-
-		case 'Trash Boys Back Out':
-			return 'Trash Compare Back Out';
-
-		case 'Trash Boys Show':
-			return 'Trash Compare Show';
-
-		case 'Trash Boys Offer Secret':
-			return 'Trash Compare Penis Secret';
-
-		case 'Trash Boys Wrap It Up':
-			return 'Trash Compare Wrap It Up';
-
-		case 'Trash Boys Crossdressing Refuse':
-			return 'Trash Compare Breast Refuse';
-
-		case 'Trash Boys Crossdressing Show All':
-			return 'Trash Compare Breast Show All';
-
-		case 'Trash Boys Forced Strip':
-			return 'Trash Compare Forced Strip';
+		case "Over Outfit Shop":
+		case "Outfit Shop":
+		case "Top Shop":
+		case "Bottom Shop":
+		case "Under Outfit Shop":
+		case "Under Top Shop":
+		case "Under Bottom Shop":
+		case "Head Shop":
+		case "Face Shop":
+		case "Neck Shop":
+		case "Hands Shop":
+		case "Legs Shop":
+		case "Shoe Shop":
+			return "Clothing Shop";
+
+		case "Penis Inspection Flaunt Crossdress":
+			return "Penis Inspection Flaunt No Penis";
+
+		case "Pussy Inspection2":
+			return "Pussy Inspection 2";
+
+		case "Pussy Inspection Penis":
+			return "Pussy Inspection Flaunt No Pussy";
+
+		case "Forest Plant Sex No Tentacles":
+			return "Forest Plant Sex";
+
+		case "Forest Plant Sex No Tentacles Finish":
+			return "Forest Plant Sex Finish";
+
+		case "Forest Plant Passout No Tentacles":
+			return "Forest";
+
+		case "Moor Plant Sex No Tentacles":
+			return "Moor Plant Sex";
+
+		case "Moor Plant Sex No Tentacles Finish":
+			return "Moor Plant Sex Finish";
+
+		case "Underground Plant Molestation No Tentacles":
+			return "Underground Plant Molestation";
+
+		case "Underground Plant Molestation No Tentacles Finish":
+			return "Underground Plant Molestation Finish";
+
+		case "Evens Swimming Endure":
+			return "Events Swimming Swim Endure";
+
+		case "Domus House Work":
+			return "Domus Gutters Intro";
+
+		case "Trash Boys":
+			return "Trash Compare";
+
+		case "Trash Boys Spy":
+			return "Trash Compare Spy";
+
+		case "Trash Boys Greet":
+			return "Trash Compare Greet";
+
+		case "Trash Boys Refuse":
+			return "Trash Compare Refuse";
+
+		case "Trash Boys Compare":
+			return "Trash Compare Others";
+
+		case "Trash Boys Back Out":
+			return "Trash Compare Back Out";
+
+		case "Trash Boys Show":
+			return "Trash Compare Show";
+
+		case "Trash Boys Offer Secret":
+			return "Trash Compare Penis Secret";
+
+		case "Trash Boys Wrap It Up":
+			return "Trash Compare Wrap It Up";
+
+		case "Trash Boys Crossdressing Refuse":
+			return "Trash Compare Breast Refuse";
+
+		case "Trash Boys Crossdressing Show All":
+			return "Trash Compare Breast Show All";
+
+		case "Trash Boys Forced Strip":
+			return "Trash Compare Forced Strip";
 
-		case 'Trash Boys Combat Win':
-			return 'Trash Compare Combat Win';
+		case "Trash Boys Combat Win":
+			return "Trash Compare Combat Win";
 
-		case 'Trash Boys Combat Loss':
-			return 'Trash Compare Combat Loss';
+		case "Trash Boys Combat Loss":
+			return "Trash Compare Combat Loss";
 
-		case 'Lake Underwater Tentacles Finish Figure':
-			return 'Lake Underwater Tentacles Finish';
+		case "Lake Underwater Tentacles Finish Figure":
+			return "Lake Underwater Tentacles Finish";
 
-		case 'Sextoys Inventory Home':
-		case 'Sextoys Inventory Brothel':
-		case 'Sextoys Inventory Cottage':
-		case 'Sextoys Inventory Cabin':
-			return 'Sextoys Inventory';
+		case "Sextoys Inventory Home":
+		case "Sextoys Inventory Brothel":
+		case "Sextoys Inventory Cottage":
+		case "Sextoys Inventory Cabin":
+			return "Sextoys Inventory";
 
-		case 'Kylar Abduction Angry':
-		case 'Kylar Abduction Apologise':
-		case 'Kylar Abduction Silent':
-		case 'Kylar Abduction Eden':
-		case 'Kylar Abduction Robin':
-		case 'Kylar Abduction Whitney':
-		case 'Kylar Abduction Sydney':
-		case 'Kylar Abduction Wolf':
-		case 'Kylar Abduction Hawk':
-			return 'Kylar Abduction Event Response';
+		case "Kylar Abduction Angry":
+		case "Kylar Abduction Apologise":
+		case "Kylar Abduction Silent":
+		case "Kylar Abduction Eden":
+		case "Kylar Abduction Robin":
+		case "Kylar Abduction Whitney":
+		case "Kylar Abduction Sydney":
+		case "Kylar Abduction Wolf":
+		case "Kylar Abduction Hawk":
+			return "Kylar Abduction Event Response";
 
 		default:
 			return false;
 	}
-}
+};
diff --git a/game/03-JavaScript/00-libs/mousetrap.min.js b/game/03-JavaScript/00-libs/mousetrap.min.js
new file mode 100644
index 0000000000..185c42fd15
--- /dev/null
+++ b/game/03-JavaScript/00-libs/mousetrap.min.js
@@ -0,0 +1,11 @@
+/* mousetrap v1.6.5 craig.is/killing/mice */
+(function(q,u,c){function v(a,b,g){a.addEventListener?a.addEventListener(b,g,!1):a.attachEvent("on"+b,g)}function z(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return b}return n[a.which]?n[a.which]:r[a.which]?r[a.which]:String.fromCharCode(a.which).toLowerCase()}function F(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function w(a){return"shift"==a||"ctrl"==a||"alt"==a||
+"meta"==a}function A(a,b){var g,d=[];var e=a;"+"===e?e=["+"]:(e=e.replace(/\+{2}/g,"+plus"),e=e.split("+"));for(g=0;g<e.length;++g){var m=e[g];B[m]&&(m=B[m]);b&&"keypress"!=b&&C[m]&&(m=C[m],d.push("shift"));w(m)&&d.push(m)}e=m;g=b;if(!g){if(!p){p={};for(var c in n)95<c&&112>c||n.hasOwnProperty(c)&&(p[n[c]]=c)}g=p[e]?"keydown":"keypress"}"keypress"==g&&d.length&&(g="keydown");return{key:m,modifiers:d,action:g}}function D(a,b){return null===a||a===u?!1:a===b?!0:D(a.parentNode,b)}function d(a){function b(a){a=
+a||{};var b=!1,l;for(l in p)a[l]?b=!0:p[l]=0;b||(x=!1)}function g(a,b,t,f,g,d){var l,E=[],h=t.type;if(!k._callbacks[a])return[];"keyup"==h&&w(a)&&(b=[a]);for(l=0;l<k._callbacks[a].length;++l){var c=k._callbacks[a][l];if((f||!c.seq||p[c.seq]==c.level)&&h==c.action){var e;(e="keypress"==h&&!t.metaKey&&!t.ctrlKey)||(e=c.modifiers,e=b.sort().join(",")===e.sort().join(","));e&&(e=f&&c.seq==f&&c.level==d,(!f&&c.combo==g||e)&&k._callbacks[a].splice(l,1),E.push(c))}}return E}function c(a,b,c,f){k.stopCallback(b,
+b.target||b.srcElement,c,f)||!1!==a(b,c)||(b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopPropagation?b.stopPropagation():b.cancelBubble=!0)}function e(a){"number"!==typeof a.which&&(a.which=a.keyCode);var b=z(a);b&&("keyup"==a.type&&y===b?y=!1:k.handleKey(b,F(a),a))}function m(a,g,t,f){function h(c){return function(){x=c;++p[a];clearTimeout(q);q=setTimeout(b,1E3)}}function l(g){c(t,g,a);"keyup"!==f&&(y=z(g));setTimeout(b,10)}for(var d=p[a]=0;d<g.length;++d){var e=d+1===g.length?l:h(f||
+A(g[d+1]).action);n(g[d],e,f,a,d)}}function n(a,b,c,f,d){k._directMap[a+":"+c]=b;a=a.replace(/\s+/g," ");var e=a.split(" ");1<e.length?m(a,e,b,c):(c=A(a,c),k._callbacks[c.key]=k._callbacks[c.key]||[],g(c.key,c.modifiers,{type:c.action},f,a,d),k._callbacks[c.key][f?"unshift":"push"]({callback:b,modifiers:c.modifiers,action:c.action,seq:f,level:d,combo:a}))}var k=this;a=a||u;if(!(k instanceof d))return new d(a);k.target=a;k._callbacks={};k._directMap={};var p={},q,y=!1,r=!1,x=!1;k._handleKey=function(a,
+d,e){var f=g(a,d,e),h;d={};var k=0,l=!1;for(h=0;h<f.length;++h)f[h].seq&&(k=Math.max(k,f[h].level));for(h=0;h<f.length;++h)f[h].seq?f[h].level==k&&(l=!0,d[f[h].seq]=1,c(f[h].callback,e,f[h].combo,f[h].seq)):l||c(f[h].callback,e,f[h].combo);f="keypress"==e.type&&r;e.type!=x||w(a)||f||b(d);r=l&&"keydown"==e.type};k._bindMultiple=function(a,b,c){for(var d=0;d<a.length;++d)n(a[d],b,c)};v(a,"keypress",e);v(a,"keydown",e);v(a,"keyup",e)}if(q){var n={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",
+18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},r={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},C={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},B={option:"alt",command:"meta","return":"enter",
+escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},p;for(c=1;20>c;++c)n[111+c]="f"+c;for(c=0;9>=c;++c)n[c+96]=c.toString();d.prototype.bind=function(a,b,c){a=a instanceof Array?a:[a];this._bindMultiple.call(this,a,b,c);return this};d.prototype.unbind=function(a,b){return this.bind.call(this,a,function(){},b)};d.prototype.trigger=function(a,b){if(this._directMap[a+":"+b])this._directMap[a+":"+b]({},a);return this};d.prototype.reset=function(){this._callbacks={};
+this._directMap={};return this};d.prototype.stopCallback=function(a,b){if(-1<(" "+b.className+" ").indexOf(" mousetrap ")||D(b,this.target))return!1;if("composedPath"in a&&"function"===typeof a.composedPath){var c=a.composedPath()[0];c!==a.target&&(b=c)}return"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.isContentEditable};d.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)};d.addKeycodes=function(a){for(var b in a)a.hasOwnProperty(b)&&(n[b]=a[b]);p=null};
+d.init=function(){var a=d(u),b;for(b in a)"_"!==b.charAt(0)&&(d[b]=function(b){return function(){return a[b].apply(a,arguments)}}(b))};d.init();q.Mousetrap=d;"undefined"!==typeof module&&module.exports&&(module.exports=d);"function"===typeof define&&define.amd&&define(function(){return d})}})("undefined"!==typeof window?window:null,"undefined"!==typeof window?document:null);
diff --git a/game/03-JavaScript/EventDebug.js b/game/03-JavaScript/EventDebug.js
index c77eff22a5..521e01994e 100644
--- a/game/03-JavaScript/EventDebug.js
+++ b/game/03-JavaScript/EventDebug.js
@@ -27,10 +27,9 @@ class EventData {
 
 	Push(passage, index, time) {
 		if (this.disable) return;
-		V.event = ensure(V.event, {
-			buffer: [],
-			schema: 1,
-		});
+		if (V.event == null) {
+			V.event = { buffer: [], schema: 1 };
+		}
 		V.event.buffer.push({
 			slot: index,
 			time,
diff --git a/game/03-JavaScript/IronMan.js b/game/03-JavaScript/IronMan.js
index a7345ed987..161b91243c 100644
--- a/game/03-JavaScript/IronMan.js
+++ b/game/03-JavaScript/IronMan.js
@@ -73,7 +73,7 @@ var IronMan = (Save => {
 				virginity: Object.assign({}, readonly, { value: V.player.virginity }),
 			});
 			Object.defineProperties(V.options, {
-				autosaveDisabled: Object.assign({}, readonly, { value: true })
+				autosaveDisabled: Object.assign({}, readonly, { value: true }),
 			});
 			if (!IRONMAN_DEBUG) {
 				Object.defineProperty(V, "debug", Object.assign({}, readonly, { value: 0 }));
@@ -134,6 +134,17 @@ var IronMan = (Save => {
 		UI Functions relating to IronMan mode.
 		-------------------------------------- */
 
+	function sliderPerc(e) {
+		const valSpan = $(e.currentTarget).siblings().first();
+		const value = valSpan.text();
+
+		valSpan.text((i, value) => Math.round(value * 100) + "%");
+
+		if (value > 1) valSpan.css("color", "gold");
+		else if (value < 1) valSpan.css("color", "green");
+		else valSpan.css("color", "unset");
+	}
+
 	function uiCheckBox(mode = "normal") {
 		$(function () {
 			const checkbox = document.getElementById("checkbox-ironmanmode");
@@ -331,7 +342,7 @@ var IronMan = (Save => {
 			//
 			V.ironmanautosaveschedule = (
 				date.getTime() +
-				getRandomIntInclusive(432000, 777600) * 1000
+				random(432000, 777600) * 1000
 			).toString(8);
 		}
 	}
diff --git a/game/03-JavaScript/UI.js b/game/03-JavaScript/UI.js
index 8070c82af7..2a0afb9fa8 100644
--- a/game/03-JavaScript/UI.js
+++ b/game/03-JavaScript/UI.js
@@ -1,6 +1,7 @@
-window.overlayShowHide = function (elementId) {
-	var div = document.getElementById(elementId);
-	if (div != undefined) {
+/* eslint-disable jsdoc/require-description-complete-sentence */
+function overlayShowHide(elementId) {
+	const div = document.getElementById(elementId);
+	if (div != null) {
 		div.classList.toggle("hidden");
 		if (elementId === "debugOverlay") {
 			V.debugMenu[0] = !V.debugMenu[0];
@@ -8,46 +9,48 @@ window.overlayShowHide = function (elementId) {
 	}
 	window.cacheDebugDiv();
 }
+window.overlayShowHide = overlayShowHide;
 
-window.overlayMenu = function (elementId, type) {
-	if (type == "debug"){
-		window.toggleClassDebug(elementId+"Button", "bg-color")
+function overlayMenu(elementId, type) {
+	if (type === "debug") {
+		window.toggleClassDebug(elementId + "Button", "bg-color");
 		V.debugMenu[1] = elementId;
-		if (document.getElementById(elementId) != undefined) {
-			if (V.debugMenu[2].length > 0)
-				window.toggleClassDebug(elementId, "hideWhileSearching")
-			else
-				window.toggleClassDebug(elementId, "classicHide")
+		if (document.getElementById(elementId) != null) {
+			if (V.debugMenu[2].length > 0) window.toggleClassDebug(elementId, "hideWhileSearching");
+			else window.toggleClassDebug(elementId, "classicHide");
 		}
-		if ((elementId == "debugFavourites" || elementId == "debugAdd") && V.debugMenu[2] != undefined && V.debugMenu[2].length > 0){
+		if ((elementId === "debugFavourites" || elementId === "debugAdd") && V.debugMenu[2] != null && V.debugMenu[2].length > 0) {
 			V.debugMenu[2] = "";
-			document.getElementById('searchEvents').value = ""
-			window.researchEvents("")
+			document.getElementById("searchEvents").value = "";
+			window.researchEvents("");
 		}
-		if (elementId == "debugFavourites"){
+		if (elementId === "debugFavourites") {
 			window.patchDebugMenu();
 		}
 	}
 	window.cacheDebugDiv();
 }
+window.overlayMenu = overlayMenu;
 
-/*Sidebar swipe*/
-document.addEventListener('touchstart', handleTouchStart, false);
-document.addEventListener('touchmove', handleTouchMove, false);
+/* Sidebar swipe */
+document.addEventListener("touchstart", handleTouchStart, false);
+document.addEventListener("touchmove", handleTouchMove, false);
 
-var xDown = null;
-var yDown = null;
+let xDown = null;
+let yDown = null;
 
 function getTouches(evt) {
-	return evt.touches ||			 // browser API
-		evt.originalEvent.touches; // jQuery
+	return (
+		evt.touches || // browser API
+		evt.originalEvent.touches // jQuery
+	);
 }
 
 function handleTouchStart(evt) {
-	var firstTouch = getTouches(evt)[0];
+	const firstTouch = getTouches(evt)[0];
 	xDown = firstTouch.clientX;
 	yDown = firstTouch.clientY;
-};
+}
 
 function handleTouchMove(evt) {
 	if (!xDown || !yDown) {
@@ -59,7 +62,7 @@ function handleTouchMove(evt) {
 	 * 50px - +/- width of unstowed UI Bar
 	 * 280px - +/- width of unstowed UI bar
 	 */
-	if (isUIBarStowed()) {
+	if (UIBar.isStowed()) {
 		if (xDown > 50) {
 			return;
 		}
@@ -69,235 +72,193 @@ function handleTouchMove(evt) {
 		}
 	}
 
-	var xUp = evt.touches[0].clientX;
-	var yUp = evt.touches[0].clientY;
+	const xUp = evt.touches[0].clientX;
+	const yUp = evt.touches[0].clientY;
 
-	var xDiff = xDown - xUp;
-	var yDiff = yDown - yUp;
+	const xDiff = xDown - xUp;
+	const yDiff = yDown - yUp;
 
-	if (Math.abs(xDiff) > Math.abs(yDiff)) {/*most significant*/
+	if (Math.abs(xDiff) > Math.abs(yDiff)) {
+		// most significant
 		if (xDiff > 0) {
-			UIBar.stow();/* left swipe */
+			UIBar.stow(); // left swipe
 		} else {
-			UIBar.unstow();/* right swipe */
+			UIBar.unstow(); // right swipe
 		}
 	} else {
 		if (yDiff > 0) {
-			/* up swipe */
+			// up swipe
 		} else {
-			/* down swipe */
+			// down swipe
 		}
 	}
-	/* reset values */
+	// reset values
 	xDown = null;
 	yDown = null;
-};
-
-function isUIBarStowed() {
-	return $('#ui-bar').hasClass('stowed');
 }
 
-var disableNumberifyInVisibleElements = [
-	'#passage-testing-room',
-];
+const disableNumberifyInVisibleElements = ["#passage-testing-room"];
 
 // Number-ify links
 window.Links = window.Links || {};
 Links.currentLinks = [];
 
 function getPrettyKeyNumber(counter) {
-	var str = "";
-
-	if (counter > 30)
-		str = "Ctrl + ";
-	else if (counter > 20)
-		str = "Alt + ";
-	else if (counter > 10)
-		str = "Shift + ";
-
-	if (counter % 10 === 0)
-		str += "0";
-	else if (counter < 10)
-		str += counter;
+	let str = "";
+
+	if (counter > 30) str = "Ctrl + ";
+	else if (counter > 20) str = "Alt + ";
+	else if (counter > 10) str = "Shift + ";
+
+	if (counter % 10 === 0) str += "0";
+	else if (counter < 10) str += counter;
 	else {
-		var c = Math.floor(counter / 10);
-		str += (counter - (10 * c)).toString();
+		const c = Math.floor(counter / 10);
+		str += (counter - 10 * c).toString();
 	}
 
 	return str;
 }
 
-$(document).on(':passagerender', function (ev) {
+$(document).on(":passagerender", function (ev) {
 	Links.currentLinks = [];
 
-	if (passage() == "GiveBirth") {
-		$(ev.content).find("[type=checkbox]").on('propertychange change', function () {
-			new Wikifier(null, '<<resetPregButtons>>');
-			Links.generateLinkNumbers(ev.content);
-		});
+	if (passage() === "GiveBirth") {
+		$(ev.content)
+			.find("[type=checkbox]")
+			.on("propertychange change", function () {
+				Wikifier.wikifyEval("<<resetPregButtons>>");
+				Links.generateLinkNumbers(ev.content);
+			});
 	}
 
 	Links.generateLinkNumbers(ev.content);
 });
 
-Links.keyNumberMatcher = /^\([^\)]+\)/
+Links.keyNumberMatcher = /^\([^)]+\)/;
 
-Links.generateLinkNumbers = function generateLinkNumbers(content) {
-	if (!V.numberify_enabled || !StartConfig.enableLinkNumberify)
-		return;
+Links.generateLinkNumbers = content => {
+	if (!V.numberify_enabled || !StartConfig.enableLinkNumberify) return;
 
-	for (var i = 0; i < disableNumberifyInVisibleElements.length; i++) {
-		if ($(content).find(disableNumberifyInVisibleElements[i]).length || $(content).is(disableNumberifyInVisibleElements[i]))
-			return; // simply skip this render
+	for (let i = 0; i < disableNumberifyInVisibleElements.length; i++) {
+		if ($(content).find(disableNumberifyInVisibleElements[i]).length || $(content).is(disableNumberifyInVisibleElements[i])) return; // simply skip this render
 	}
 
 	// wanted to use .macro-link, but wardrobe and something else doesn't get selected, lmao
-	Links.currentLinks = $(content)
-		.find(".link-internal")
-		.not(".no-numberify *, .no-numberify");
+	Links.currentLinks = $(content).find(".link-internal").not(".no-numberify *, .no-numberify");
 
 	$(Links.currentLinks).each(function (i, el) {
 		if (Links.keyNumberMatcher.test(el.innerHTML)) {
-			el.innerHTML = el.innerHTML.replace(Links.keyNumberMatcher, `(${getPrettyKeyNumber(i + 1)})`)
+			el.innerHTML = el.innerHTML.replace(Links.keyNumberMatcher, `(${getPrettyKeyNumber(i + 1)})`);
 		} else {
 			$(el).html("(" + getPrettyKeyNumber(i + 1) + ") " + $(el).html());
 		}
 	});
-}
+};
 Links.generate = () => Links.generateLinkNumbers(document.getElementsByClassName("passage")[0] || document);
 
-$(document).on('keyup', function (ev) {
-	if (!V.numberify_enabled || !StartConfig.enableLinkNumberify || V.tempDisable)
-		return;
+$(document).on("keyup", function (ev) {
+	if (!V.numberify_enabled || !StartConfig.enableLinkNumberify || V.tempDisable) return;
 
-	if (document.activeElement.tagName === "INPUT" && document.activeElement.type !== "radio"
-		&& document.activeElement.type !== "checkbox")
+	if (document.activeElement.tagName === "INPUT" && document.activeElement.type !== "radio" && document.activeElement.type !== "checkbox")
 		return;
 
 	if ((ev.keyCode >= 48 && ev.keyCode <= 57) || (ev.keyCode >= 96 && ev.keyCode <= 105)) {
-		var fixedKeyIndex = (ev.keyCode < 60 ? ev.keyCode - 48 : ev.keyCode - 96);
-
-		var requestedLinkIndex = [
-			9,
-			0,
-			1,
-			2,
-			3,
-			4,
-			5,
-			6,
-			7,
-			8
-		][fixedKeyIndex];
-
-		if (ev.ctrlKey)
-			requestedLinkIndex += 30;
-		else if (ev.altKey)
-			requestedLinkIndex += 20;
-		else if (ev.shiftKey)
-			requestedLinkIndex += 10;
-
-		if ($(Links.currentLinks).length >= requestedLinkIndex + 1)
-			$(Links.currentLinks[requestedLinkIndex]).click();
+		const fixedKeyIndex = ev.keyCode < 60 ? ev.keyCode - 48 : ev.keyCode - 96;
+
+		let requestedLinkIndex = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8][fixedKeyIndex];
+
+		if (ev.ctrlKey) requestedLinkIndex += 30;
+		else if (ev.altKey) requestedLinkIndex += 20;
+		else if (ev.shiftKey) requestedLinkIndex += 10;
+
+		if ($(Links.currentLinks).length >= requestedLinkIndex + 1) $(Links.currentLinks[requestedLinkIndex]).click();
 	}
 });
 
-var defaultSkinColorRanges = {
-	"hStart": 45, "hEnd": 45,
-	"sStart": 0.2, "sEnd": 0.4,
-	"bStart": 4.5, "bEnd": 0.7,
+const defaultSkinColorRanges = {
+	hStart: 45,
+	hEnd: 45,
+	sStart: 0.2,
+	sEnd: 0.4,
+	bStart: 4.5,
+	bEnd: 0.7,
 };
 
-window.skinColor = function (enabled, percent, overwrite) {
+function ensureIsArray(x, check = false) {
+	if (check) x = x != null ? x : [];
+	if (Array.isArray(x)) return x;
+	return [x];
+}
+window.ensureIsArray = ensureIsArray;
+
+function skinColor(enabled, percent, overwrite) {
 	if (enabled === false) {
 		return "";
 	}
 
-	var ranges = ensureIsArray(overwrite || defaultSkinColorRanges);
-	var totalProgress = percent / 100;
+	const ranges = ensureIsArray(overwrite || defaultSkinColorRanges);
+	const totalProgress = percent / 100;
 
-	var scaledProgress = ranges.length * totalProgress;
-	var rangeIndex = totalProgress === 1
-		? ranges.length - 1
-		: Math.floor(scaledProgress);
-	var progress = totalProgress === 1
-		? 1
-		: scaledProgress - rangeIndex;
+	const scaledProgress = ranges.length * totalProgress;
+	const rangeIndex = totalProgress === 1 ? ranges.length - 1 : Math.floor(scaledProgress);
+	const progress = totalProgress === 1 ? 1 : scaledProgress - rangeIndex;
 
-	var { hStart, hEnd, sStart, sEnd, bStart, bEnd } = ranges[rangeIndex];
+	const { hStart, hEnd, sStart, sEnd, bStart, bEnd } = ranges[rangeIndex];
 
-	var hue = (hEnd - hStart) * progress + hStart;
-	var saturation = (sEnd - sStart) * progress + sStart;
-	var brightness = (bEnd - bStart) * progress + bStart;
+	const hue = (hEnd - hStart) * progress + hStart;
+	const saturation = (sEnd - sStart) * progress + sStart;
+	const brightness = (bEnd - bStart) * progress + bStart;
 
-	var hueCss = `hue-rotate(${hue}deg)`;
-	var saturationCss = `saturate(${saturation.toFixed(2)})`;
-	var brightnessCss = `brightness(${brightness.toFixed(2)})`;
+	const hueCss = `hue-rotate(${hue}deg)`;
+	const saturationCss = `saturate(${saturation.toFixed(2)})`;
+	const brightnessCss = `brightness(${brightness.toFixed(2)})`;
 
 	return `${hueCss} ${saturationCss} ${brightnessCss}`;
 }
+window.skinColor = skinColor;
 
-window.closeFeats = function (id) {
-	var div1 = document.getElementById("feat-" + id);
-	var div2 = document.getElementById("closeFeat-" + id);
+// feats related widgets
+function closeFeats(id) {
+	const div1 = document.getElementById("feat-" + id);
+	const div2 = document.getElementById("closeFeat-" + id);
 	div1.style.display = "none";
 	div2.style.display = "none";
 }
+window.closeFeats = closeFeats;
 
-window.filterFeats = function () {
-	new Wikifier(null, '<<replace #featsList>><<featsList>><</replace>>');
-}
-
-window.getTimeNumber = function (t) {
-	var time = new Date(t);
-	var result = time.getTime();
+function getTimeNumber(t) {
+	const time = new Date(t);
+	const result = time.getTime();
 	if (isNaN(result)) {
-		return 9999999999999999;
+		return 999999999999999;
 	}
 	return result;
 }
+window.getTimeNumber = getTimeNumber;
 
-window.extendStats = function () {
+function extendStats() {
 	V.extendedStats = !V.extendedStats;
-	const captionDiv = document.getElementById('storyCaptionDiv');
+	const captionDiv = document.getElementById("storyCaptionDiv");
 	if (captionDiv === null) return;
 	if (V.extendedStats === true) {
 		captionDiv.classList.add("statsExtended");
 	} else {
 		captionDiv.classList.remove("statsExtended");
 	}
-	new Wikifier(null, '<<replace #stats>><<statsCaption>><</replace>>');
+	Wikifier.wikifyEval("<<replace #stats>><<statsCaption>><</replace>>");
 }
+window.extendStats = extendStats;
 
-window.customColour = function (color, saturation, brightness, contrast, sepia) {
-	return 'filter: hue-rotate(' + color + 'deg) saturate(' + saturation + ') brightness(' + brightness + ') contrast(' + contrast + ') sepia(' + sepia + ')';
+function customColour(color, saturation, brightness, contrast, sepia) {
+	return (
+		// eslint-disable-next-line prettier/prettier
+		"filter: hue-rotate(" + color + "deg) saturate(" + saturation + ") brightness(" + brightness + ") contrast(" + contrast + ") sepia(" + sepia + ")"
+	);
 }
+window.customColour = customColour;
 
-window.zoom = function (size, set) {
-	if (size === undefined) {
-		size = document.getElementById("numberslider-input-zoom").value;
-	}
-	var parsedSize = parseInt(size);
-	var body = document.getElementsByTagName("body")[0];
-	if (parsedSize >= 50 && parsedSize <= 200 && parsedSize !== 100) {
-		body.style.zoom = size + "%";
-		if (set === true) {
-			V.zoom = size;
-		}
-	} else {
-		body.style.zoom = "";
-		if (set === true) {
-			V.zoom = 100;
-		}
-	}
-}
-
-// Checks if image was loaded with errors, input is the id: '#idOfImg'
-window.isImageOk = function (id) {
-	return jQuery(id).naturalWidth !== 0 || true;
-}
-
-window.beastTogglesCheck = function () {
+function beastTogglesCheck() {
 	T.beastVars = [
 		"bestialitydisable",
 		"swarmdisable",
@@ -312,101 +273,121 @@ window.beastTogglesCheck = function () {
 		"beedisable",
 		"lurkerdisable",
 		"horsedisable",
-		"plantdisable"
+		"plantdisable",
 	];
-	T.anyBeastOn = T.beastVars.some(x => V[x] == 'f');
+	T.anyBeastOn = T.beastVars.some(x => V[x] === "f");
 }
+window.beastTogglesCheck = beastTogglesCheck;
 
-window.settingsAsphyxiation = function () {
-	let updateText = () => {
+function settingsAsphyxiation() {
+	const updateText = () => {
 		let val = V.asphyxiaLvl;
 		let text = null;
 		switch (val) {
 			case 0:
-				text = "Don't touch my neck!"; break;
+				text = "Don't touch my neck!";
+				break;
 			case 1:
-				text = "NPCs may <span class='blue inline-colour'>grab</span> you by the neck. Doesn't impede breathing."; break;
+				text = "NPCs may <span class='blue inline-colour'>grab</span> you by the neck. Doesn't impede breathing.";
+				break;
 			case 2:
-				text = "NPCs may try to <span class='purple inline-colour'>choke</span> you during consensual intercourse."; break;
+				text = "NPCs may try to <span class='purple inline-colour'>choke</span> you during consensual intercourse.";
+				break;
 			case 3:
-				text = "NPCs may try to <span class='red inline-colour'>strangle</span> you during non-consensual intercourse."; break;
+				text = "NPCs may try to <span class='red inline-colour'>strangle</span> you during non-consensual intercourse.";
+				break;
 			case 4:
-				text = "NPCs will <span class='red inline-colour'>often</span> try to <span class='red inline-colour'>strangle</span> you during non-consensual intercourse."; break;
-
+				text = "NPCs will <span class='red inline-colour'>often</span> try to <span class='red inline-colour'>strangle</span> you during non-consensual intercourse.";
+				break;
 			default:
 				text = "Error: bad value: " + val;
 				val = 0;
 		}
-		jQuery('#numberslider-value-asphyxialvl').text('').append(text).addClass('small-description');
+		jQuery("#numberslider-value-asphyxialvl").text("").append(text).addClass("small-description");
 	};
 
-	jQuery(document).ready(() => {
+	$(() => {
 		updateText();
-		jQuery('#numberslider-input-asphyxialvl').on('input change', function (e) { updateText(); });
+		$("#numberslider-input-asphyxialvl").on("input change", function (e) {
+			updateText();
+		});
 	});
 }
+window.settingsAsphyxiation = settingsAsphyxiation;
 
-window.settingsNudeGenderAppearance = function () {
-	let updateText = () => {
+function settingsNudeGenderAppearance() {
+	const updateText = () => {
 		let val = V.NudeGenderDC;
 		let text = null;
 		switch (val) {
 			case 0:
-				text = "NPCs will <span class='blue inline-colour'>ignore</span> your genitals when perceiving your gender."; break;
+				text = "NPCs will <span class='blue inline-colour'>ignore</span> your genitals when perceiving your gender.";
+				break;
 			case 1:
-				text = "NPCs will <span class='purple inline-colour'>consider</span> your genitals when perceiving your gender."; break;
+				text = "NPCs will <span class='purple inline-colour'>consider</span> your genitals when perceiving your gender.";
+				break;
 			case 2:
-				text = "NPCs will <span class='red inline-colour'>judge</span> your gender based on your genitals."; break;
-
+				text = "NPCs will <span class='red inline-colour'>judge</span> your gender based on your genitals.";
+				break;
 			default:
 				text = "Error: bad value: " + val;
 				val = 0;
 		}
-		jQuery('#numberslider-value-nudegenderdc').text('').append(text).addClass('small-description')
-		                                          .css('margin-left', '1em');
+		$("#numberslider-value-nudegenderdc").text("").append(text).addClass("small-description").css("margin-left", "1em");
 	};
 
-	jQuery(document).ready(() => {
+	$(() => {
 		updateText();
-		jQuery('#numberslider-input-nudegenderdc').on('input change', function (e) { updateText(); })
-		                                          .css('width', '100%');
+		jQuery("#numberslider-input-nudegenderdc")
+			.on("input change", function (e) {
+				updateText();
+			})
+			.css("width", "100%");
 	});
 }
+window.settingsNudeGenderAppearance = settingsNudeGenderAppearance;
 
-window.settingsBodywriting = function () {
-	let updateText = () => {
+function settingsBodywriting() {
+	const updateText = () => {
 		let val = V.bodywritingLvl;
 		let text = null;
 		switch (val) {
 			case 0:
-				text = "NPCs may <span class='green inline-colour'>not</span> write on you."; break;
+				text = "NPCs may <span class='green inline-colour'>not</span> write on you.";
+				break;
 			case 1:
-				text = "NPCs may <span class='blue inline-colour'>ask</span> to write on you."; break;
+				text = "NPCs may <span class='blue inline-colour'>ask</span> to write on you.";
+				break;
 			case 2:
-				text = "NPCs may <span class='purple inline-colour'>forcibly</span> write on you."; break;
+				text = "NPCs may <span class='purple inline-colour'>forcibly</span> write on you.";
+				break;
 			case 3:
-				text = "NPCs may <span class='red inline-colour'>forcibly</span> write on and <span class='red inline-colour'>tattoo</span> you."; break;
+				text = "NPCs may <span class='red inline-colour'>forcibly</span> write on and <span class='red inline-colour'>tattoo</span> you.";
+				break;
 			default:
 				text = "Error: bad value: " + val;
 				val = 0;
 		}
 		// delete the below code when $bodywritingdisable is fully replaced by $bodywritingLvl
 		V.bodywritingdisable = "f";
-		if (val == 0) V.bodywritingdisable = "t";
+		if (val === 0) V.bodywritingdisable = "t";
 
-		jQuery('#numberslider-value-bodywritinglvl').text('').append(text).addClass('small-description');
+		$("#numberslider-value-bodywritinglvl").text("").append(text).addClass("small-description");
 	};
 
-	jQuery(document).ready(() => {
+	$(() => {
 		updateText();
-		jQuery('#numberslider-input-bodywritinglvl').on('input change', function (e) { updateText(); });
+		$("#numberslider-input-bodywritinglvl").on("input change", function (e) {
+			updateText();
+		});
 	});
 }
+window.settingsBodywriting = settingsBodywriting;
 
-window.settingsNamedNpcBreastSize = function (id, persist) {
-	const breastSizes = ["nipple","budding","tiny","small","pert","modest","full","large","ample","massive","huge","gigantic","enormous"];
+function settingsNamedNpcBreastSize(id, persist) {
+	const breastSizes = ["nipple", "budding", "tiny", "small", "pert", "modest", "full", "large", "ample", "massive", "huge", "gigantic", "enormous"];
 
-	let updateText = () => {
+	const updateText = () => {
 		const npc = persist ? V.per_npc[T.pNPCId] : V.NPCName[T.npcId];
 		const val = npc.breastsize;
 
@@ -420,67 +401,135 @@ window.settingsNamedNpcBreastSize = function (id, persist) {
 			npc.breastsdesc = text + "s";
 		}
 
-		jQuery('#numberslider-value-' + id).text(npc.breastsdesc);
+		$("#numberslider-value-" + id).text(npc.breastsdesc);
 	};
 
-	jQuery(document).ready(() => {
+	$(() => {
 		updateText();
-		jQuery('#numberslider-input-' + id).on('input change', function (e) { updateText(); });
+		$("#numberslider-input-" + id).on("input change", function (e) {
+			updateText();
+		});
 	});
 }
+window.settingsNamedNpcBreastSize = settingsNamedNpcBreastSize;
 
 // Checks current settings page for data attributes
 // Run only when settings tab is changed (probably in "displaySettings" widget)
-//data-target is the target element that needs to be clicked for the value to be updated
-//data-disabledif is the conditional statement (e.g. data-disabledif="V.per_npc[T.pNPCId].gender==='f'")
-//Conditional statement uses V and T instead of $ and _
-
-window.settingsDisableElement = function() {
-	$(document).ready(() => {
-		$("[data-target]").each(function(){
-			let updateButtonsActive = () => {
-				$(document).ready(() => {
-					try{
-						let cond = eval(disabledif);
-						let style = cond ? "var(--500)" : "";
+// data-target is the target element that needs to be clicked for the value to be updated
+// data-disabledif is the conditional statement (e.g. data-disabledif="V.per_npc[T.pNPCId].gender==='f'")
+// Conditional statement uses V and T instead of $ and _
+
+function settingsDisableElement() {
+	$(() => {
+		$("[data-target]").each(function () {
+			const updateButtonsActive = () => {
+				$(() => {
+					try {
+						const evalStr = "'use strict'; return " + disabledif;
+						// eslint-disable-next-line no-new-func
+						const cond = Function(evalStr)();
+						const style = cond ? "var(--500)" : "";
 						orig.css("color", style).children().css("color", style);
 						orig.find("input").prop("disabled", cond);
+					} catch (e) {
+						console.log(e);
 					}
-					catch(e){ console.log(e); }
 				});
 			};
-			let orig = $(this);
-			let target = orig.data("target");
-			let disabledif = orig.data("disabledif");
-			if(orig.data("target") && disabledif){
+			const orig = $(this);
+			const target = orig.data("target");
+			const disabledif = orig.data("disabledif");
+			if (orig.data("target") && disabledif) {
 				updateButtonsActive();
-				$(document).on("click.evt", "[name*='" + (Array.isArray(target) ? target.map(x => Util.slugify(x)).join("'], [name*='") : Util.slugify(target)) + "']", function(){ updateButtonsActive(); });
+				$(document).on(
+					"click.evt",
+					"[name*='" + (Array.isArray(target) ? target.map(x => Util.slugify(x)).join("'], [name*='") : Util.slugify(target)) + "']",
+					function () {
+						updateButtonsActive();
+					}
+				);
 			}
 		});
 	});
 }
-
-/* Adds event listeners to input on current page */
-window.onInputChanged = function(func) {
-	if (!func || (typeof func !== "function")) return;
-	$(document).ready(() => {
-		$("input").on("change", function() { func(); });
+window.settingsDisableElement = settingsDisableElement;
+
+// Adds event listeners to input on current page
+// mainly used for options overlay
+function onInputChanged(func) {
+	if (!func || typeof func !== "function") return;
+	$(() => {
+		$("input").on("change", function () {
+			func();
+		});
 	});
 }
+window.onInputChanged = onInputChanged;
 
-window.closeOverlay = function() {
+function closeOverlay() {
 	updateOptions();
 	V.currentOverlay = null;
 	T.buttons.reset();
 	$("#customOverlay").addClass("hidden").parent().addClass("hidden");
 }
+window.closeOverlay = closeOverlay;
 
-window.updateOptions = function() {
-	if(V.currentOverlay === "options" && T.optionsRefresh && V.passage != 'Start'){
+function updatehistorycontrols() {
+	if (V.options.maxStates === undefined || V.options.maxStates > 20) {
+		/* initiate new variable based on engine config and limit it to 20 */
+		V.options.maxStates = Math.clamp(1, 20, Config.history.maxStates);
+	}
+	if (V.options.maxStates === 1) {
+		/* when disabled, irreversibly delete history controls the way sugarcube intended */
+		Config.history.maxStates = 1;
+		jQuery("#ui-bar-history").remove();
+	} else {
+		/* set actual maxStates in accordance with our new variable */
+		Config.history.maxStates = V.options.maxStates;
+		/* ensure that controls are enabled so sugarcube won't destroy them on reload */
+		Config.history.controls = true;
+		/* if irreversibly deleted, restore #ui-bar-history from oblivion and pop it after #ui-bar-toggle */
+		if (jQuery("#ui-bar-history").length === 0) {
+			jQuery("#ui-bar-toggle").after(`
+				<div id="ui-bar-history">
+					<button id="history-backward" tabindex="0" title="'+t+'" aria-label="'+t+'">\uE821</button>
+					<button id="history-forward" tabindex="0" title="'+n+'" aria-label="'+n+'">\uE822</button>
+				</div>`);
+			/* make buttons active/inactive based on the available history states */
+			jQuery(document).on(
+				":historyupdate.ui-bar",
+				(($backward, $forward) => () => {
+					$backward.ariaDisabled(State.length < 2);
+					$forward.ariaDisabled(State.length === State.size);
+				})(jQuery("#history-backward"), jQuery("#history-forward"))
+			);
+			jQuery("#history-backward")
+				.ariaDisabled(State.length < 2)
+				.ariaClick({
+						label: L10n.get("uiBarBackward"),
+					},
+					() => Engine.backward()
+				);
+			jQuery("#history-forward")
+				.ariaDisabled(State.length === State.size)
+				.ariaClick({
+						label: L10n.get("uiBarForward"),
+					},
+					() => Engine.forward()
+				);
+		}
+		jQuery("#ui-bar-history").show();
+	}
+}
+window.updatehistorycontrols = updatehistorycontrols;
+DefineMacro("updatehistorycontrols", updatehistorycontrols);
+
+function updateOptions() {
+	if (V.currentOverlay === "options" && T.optionsRefresh && V.passage !== "Start") {
 		updatehistorycontrols();
-		let optionsData = clone(V.options);
-		let tmpButtons = T.buttons;
-		let tmpKey = T.key;
+		const optionsData = clone(V.options);
+		const tmpButtons = T.buttons;
+		const tmpKey = T.key;
 
 		State.restore();
 		V.options = optionsData;
@@ -489,30 +538,17 @@ window.updateOptions = function() {
 		T.key = tmpKey;
 		T.buttons = tmpButtons;
 		T.buttons.setupTabs();
-		if(T.key !== "options") {
-			T.buttons.setActive(T.buttons.activeTab);	
+		if (T.key !== "options") {
+			T.buttons.setActive(T.buttons.activeTab);
 		}
 	}
 }
+window.updateOptions = updateOptions;
 
-$(document).on('click', '#cbtToggleMenu .cbtToggle', function (e) {
-	$('#cbtToggleMenu').toggleClass('visible');
+$(document).on("click", "#cbtToggleMenu .cbtToggle", function (e) {
+	$("#cbtToggleMenu").toggleClass("visible");
 });
 
-function sliderPerc(e){
-	let valSpan = $(e.currentTarget).siblings().first();
-	let value = valSpan.text();
-
-	valSpan.text((i, value) => Math.round(value * 100) + '%');
-
-	if (value > 1)
-		valSpan.css('color', 'gold');
-	else if (value < 1)
-		valSpan.css('color', 'green');
-	else
-		valSpan.css('color', 'unset');
-}
-
 function elementExists(selector) {
 	return document.querySelector(selector) !== null;
 }
diff --git a/game/03-JavaScript/base-clothing.js b/game/03-JavaScript/base-clothing.js
index 83d8d6ff49..1f41706e6d 100644
--- a/game/03-JavaScript/base-clothing.js
+++ b/game/03-JavaScript/base-clothing.js
@@ -1,115 +1,125 @@
 function colourContainerClasses() {
-	return 'hair-' + (V.haircolour || '').replace(/ /g, '-') +
-		' ' + 'upper-' + (V.upperwet > 100 ? 'wet' : '') + (V.worn.upper.colour_combat || V.worn.upper.colour || '').replace(/ /g, '-') +
-		' ' + 'lower-' + (V.lowerwet > 100 ? 'wet' : '') + (V.worn.lower.colour_combat || V.worn.lower.colour || '').replace(/ /g, '-') +
-		' ' + 'under_lower-' + (V.underlowerwet > 100 ? 'wet' : '') + (V.worn.under_lower.colour || '').replace(/ /g, '-') +
-		' ' + 'under_upper-' + (V.underupperwet > 100 ? 'wet' : '') + (V.worn.under_upper.colour || '').replace(/ /g, '-') +
-		' ' + 'head-' + (V.worn.head.colour_combat || V.worn.head.colour || '').replace(/ /g, '-') +
-		' ' + 'face-' + (V.worn.face.colour_combat || V.worn.face.colour || '').replace(/ /g, '-') +
-		' ' + 'neck-' + (V.worn.neck.colour_combat || V.worn.neck.colour || '').replace(/ /g, '-') +
-		' ' + 'hands-' + (V.worn.hands.colour_combat || V.worn.hands.colour || '').replace(/ /g, '-') +
-		' ' + 'legs-' + (V.worn.legs.colour_combat || V.worn.legs.colour || '').replace(/ /g, '-') +
-		' ' + 'feet-' + (V.worn.feet.colour_combat || V.worn.feet.colour || '').replace(/ /g, '-') +
-		' ' + 'upper_acc-' + (V.worn.upper.accessory_colour_combat || V.worn.upper.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'lower_acc-' + (V.worn.lower.accessory_colour_combat || V.worn.lower.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'under_lower_acc-' + (V.worn.under_lower.accessory_colour_combat || V.worn.under_lower.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'under_upper_acc-' + (V.worn.under_upper.accessory_colour_combat || V.worn.under_upper.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'head_acc-' + (V.worn.head.accessory_colour_combat || V.worn.head.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'face_acc-' + (V.worn.face.accessory_colour_combat || V.worn.face.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'neck_acc-' + (V.worn.neck.accessory_colour_combat || V.worn.neck.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'hands_acc-' + (V.worn.hands.accessory_colour_combat || V.worn.hands.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'legs_acc-' + (V.worn.legs.accessory_colour_combat || V.worn.legs.accessory_colour || '').replace(/ /g, '-') +
-		' ' + 'feet_acc-' + (V.worn.feet.accessory_colour_combat || V.worn.feet.accessory_colour || '').replace(/ /g, '-')
+	return "hair-" + (V.haircolour || "").replace(/ /g, "-") +
+		" " + "upper-" + (V.upperwet > 100 ? "wet" : "") + (V.worn.upper.colour_combat || V.worn.upper.colour || "").replace(/ /g, "-") +
+		" " + "lower-" + (V.lowerwet > 100 ? "wet" : "") + (V.worn.lower.colour_combat || V.worn.lower.colour || "").replace(/ /g, "-") +
+		" " + "under_lower-" + (V.underlowerwet > 100 ? "wet" : "") + (V.worn.under_lower.colour || "").replace(/ /g, "-") +
+		" " + "under_upper-" + (V.underupperwet > 100 ? "wet" : "") + (V.worn.under_upper.colour || "").replace(/ /g, "-") +
+		" " + "head-" + (V.worn.head.colour_combat || V.worn.head.colour || "").replace(/ /g, "-") +
+		" " + "face-" + (V.worn.face.colour_combat || V.worn.face.colour || "").replace(/ /g, "-") +
+		" " + "neck-" + (V.worn.neck.colour_combat || V.worn.neck.colour || "").replace(/ /g, "-") +
+		" " + "hands-" + (V.worn.hands.colour_combat || V.worn.hands.colour || "").replace(/ /g, "-") +
+		" " + "legs-" + (V.worn.legs.colour_combat || V.worn.legs.colour || "").replace(/ /g, "-") +
+		" " + "feet-" + (V.worn.feet.colour_combat || V.worn.feet.colour || "").replace(/ /g, "-") +
+		" " + "upper_acc-" + (V.worn.upper.accessory_colour_combat || V.worn.upper.accessory_colour || "").replace(/ /g, "-") +
+		" " + "lower_acc-" + (V.worn.lower.accessory_colour_combat || V.worn.lower.accessory_colour || "").replace(/ /g, "-") +
+		" " + "under_lower_acc-" + (V.worn.under_lower.accessory_colour_combat || V.worn.under_lower.accessory_colour || "").replace(/ /g, "-") +
+		" " + "under_upper_acc-" + (V.worn.under_upper.accessory_colour_combat || V.worn.under_upper.accessory_colour || "").replace(/ /g, "-") +
+		" " + "head_acc-" + (V.worn.head.accessory_colour_combat || V.worn.head.accessory_colour || "").replace(/ /g, "-") +
+		" " + "face_acc-" + (V.worn.face.accessory_colour_combat || V.worn.face.accessory_colour || "").replace(/ /g, "-") +
+		" " + "neck_acc-" + (V.worn.neck.accessory_colour_combat || V.worn.neck.accessory_colour || "").replace(/ /g, "-") +
+		" " + "hands_acc-" + (V.worn.hands.accessory_colour_combat || V.worn.hands.accessory_colour || "").replace(/ /g, "-") +
+		" " + "legs_acc-" + (V.worn.legs.accessory_colour_combat || V.worn.legs.accessory_colour || "").replace(/ /g, "-") +
+		" " + "feet_acc-" + (V.worn.feet.accessory_colour_combat || V.worn.feet.accessory_colour || "").replace(/ /g, "-")
 }
 window.colourContainerClasses = colourContainerClasses; // export function
 
 function limitedColourContainerClasses() {
-	return 'hair-' + (V.haircolour || '').replace(/ /g, '-')
+	return "hair-" + (V.haircolour || "").replace(/ /g, "-");
 }
 window.limitedColourContainerClasses = limitedColourContainerClasses; // export function
 
 function debugColourContainerClasses(color) {
-	return 'hair-' + (color.hair || '').replace(/ /g, '-') +
-		' ' + 'upper-' + (color.upper[0] || '').replace(/ /g, '-') +
-		' ' + 'lower-' + (color.lower[0] || '').replace(/ /g, '-') +
-		' ' + 'under_lower-' + (color.under_lower[0] || '').replace(/ /g, '-') +
-		' ' + 'under_upper-' + (color.under_upper[0] || '').replace(/ /g, '-') +
-		' ' + 'head-' + (color.head[0] || '').replace(/ /g, '-') +
-		' ' + 'face-' + (color.face[0] || '').replace(/ /g, '-') +
-		' ' + 'neck-' + (color.neck[0] || '').replace(/ /g, '-') +
-		' ' + 'hands-' + (color.hands[0] || '').replace(/ /g, '-') +
-		' ' + 'legs-' + (color.legs[0] || '').replace(/ /g, '-') +
-		' ' + 'feet-' + (color.feet[0] || '').replace(/ /g, '-') +
-		' ' + 'upper_acc-' + (color.upper[1] || '').replace(/ /g, '-') +
-		' ' + 'lower_acc-' + (color.lower[1] || '').replace(/ /g, '-') +
-		' ' + 'under_lower_acc-' + (color.under_lower[1] || '').replace(/ /g, '-') +
-		' ' + 'under_upper_acc-' + (color.under_upper[1] || '').replace(/ /g, '-') +
-		' ' + 'head_acc-' + (color.head[1] || '').replace(/ /g, '-') +
-		' ' + 'face_acc-' + (color.face[1] || '').replace(/ /g, '-') +
-		' ' + 'neck_acc-' + (color.neck[1] || '').replace(/ /g, '-') +
-		' ' + 'hands_acc-' + (color.hands[1] || '').replace(/ /g, '-') +
-		' ' + 'legs_acc-' + (color.legs[1] || '').replace(/ /g, '-') +
-		' ' + 'feet_acc-' + (color.feet[1] || '').replace(/ /g, '-')
+	return "hair-" + (color.hair || "").replace(/ /g, "-") +
+		" " + "upper-" + (color.upper[0] || "").replace(/ /g, "-") +
+		" " + "lower-" + (color.lower[0] || "").replace(/ /g, "-") +
+		" " + "under_lower-" + (color.under_lower[0] || "").replace(/ /g, "-") +
+		" " + "under_upper-" + (color.under_upper[0] || "").replace(/ /g, "-") +
+		" " + "head-" + (color.head[0] || "").replace(/ /g, "-") +
+		" " + "face-" + (color.face[0] || "").replace(/ /g, "-") +
+		" " + "neck-" + (color.neck[0] || "").replace(/ /g, "-") +
+		" " + "hands-" + (color.hands[0] || "").replace(/ /g, "-") +
+		" " + "legs-" + (color.legs[0] || "").replace(/ /g, "-") +
+		" " + "feet-" + (color.feet[0] || "").replace(/ /g, "-") +
+		" " + "upper_acc-" + (color.upper[1] || "").replace(/ /g, "-") +
+		" " + "lower_acc-" + (color.lower[1] || "").replace(/ /g, "-") +
+		" " + "under_lower_acc-" + (color.under_lower[1] || "").replace(/ /g, "-") +
+		" " + "under_upper_acc-" + (color.under_upper[1] || "").replace(/ /g, "-") +
+		" " + "head_acc-" + (color.head[1] || "").replace(/ /g, "-") +
+		" " + "face_acc-" + (color.face[1] || "").replace(/ /g, "-") +
+		" " + "neck_acc-" + (color.neck[1] || "").replace(/ /g, "-") +
+		" " + "hands_acc-" + (color.hands[1] || "").replace(/ /g, "-") +
+		" " + "legs_acc-" + (color.legs[1] || "").replace(/ /g, "-") +
+		" " + "feet_acc-" + (color.feet[1] || "").replace(/ /g, "-")
 }
 window.debugColourContainerClasses = debugColourContainerClasses; // export function
 
-window.getClothingCost = function (item, slot) {
+function getClothingCost(item, slot) {
 	let cost = setup.clothes[slot][clothesIndex(slot, item)].cost * V.clothesPrice;
 
-	if (setup.clothes.under_lower.findIndex(x => x.name == item.name && x.modder === item.modder) >= 0 || setup.clothes.under_upper.findIndex(x => x.name == item.name && x.modder === item.modder) >= 0)
+	if (
+		setup.clothes.under_lower.findIndex(x => x.name === item.name && x.modder === item.modder) >= 0 ||
+		setup.clothes.under_upper.findIndex(x => x.name === item.name && x.modder === item.modder) >= 0
+	)
 		cost *= V.clothesPriceUnderwear;
-	else if (item.type.includes('school'))
-		cost *= V.clothesPriceSchool;
+	else if (item.type.includes("school")) cost *= V.clothesPriceSchool;
 
 	// the lewder item is, the more affected by the multiplier it is
-	let lewdness = Math.clamp((item.reveal - 400) / 500, 0, 1);
-	let lewdCoef = 1 + (V.clothesPriceLewd - 1) * lewdness;
+	const lewdness = Math.clamp((item.reveal - 400) / 500, 0, 1);
+	const lewdCoef = 1 + (V.clothesPriceLewd - 1) * lewdness;
 	cost *= lewdCoef;
 
-	if (V.passage === "School Library Shop"){
-		cost *= 1.4 + (((V.delinquency - 500) / 5000) + ((V.NPCName[V.NPCNameList.indexOf("Sydney")].love - 50) / -500))
+	if (V.passage === "School Library Shop") {
+		cost *= 1.4 + ((V.delinquency - 500) / 5000 + (V.NPCName[V.NPCNameList.indexOf("Sydney")].love - 50) / -500);
 	}
 
 	return Math.round(cost);
 }
+window.getClothingCost = getClothingCost;
 
 // makes all existing specified upper/lower clothes to be over_upper/over_lower
 // it assumes that over_xxx equipment slots are empty, otherwise it will overwrite anything in those slots
 // use this function in version update widget when over clothes will be ready
-window.convertNormalToOver = function () {
-	let clothesToConvert = ['bathrobe', 'bathrobe bottom', 'peacoat', 'shadbelly coat', 'puffer jacket', 'brown leather jacket', 'black leather jacket', 'vampire jacket'];
+function convertNormalToOver() {
+	const clothesToConvert = [
+		"bathrobe",
+		"bathrobe bottom",
+		"peacoat",
+		"shadbelly coat",
+		"puffer jacket",
+		"brown leather jacket",
+		"black leather jacket",
+		"vampire jacket",
+	];
 
 	// function that converts a clothing item
-	let convertItem = (item) => {
-		console.log('converting ' + item.name);
+	const convertItem = item => {
+		console.log("converting " + item.name);
 
 		if (item.outfitPrimary) {
 			Object.keys(item.outfitPrimary).forEach(slot => {
-				if (slot == 'upper' || slot == 'lower') {
-					item.outfitPrimary['over_' + slot] = item.outfitPrimary[slot];
+				if (slot === "upper" || slot === "lower") {
+					item.outfitPrimary["over_" + slot] = item.outfitPrimary[slot];
 					delete item.outfitPrimary[slot];
 				}
 			});
-		}
-		else if (item.outfitSecondary) {
+		} else if (item.outfitSecondary) {
 			for (let i = 0; i < item.outfitSecondary.length; i += 2) {
-				if (item.outfitSecondary[i] == 'upper' || item.outfitSecondary[i] == 'lower') {
-					item.outfitSecondary[i] = 'over_' + item.outfitSecondary[i];
+				if (item.outfitSecondary[i] === "upper" || item.outfitSecondary[i] === "lower") {
+					item.outfitSecondary[i] = "over_" + item.outfitSecondary[i];
 				}
 			}
 		}
-		if (item.set == 'upper' || item.set == 'lower')
-			item.set = 'over_' + item.set;
+		if (item.set === "upper" || item.set === "lower") item.set = "over_" + item.set;
 
 		return item;
 	};
 
-	for (let index in clothesToConvert) {
-		let itemName = clothesToConvert[index];
+	for (const index in clothesToConvert) {
+		const itemName = clothesToConvert[index];
 
 		// convert clothing sets
 		V.outfit.forEach(outf => {
-			if (outf.upper == itemName) {
+			if (outf.upper === itemName) {
 				outf.upper = "naked";
 				outf.over_upper = itemName;
 				if (outf.colors) {
@@ -117,7 +127,7 @@ window.convertNormalToOver = function () {
 					outf.colors.upper = [0, 0];
 				}
 			}
-			if (outf.lower == itemName) {
+			if (outf.lower === itemName) {
 				outf.lower = "naked";
 				outf.over_lower = itemName;
 				if (outf.colors) {
@@ -129,70 +139,71 @@ window.convertNormalToOver = function () {
 
 		// convert clothes in wardrobe
 		for (let i = V.wardrobe.upper.length - 1; i >= 0; i--) {
-			if (V.wardrobe.upper[i].name == itemName) {
+			if (V.wardrobe.upper[i].name === itemName) {
 				V.wardrobe.over_upper.push(convertItem(V.wardrobe.upper[i]));
 				V.wardrobe.upper.splice(i, 1);
 			}
 		}
 		for (let i = V.wardrobe.lower.length - 1; i >= 0; i--) {
-			if (V.wardrobe.lower[i].name == itemName) {
+			if (V.wardrobe.lower[i].name === itemName) {
 				V.wardrobe.over_lower.push(convertItem(V.wardrobe.lower[i]));
 				V.wardrobe.lower.splice(i, 1);
 			}
 		}
 
 		// convert worn clothes
-		if (V.worn.upper.name == itemName) {
+		if (V.worn.upper.name === itemName) {
 			V.worn.over_upper = convertItem(V.worn.upper);
 			V.worn.upper = clone(setup.clothes.upper[0]);
 		}
-		if (V.worn.lower.name == itemName) {
+		if (V.worn.lower.name === itemName) {
 			V.worn.over_lower = convertItem(V.worn.lower);
 			V.worn.lower = clone(setup.clothes.lower[0]);
 		}
 
 		// convert carried clothes
-		if (V.carried.upper.name == itemName) {
+		if (V.carried.upper.name === itemName) {
 			V.carried.over_upper = convertItem(V.carried.upper);
 			V.carried.upper = clone(setup.clothes.upper[0]);
 		}
-		if (V.carried.lower.name == itemName) {
+		if (V.carried.lower.name === itemName) {
 			V.carried.over_lower = convertItem(V.carried.lower);
 			V.carried.lower = clone(setup.clothes.lower[0]);
 		}
 
 		// convert stripped stored clothes
-		for (let i = V.store.upper.length - 1; i>= 0; i--) {
-			if (V.store.upper[i].name == itemName) {
+		for (let i = V.store.upper.length - 1; i >= 0; i--) {
+			if (V.store.upper[i].name === itemName) {
 				V.store.over_upper.push(convertItem(V.store.upper[i]));
 				V.store.upper.splice(i, 1);
 			}
 		}
-		for (let i = V.store.lower.length - 1; i>= 0; i--) {
-			if (V.store.lower[i].name == itemName) {
+		for (let i = V.store.lower.length - 1; i >= 0; i--) {
+			if (V.store.lower[i].name === itemName) {
 				V.store.over_lower.push(convertItem(V.store.lower[i]));
 				V.store.lower.splice(i, 1);
 			}
 		}
 
 		// convert try on stored
-		if (V.tryOn.ownedStored.upper.name == itemName) {
+		if (V.tryOn.ownedStored.upper.name === itemName) {
 			V.tryOn.ownedStored.over_upper = convertItem(V.tryOn.ownedStored.upper);
 			V.tryOn.ownedStored.upper = clone(setup.clothes.upper[0]);
 		}
-		if (V.tryOn.ownedStored.lower.name == itemName) {
+		if (V.tryOn.ownedStored.lower.name === itemName) {
 			V.tryOn.ownedStored.over_lower = convertItem(V.tryOn.ownedStored.lower);
 			V.tryOn.ownedStored.lower = clone(setup.clothes.lower[0]);
 		}
 
 		// convert try on equipped
-		if (V.tryOn.tryingOn.upper && V.tryOn.tryingOn.upper.name == itemName) {
+		if (V.tryOn.tryingOn.upper && V.tryOn.tryingOn.upper.name === itemName) {
 			V.tryOn.tryingOn.over_upper = convertItem(V.tryOn.tryingOn.upper);
 			V.tryOn.tryingOn.upper = null;
 		}
-		if (V.tryOn.tryingOn.lower && V.tryOn.tryingOn.lower.name == itemName) {
+		if (V.tryOn.tryingOn.lower && V.tryOn.tryingOn.lower.name === itemName) {
 			V.tryOn.tryingOn.over_lower = convertItem(V.tryOn.tryingOn.lower);
 			V.tryOn.tryingOn.lower = null;
 		}
 	}
 }
+window.convertNormalToOver = convertNormalToOver;
diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index 8de8c2225b..c25dc2d24c 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -1,81 +1,36 @@
-window.statsConsole = function () {
-	console.log("PenisGrowthTimer", SugarCube.State.variables.penisgrowthtimer);
-	console.log("BreastGrowthTimer", SugarCube.State.variables.breastgrowthtimer);
-
-}
-
-jQuery(document).ready(function () {
-	jQuery('#sidetooltip').appendTo("body");
-});
-
-(function (window, define, exports) {
-
-	/* mousetrap v1.6.2 craig.is/killing/mice */
-	(function (p, t, h) {
-		function u(a, b, d) { a.addEventListener ? a.addEventListener(b, d, !1) : a.attachEvent("on" + b, d) } function y(a) { if ("keypress" == a.type) { var b = String.fromCharCode(a.which); a.shiftKey || (b = b.toLowerCase()); return b } return m[a.which] ? m[a.which] : q[a.which] ? q[a.which] : String.fromCharCode(a.which).toLowerCase() } function E(a) { var b = []; a.shiftKey && b.push("shift"); a.altKey && b.push("alt"); a.ctrlKey && b.push("ctrl"); a.metaKey && b.push("meta"); return b } function v(a) {
-			return "shift" == a || "ctrl" == a || "alt" == a ||
-				"meta" == a
-		} function z(a, b) { var d, e = []; var c = a; "+" === c ? c = ["+"] : (c = c.replace(/\+{2}/g, "+plus"), c = c.split("+")); for (d = 0; d < c.length; ++d) { var k = c[d]; A[k] && (k = A[k]); b && "keypress" != b && B[k] && (k = B[k], e.push("shift")); v(k) && e.push(k) } c = k; d = b; if (!d) { if (!n) { n = {}; for (var h in m) 95 < h && 112 > h || m.hasOwnProperty(h) && (n[m[h]] = h) } d = n[c] ? "keydown" : "keypress" } "keypress" == d && e.length && (d = "keydown"); return { key: k, modifiers: e, action: d } } function C(a, b) { return null === a || a === t ? !1 : a === b ? !0 : C(a.parentNode, b) } function e(a) {
-			function b(a) {
-				a =
-					a || {}; var b = !1, l; for (l in n) a[l] ? b = !0 : n[l] = 0; b || (w = !1)
-			} function d(a, b, r, g, F, e) { var l, D = [], h = r.type; if (!f._callbacks[a]) return []; "keyup" == h && v(a) && (b = [a]); for (l = 0; l < f._callbacks[a].length; ++l) { var d = f._callbacks[a][l]; if ((g || !d.seq || n[d.seq] == d.level) && h == d.action) { var c; (c = "keypress" == h && !r.metaKey && !r.ctrlKey) || (c = d.modifiers, c = b.sort().join(",") === c.sort().join(",")); c && (c = g && d.seq == g && d.level == e, (!g && d.combo == F || c) && f._callbacks[a].splice(l, 1), D.push(d)) } } return D } function h(a, b, d, g) {
-				f.stopCallback(b,
-					b.target || b.srcElement, d, g) || !1 !== a(b, d) || (b.preventDefault ? b.preventDefault() : b.returnValue = !1, b.stopPropagation ? b.stopPropagation() : b.cancelBubble = !0)
-			} function c(a) { "number" !== typeof a.which && (a.which = a.keyCode); var b = y(a); b && ("keyup" == a.type && x === b ? x = !1 : f.handleKey(b, E(a), a)) } function k(a, d, r, g) {
-				function l(d) { return function () { w = d; ++n[a]; clearTimeout(p); p = setTimeout(b, 1E3) } } function e(d) { h(r, d, a); "keyup" !== g && (x = y(d)); setTimeout(b, 10) } for (var c = n[a] = 0; c < d.length; ++c) {
-					var f = c + 1 === d.length ? e : l(g ||
-						z(d[c + 1]).action); m(d[c], f, g, a, c)
-				}
-			} function m(a, b, c, g, e) { f._directMap[a + ":" + c] = b; a = a.replace(/\s+/g, " "); var h = a.split(" "); 1 < h.length ? k(a, h, b, c) : (c = z(a, c), f._callbacks[c.key] = f._callbacks[c.key] || [], d(c.key, c.modifiers, { type: c.action }, g, a, e), f._callbacks[c.key][g ? "unshift" : "push"]({ callback: b, modifiers: c.modifiers, action: c.action, seq: g, level: e, combo: a })) } var f = this; a = a || t; if (!(f instanceof e)) return new e(a); f.target = a; f._callbacks = {}; f._directMap = {}; var n = {}, p, x = !1, q = !1, w = !1; f._handleKey = function (a,
-				c, e) { var g = d(a, c, e), f; c = {}; var l = 0, k = !1; for (f = 0; f < g.length; ++f)g[f].seq && (l = Math.max(l, g[f].level)); for (f = 0; f < g.length; ++f)g[f].seq ? g[f].level == l && (k = !0, c[g[f].seq] = 1, h(g[f].callback, e, g[f].combo, g[f].seq)) : k || h(g[f].callback, e, g[f].combo); g = "keypress" == e.type && q; e.type != w || v(a) || g || b(c); q = k && "keydown" == e.type }; f._bindMultiple = function (a, b, c) { for (var d = 0; d < a.length; ++d)m(a[d], b, c) }; u(a, "keypress", c); u(a, "keydown", c); u(a, "keyup", c)
-		} if (p) {
-			var m = {
-				8: "backspace", 9: "tab", 13: "enter", 16: "shift", 17: "ctrl",
-				18: "alt", 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", 37: "left", 38: "up", 39: "right", 40: "down", 45: "ins", 46: "del", 91: "meta", 93: "meta", 224: "meta"
-			}, q = { 106: "*", 107: "+", 109: "-", 110: ".", 111: "/", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'" }, B = { "~": "`", "!": "1", "@": "2", "#": "3", $: "4", "%": "5", "^": "6", "&": "7", "*": "8", "(": "9", ")": "0", _: "-", "+": "=", ":": ";", '"': "'", "<": ",", ">": ".", "?": "/", "|": "\\" }, A = {
-				option: "alt", command: "meta", "return": "enter",
-				escape: "esc", plus: "+", mod: /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? "meta" : "ctrl"
-			}, n; for (h = 1; 20 > h; ++h)m[111 + h] = "f" + h; for (h = 0; 9 >= h; ++h)m[h + 96] = h.toString(); e.prototype.bind = function (a, b, d) { a = a instanceof Array ? a : [a]; this._bindMultiple.call(this, a, b, d); return this }; e.prototype.unbind = function (a, b) { return this.bind.call(this, a, function () { }, b) }; e.prototype.trigger = function (a, b) { if (this._directMap[a + ":" + b]) this._directMap[a + ":" + b]({}, a); return this }; e.prototype.reset = function () {
-				this._callbacks = {};
-				this._directMap = {}; return this
-			}; e.prototype.stopCallback = function (a, b) { return -1 < (" " + b.className + " ").indexOf(" mousetrap ") || C(b, this.target) ? !1 : "INPUT" == b.tagName || "SELECT" == b.tagName || "TEXTAREA" == b.tagName || b.isContentEditable }; e.prototype.handleKey = function () { return this._handleKey.apply(this, arguments) }; e.addKeycodes = function (a) { for (var b in a) a.hasOwnProperty(b) && (m[b] = a[b]); n = null }; e.init = function () {
-				var a = e(t), b; for (b in a) "_" !== b.charAt(0) && (e[b] = function (b) {
-					return function () {
-						return a[b].apply(a,
-							arguments)
-					}
-				}(b))
-			}; e.init(); p.Mousetrap = e; "undefined" !== typeof module && module.exports && (module.exports = e); "function" === typeof define && define.amd && define(function () { return e })
-		}
-	})("undefined" !== typeof window ? window : null, "undefined" !== typeof window ? document : null);
-
-}).call(window, window);
-
+/* eslint-disable jsdoc/require-description-complete-sentence */
+// adjust mousetrap behavior, see mousetrap.js
+// eslint-disable-next-line no-undef
 Mousetrap.prototype.stopCallback = function (e, element, combo) {
 	return false;
-}
+};
 
-Mousetrap.bind(["z", "n", "enter"], function () {
+// add binds for "next" link in combat
+// eslint-disable-next-line no-undef
+Mousetrap.bind(["z", "n", "enter", "space"], function () {
 	$("#passages #next a.macro-link").trigger("click");
 });
 
+/* obsolete
+// add bind for fixing stuck animations
+// eslint-disable-next-line no-undef
 Mousetrap.bind(["f"], function () {
-	if (document.activeElement.tagName === "INPUT" && document.activeElement.type !== "radio"
-		&& document.activeElement.type !== "checkbox")
+	if (document.activeElement.tagName === "INPUT" && document.activeElement.type !== "radio" && document.activeElement.type !== "checkbox")
 		return;
 
 	fixStuckAnimations();
 });
+*/
 
-Macro.add('time', {
-	handler: function () {
-		var time = V.time;
-		var hour, daystate; // Never checked and always overwritten - no need to init with old value
+Macro.add("time", {
+	handler() {
+		let daystate; // Never checked and always overwritten - no need to init with old value
+		let time = V.time;
 		// Sanity check
 		if (time < 0) time = 0;
 		if (time >= 24 * 60) time = 23 * 59 + 59;
-		hour = Math.floor(time / 60);
+
+		const hour = Math.floor(time / 60);
 		if (hour < 6) {
 			daystate = "night";
 		} else if (hour < 9) {
@@ -89,35 +44,9 @@ Macro.add('time', {
 		}
 		V.hour = hour;
 		V.daystate = daystate;
-	}
+	},
 });
 
-window.ensureIsArray = function(x, check = false) {
-	if (check) x = ensure(x, []);
-	if (Array.isArray(x)) return x;
-	return [x];
-}
-
-window.ensure = function(x, y) {
-	/* lazy comparison to include null. */
-	return (x == undefined) ? y : x;
-}
-
-/**
- * Copies to targets keys from source that are not present there.
- * Shallow.
- * @param {object} target Object to extend
- * @param {object} source Default properties
- * @return {object} target
- */
-function assignDefaults(target, source) {
-	for (let k in source) {
-		if (!source.hasOwnProperty(k)) continue;
-		if (!(k in target)) target[k] = source[k];
-	}
-	return target;
-}
-
 /*
  * Similar to <<script>>, but preprocesses the contents, so $variables are accessible.
  * The variable "output" is also exposed (unlike <<run>>, <<set>>)
@@ -127,18 +56,17 @@ function assignDefaults(target, source) {
  *     output.textContent = $text
  * <</twinescript>>
  */
-Macro.add('twinescript', {
-	skipArgs : true,
-	tags     : null,
+Macro.add("twinescript", {
+	skipArgs: true,
+	tags: null,
 
 	handler() {
 		const output = document.createDocumentFragment();
 
 		try {
 			Scripting.evalTwineScript(this.payload[0].contents, output);
-		}
-		catch (ex) {
-			return this.error(`bad evaluation: ${typeof ex === 'object' ? ex.message : ex}`);
+		} catch (ex) {
+			return this.error(`bad evaluation: ${typeof ex === "object" ? ex.message : ex}`);
 		}
 
 		// Custom debug view setup.
@@ -149,7 +77,7 @@ Macro.add('twinescript', {
 		if (output.hasChildNodes()) {
 			this.output.appendChild(output);
 		}
-	}
+	},
 });
 
 /**
@@ -163,28 +91,24 @@ Macro.add('twinescript', {
 function rangeIterate(range, handler) {
 	let list;
 	switch (typeof range) {
-		case 'string':
+		case "string":
 			list = [];
-			for (let i = 0; i < range.length; /* empty */) {
+			for (let i = 0; i < range.length; true) {
 				const obj = Util.charAndPosAt(range, i);
 				list.push([i, obj.char]);
 				i = 1 + obj.end;
 			}
 			break;
-		case 'object':
+		case "object":
 			if (Array.isArray(range)) {
 				list = range.map((val, i) => [i, val]);
-			}
-			else if (range instanceof Set) {
+			} else if (range instanceof Set) {
 				list = Array.from(range).map((val, i) => [i, val]);
-			}
-			else if (range instanceof Map) {
+			} else if (range instanceof Map) {
 				list = Array.from(range);
-			}
-			else if (Util.toStringTag(range) === 'Object') {
+			} else if (Util.toStringTag(range) === "Object") {
 				list = Object.keys(range).map(key => [key, range[key]]);
-			}
-			else {
+			} else {
 				throw new Error(`unsupported range expression type: ${Util.toStringTag(range)}`);
 			}
 			break;
@@ -192,7 +116,7 @@ function rangeIterate(range, handler) {
 			throw new Error(`unsupported range expression type: ${typeof range}`);
 	}
 	for (let i = 0; i < list.length; i++) {
-		let entry = list[i];
+		const entry = list[i];
 		handler(entry[0], entry[1]);
 	}
 }
@@ -204,15 +128,15 @@ window.rangeIterate = rangeIterate;
 function DefineMacro(macroName, macroFunction, tags, skipArgs) {
 	Macro.add(macroName, {
 		isWidget: true,
-		tags: tags,
-		skipArgs: skipArgs,
-		handler: function () {
+		tags,
+		skipArgs,
+		handler() {
 			DOL.Perflog.logWidgetStart(macroName);
 			try {
-				var oldArgs = State.temporary.args;
+				const oldArgs = State.temporary.args;
 				State.temporary.args = this.args.slice();
 				macroFunction.apply(this, this.args);
-				if (typeof oldArgs === 'undefined') {
+				if (typeof oldArgs === "undefined") {
 					delete State.temporary.args;
 				} else {
 					State.temporary.args = oldArgs;
@@ -220,7 +144,7 @@ function DefineMacro(macroName, macroFunction, tags, skipArgs) {
 			} finally {
 				DOL.Perflog.logWidgetEnd(macroName);
 			}
-		}
+		},
 	});
 }
 
@@ -228,41 +152,47 @@ function DefineMacro(macroName, macroFunction, tags, skipArgs) {
  * Define macro, where macroFunction returns text to wikify & print
  */
 function DefineMacroS(macroName, macroFunction, tags, skipArgs, maintainContext) {
-	DefineMacro(macroName, function () {
-		$(this.output).wiki(macroFunction.apply(maintainContext ? this : null, this.args))
-	}, tags, skipArgs);
+	DefineMacro(
+		macroName,
+		function () {
+			$(this.output).wiki(macroFunction.apply(maintainContext ? this : null, this.args));
+		},
+		tags,
+		skipArgs
+	);
 }
 
 /**
  * @param worn clothing article, State.variables.worn.XXXX
  * @param slot clothing article slot used
- * @return {string} condition key word ("tattered"|"torn|"frayed"|"full")
+ * @returns {string} condition key word ("tattered"|"torn|"frayed"|"full")
  */
-window.integrityKeyword = function(worn, slot) {
-	const i = worn.integrity/clothingData(slot,worn,'integrity_max');
+function integrityKeyword(worn, slot) {
+	const i = worn.integrity / clothingData(slot, worn, "integrity_max");
 	if (i <= 0.2) {
-		return "tattered"
+		return "tattered";
 	} else if (i <= 0.5) {
-		return "torn"
+		return "torn";
 	} else if (i <= 0.9) {
-		return "frayed"
+		return "frayed";
 	} else {
-		return "full"
+		return "full";
 	}
 }
+window.integrityKeyword = integrityKeyword;
 
 /**
  * @param worn clothing article, State.variables.worn.XXXX
  * @param slot clothing article, State.variables.worn.XXXX
- * @return {string} printable integrity prefix
+ * @returns {string} printable integrity prefix
  */
-window.integrityWord = function(worn, slot) {
+function integrityWord(worn, slot) {
 	const kw = integrityKeyword(worn, slot);
 	switch (kw) {
 		case "tattered":
 		case "torn":
 		case "frayed":
-			T.text_output = kw+" ";
+			T.text_output = kw + " ";
 			break;
 		case "full":
 		default:
@@ -270,233 +200,245 @@ window.integrityWord = function(worn, slot) {
 	}
 	return T.text_output;
 }
+window.integrityWord = integrityWord;
 DefineMacroS("integrityWord", integrityWord);
 
 function underlowerintegrity() {
-	return integrityWord(V.worn.under_lower,'under_lower');
+	return integrityWord(V.worn.under_lower, "under_lower");
 }
 DefineMacroS("underlowerintegrity", underlowerintegrity);
 
 function underupperintegrity() {
-	return integrityWord(V.worn.under_upper,'under_upper');
+	return integrityWord(V.worn.under_upper, "under_upper");
 }
 DefineMacroS("underupperintegrity", underupperintegrity);
 
 function overlowerintegrity() {
-	return integrityWord(V.worn.over_lower,'over_lower');
+	return integrityWord(V.worn.over_lower, "over_lower");
 }
 DefineMacroS("overlowerintegrity", overlowerintegrity);
 
 function lowerintegrity() {
-	return integrityWord(V.worn.lower,'lower');
+	return integrityWord(V.worn.lower, "lower");
 }
 DefineMacroS("lowerintegrity", lowerintegrity);
 
 function overupperintegrity() {
-	return integrityWord(V.worn.over_upper,'over_upper');
+	return integrityWord(V.worn.over_upper, "over_upper");
 }
 DefineMacroS("overupperintegrity", overupperintegrity);
 
 function upperintegrity() {
-	return integrityWord(V.worn.upper,'upper');
+	return integrityWord(V.worn.upper, "upper");
 }
 DefineMacroS("upperintegrity", upperintegrity);
 
 function genitalsintegrity() {
-	return integrityWord(V.worn.genitals,'genitals');
+	return integrityWord(V.worn.genitals, "genitals");
 }
 DefineMacroS("genitalsintegrity", genitalsintegrity);
 
 function faceintegrity() {
-	return integrityWord(V.worn.face,'face');
+	return integrityWord(V.worn.face, "face");
 }
 DefineMacroS("faceintegrity", faceintegrity);
 
 /**
  * @param worn clothing article, State.variables.worn.XXXX
- * @return {string} printable clothing colour
+ * @returns {string} printable clothing colour
  */
-window.clothesColour = function(worn){
-	if (!worn.colour) return T.text_output = "";
-	if (worn.colour.startsWith("wet")){ //this might not be used anymore
-		return T.text_output = worn.colour.slice(3);
+function clothesColour(worn) {
+	if (!worn.colour) return (T.text_output = "");
+	if (worn.colour_sidebar) {
+		// eslint-disable-next-line no-undef
+		if (worn.colour === "custom") return (T.text_output = getCustomColourName(worn.colourCustom)); // defined in clothing-shop-v2.js
+		return (T.text_output = worn.colour);
 	}
-	if (worn.colour_sidebar){
-		if (worn.colour == "custom") return T.text_output = getCustomColourName(worn.colourCustom);
-		return T.text_output = worn.colour;
-	}
-	return T.text_output = "";
+	return (T.text_output = "");
 }
+window.clothesColour = clothesColour;
 
 /**
- * @return {void}
+ * set temporary vars for outfit checks
+ *
+ * @returns {void}
  */
-window.outfitChecks = function(){
-	T.underOutfit = ((V.worn.under_lower.outfitSecondary) && V.worn.under_lower.outfitSecondary[1] === V.worn.under_upper.name);
-	T.middleOutfit = ((V.worn.lower.outfitSecondary) && V.worn.lower.outfitSecondary[1] === V.worn.upper.name);
-	T.overOutfit = ((V.worn.over_lower.outfitSecondary) && V.worn.over_lower.outfitSecondary[1] === V.worn.over_upper.name);
-
-	T.underNaked = (V.worn.under_lower.name === "naked" && V.worn.under_upper.name === "naked");
-	T.middleNaked = (V.worn.lower.name === "naked" && V.worn.upper.name === "naked");
-	T.overNaked = (V.worn.over_lower.name === "naked" && V.worn.over_upper.name === "naked");
-	T.topless = (V.worn.over_upper.name === "naked" && V.worn.upper.name === "naked" && V.worn.under_upper.name === "naked");
-	T.bottomless = (V.worn.over_lower.name === "naked" && V.worn.lower.name === "naked" && V.worn.under_lower.name === "naked");
-	T.fullyNaked = (T.topless && T.bottomless);
-	return;
+function outfitChecks() {
+	T.underOutfit = V.worn.under_lower.outfitSecondary && V.worn.under_lower.outfitSecondary[1] === V.worn.under_upper.name;
+	T.middleOutfit = V.worn.lower.outfitSecondary && V.worn.lower.outfitSecondary[1] === V.worn.upper.name;
+	T.overOutfit = V.worn.over_lower.outfitSecondary && V.worn.over_lower.outfitSecondary[1] === V.worn.over_upper.name;
+
+	T.underNaked = V.worn.under_lower.name === "naked" && V.worn.under_upper.name === "naked";
+	T.middleNaked = V.worn.lower.name === "naked" && V.worn.upper.name === "naked";
+	T.overNaked = V.worn.over_lower.name === "naked" && V.worn.over_upper.name === "naked";
+	T.topless = V.worn.over_upper.name === "naked" && V.worn.upper.name === "naked" && V.worn.under_upper.name === "naked";
+	T.bottomless = V.worn.over_lower.name === "naked" && V.worn.lower.name === "naked" && V.worn.under_lower.name === "naked";
+	T.fullyNaked = T.topless && T.bottomless;
 }
+window.outfitChecks = outfitChecks;
 
 /**
  * @return {boolean} whether or not any main-body clothing is out of place or wet
  */
- window.checkForExposedClothing = function(){
-	return setup.clothingLayer.torso.some( clothingLayer => {
-		let wetstage = V[clothingLayer.replace("_","") + "wetstage"];
-		return (V.worn[clothingLayer].state !== setup.clothes[clothingLayer][clothesIndex(clothingLayer, V.worn[clothingLayer])].state_base || wetstage >= 3);
-	})
+function checkForExposedClothing() {
+	return setup.clothingLayer.torso.some(clothingLayer => {
+		const wetstage = V[clothingLayer.replace("_", "") + "wetstage"];
+		return (
+			V.worn[clothingLayer].state !== setup.clothes[clothingLayer][clothesIndex(clothingLayer, V.worn[clothingLayer])].state_base ||
+			wetstage >= 3
+		);
+	});
 }
+window.checkForExposedClothing = checkForExposedClothing;
 
 function processedSvg(width, height) {
-	let svgElem = jQuery(document.createElementNS("http://www.w3.org/2000/svg", "svg"))
-		.attr('xmlns',"http://www.w3.org/2000/svg")
-		.attr('viewBox', '0 0 ' + width + ' ' + height)
+	const svgElem = jQuery(document.createElementNS("http://www.w3.org/2000/svg", "svg"))
+		.attr("xmlns", "http://www.w3.org/2000/svg")
+		.attr("viewBox", "0 0 " + width + " " + height)
+		// eslint-disable-next-line object-shorthand
 		.css({ width: width, height: height })
 		.wiki(this.payload[0].contents.replace(/^\n/, ""));
 
-		let supportedChildElements = ['img', 'image', 'a', 'rect'];
-		let commonAttributes = ['class', 'x', 'y', 'width', 'height', 'style', 'onclick'];
+	const supportedChildElements = ["img", "image", "a", "rect"];
+	const commonAttributes = ["class", "x", "y", "width", "height", "style", "onclick"];
 
-		//Some browsers really don't like working with svg elements unless you specify their namespace upon creation, raw insertion won't render.
-		let fixSVGNameSpace = function(type, elem, newParent = null) {
-			if(type == 'img')
-				type = 'image';
+	// Some browsers really don't like working with svg elements unless you specify their namespace upon creation, raw insertion won't render.
+	const fixSVGNameSpace = (type, elem, newParent = null) => {
+		if (type === "img") type = "image";
 
-			let oldElem = $(elem);
-			let newElem = document.createElementNS('http://www.w3.org/2000/svg', type);
+		const oldElem = $(elem);
+		const newElem = document.createElementNS("http://www.w3.org/2000/svg", type);
 
-			//Set common attributes of new svg namespaced element
-			for(let attr of commonAttributes) {
-				if(oldElem.attr(attr))
-					newElem.setAttribute(attr, oldElem.attr(attr));
-			}
+		// Set common attributes of new svg namespaced element
+		for (const attr of commonAttributes) {
+			if (oldElem.attr(attr)) newElem.setAttribute(attr, oldElem.attr(attr));
+		}
 
-			//Set unique attributes of specific types of elements
-			switch (type) {
-				case 'image':
-					newElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', oldElem.attr('href') || oldElem.attr('xlink:href') || '');
-					break;
-				case 'rect':
-					//No unique properties
-					break;
-				case 'a':
-					newElem.setAttributeNS('http://www.w3.org/1999/xlink', 'title', oldElem.attr('alt') || oldElem.attr('xlink:alt') || '');
-					newElem.setAttributeNS('http://www.w3.org/1999/xlink', 'alt', oldElem.attr('title') || oldElem.attr('xlink:title') || '');
-					break;
-				default:
-					break;
-			}
+		// Set unique attributes of specific types of elements
+		switch (type) {
+			case "image":
+				newElem.setAttributeNS("http://www.w3.org/1999/xlink", "href", oldElem.attr("href") || oldElem.attr("xlink:href") || "");
+				break;
+			case "rect":
+				// No unique properties
+				break;
+			case "a":
+				newElem.setAttributeNS("http://www.w3.org/1999/xlink", "title", oldElem.attr("alt") || oldElem.attr("xlink:alt") || "");
+				newElem.setAttributeNS("http://www.w3.org/1999/xlink", "alt", oldElem.attr("title") || oldElem.attr("xlink:title") || "");
+				break;
+			default:
+				break;
+		}
 
-			if(newParent)
-				newParent.appendChild(newElem);
-			else
-				oldElem.replaceWith(newElem);
+		if (newParent) newParent.appendChild(newElem);
+		else oldElem.replaceWith(newElem);
 
-			//Recursively process nested children if they exist
-			for(let htmlElem of supportedChildElements) {
-				$(oldElem).children(htmlElem).each(function(i, elem) {
+		// Recursively process nested children if they exist
+		for (const htmlElem of supportedChildElements) {
+			$(oldElem)
+				.children(htmlElem)
+				.each((i, elem) => {
 					fixSVGNameSpace(htmlElem, elem, newElem);
 				});
-			}
 		}
-
-		//Because the payload got processed as HTML, fix the namespacing and rendering issues to make it a proper SVG again
-		jQuery(document).one(':passagerender', function (ev) {
-			for(let htmlElem of supportedChildElements) {
-				$(ev.content).find('svg ' + htmlElem).each(function(i, elem) {
+	};
+
+	// Because the payload got processed as HTML, fix the namespacing and rendering issues to make it a proper SVG again
+	$(document).one(":passagerender", function (ev) {
+		for (const htmlElem of supportedChildElements) {
+			$(ev.content)
+				.find("svg " + htmlElem)
+				.each((i, elem) => {
 					fixSVGNameSpace(htmlElem, elem);
 				});
-			}
-		});
+		}
+	});
 
-	//This macro works a little different because we can't rely on the normal wikify method to properly translate SVG elements. We need to manually edit the output variable.
+	// This macro works a little different because we can't rely on the normal wikify method to properly translate SVG elements.
+	// We need to manually edit the output variable.
 	svgElem.appendTo(this.output);
 
-	return '';
+	return "";
 }
-
 DefineMacroS("svg", processedSvg, null, false, true);
 
-/*! <<numberpool>> macro set for SugarCube v2 */
-
 function numberify(selector) {
-	$(() => Links.generateLinkNumbers($(selector)))
+	$(() => Links.generateLinkNumbers($(selector)));
 	return "";
 }
 DefineMacroS("numberify", numberify);
 
+/* obsolete
 // blink entire page to fix a bug in Chrome where animation on images doesn't start
-window.fixStuckAnimations = function() {
-	let scrollX = window.scrollX;
-	let scrollY = window.scrollY;
-	let imgs = $('#story').add($('#ui-bar'));
-	imgs.toggleClass('hidden');
+function fixStuckAnimations() {
+	const scrollX = window.scrollX;
+	const scrollY = window.scrollY;
+	const imgs = $("#story").add($("#ui-bar"));
+	imgs.toggleClass("hidden");
 	window.setTimeout(() => {
-		imgs.toggleClass('hidden');
+		imgs.toggleClass("hidden");
 		window.scroll(scrollX, scrollY);
 	}, 5);
 }
+window.fixStuckAnimations = fixStuckAnimations;
 
 // attaches event listeners to combat images
-window.initTouchToFixAnimations = function() {
-	$(document).on('click', "#divsex img", fixStuckAnimations);
+function initTouchToFixAnimations() {
+	$(document).on("click", "#divsex img", fixStuckAnimations);
 }
 
-$(document).on(':passagedisplay', function (ev) {
+$(document).on(":passagedisplay", function (ev) {
 	if (V.combat) {
 		initTouchToFixAnimations();
 	}
 	function checkFadingSpans() {
-		let spans = $(".fading");
-	  if (spans.length > 0) {
-		  let span = spans[Math.floor(Math.random()*spans.length)];
-		setTimeout(()=>{
-			$(span).removeClass("fading").addClass("faded");
-		  checkFadingSpans();
-		}, Math.random()*1000 + 500);
-	  }
+		const spans = $(".fading");
+		if (spans.length > 0) {
+			const span = spans[Math.floor(Math.random() * spans.length)];
+			setTimeout(() => {
+				$(span).removeClass("fading").addClass("faded");
+				checkFadingSpans();
+			}, Math.random() * 1000 + 500);
+		}
 	}
 
 	setTimeout(checkFadingSpans, 1000);
 });
+*/
 
-window.saveDataCompare = function(save1, save2){
-	var result = {};
-	var keys = Object.keys(save1)
-	keys.forEach(key =>{
-		let save1Json = JSON.stringify(save1[key])
-		let save2Json = JSON.stringify(save2[key])
-		if(save1Json !== save2Json){
-			result[key] = [save1[key],save2[key]];
+function saveDataCompare(save1, save2) {
+	const result = {};
+	const keys = Object.keys(save1);
+	keys.forEach(key => {
+		const save1Json = JSON.stringify(save1[key]);
+		const save2Json = JSON.stringify(save2[key]);
+		if (save1Json !== save2Json) {
+			result[key] = [save1[key], save2[key]];
 		}
-	})
+	});
 	return result;
 }
+window.saveDataCompare = saveDataCompare;
 
-/*For the optional numpad to the right of the screen*/
-window.mobclick = function mobclick(index){
-	$(Links.currentLinks[index-1]).click();
+// For the optional numpad to the right of the screen
+function mobClick(index) {
+	if (index <= Links.currentLinks.length) Links.currentLinks[index - 1].click();
 }
-window.mobBtnHide = function mobBtnHide(){
-	$('.mob-btn').hide()
-	$('.mob-btn-h').show()
+window.mobClick = mobClick;
+function mobBtnHide() {
+	$(".mob-btn").hide();
+	$(".mob-btn-h").show();
 }
-window.mobBtnShow = function mobBtnShow(){
-	$('.mob-btn').show()
-	$('.mob-btn-h').hide()
+window.mobBtnHide = mobBtnHide;
+function mobBtnShow() {
+	$(".mob-btn").show();
+	$(".mob-btn-h").hide();
 }
+window.mobBtnShow = mobBtnShow;
 
 /**
  * This function takes a value, and weights it by exponential curve.
- * 
+ *
  * Value should be between 0.0 and 1.0 (use normalise to get a percentage of a max).
  *
  * An exponent of 1.0 returns 1 every time.
@@ -509,12 +451,14 @@ window.mobBtnShow = function mobBtnShow(){
  *
  * For example, see:
  * https://www.desmos.com/calculator/87hhrjfixi
- * 
+ *
  * @param {number} value Value to be weighted
  * @param {number} exp Exponent used to generate the curve
  * @returns {number} value weighted against exponential curve
  */
-function expCurve(value, exp) {	return (value ** exp) / value; };
+function expCurve(value, exp) {
+	return value ** exp / value;
+}
 window.expCurve = expCurve;
 
 /**
@@ -530,45 +474,48 @@ window.expCurve = expCurve;
  *
  * For example, see:
  * https://www.desmos.com/calculator/87hhrjfixi
- * 
+ *
  * @param {number} exp Exponent used to generate the curve
  * @returns {number} random number weighted against exponential curve
  */
-function randomExp(exp) { return expCurve(State.random(), exp); };
+function randomExp(exp) {
+	return expCurve(State.random(), exp);
+}
 window.randomExp = randomExp;
 
 /**
  * Normalises value to a decimal number 0.0-1.0, a percentage of the range specified in min and max.
+ *
  * @param {number} value The value to be normalised
- * @param {number} max - The highest value of the range
+ * @param {number} max The highest value of the range
  * @param {number} min The lowest value of the range, default 0
  * @returns {number} Normalised value
  */
 function normalise(value, max, min = 0) {
-    const denominator = max - min;
-    if (denominator === 0) {
-        Errors.report('[normalise]: min and max params must be different.', { value, max, min });
-        return 0;
-    }
-    if (denominator < 0) {
-        Errors.report('[normalise]: max param must be greater than min param.', { value, max, min });
-        return 0;
-    }
-    return Math.clamp( (value - min) / denominator, 0, 1);
+	const denominator = max - min;
+	if (denominator === 0) {
+		Errors.report("[normalise]: min and max params must be different.", { value, max, min });
+		return 0;
+	}
+	if (denominator < 0) {
+		Errors.report("[normalise]: max param must be greater than min param.", { value, max, min });
+		return 0;
+	}
+	return Math.clamp((value - min) / denominator, 0, 1);
 }
 window.normalise = normalise;
 
 /**
-* This macro sets $rng. If the variable $rngOverride is set, $rng will always be set to that.
-* Set $rngOverride in the console for bugtesting purposes. Remember to unset it after testing is finished.
-* With two arguments, it sets $rng to a random value between the first arg and the second arg. This can be used to guarantee $rng is set to a specific value.
-* With one argument, it sets $rng to a random value between 1 and the arg.
-* With no arguments, it sets $rng to a random value between 1 and 100.
-*/
-Macro.add('rng', {
+ * This macro sets $rng. If the variable $rngOverride is set, $rng will always be set to that.
+ * Set $rngOverride in the console for bugtesting purposes. Remember to unset it after testing is finished.
+ * With two arguments, it sets $rng to a random value between the first arg and the second arg. This can be used to guarantee $rng is set to a specific value.
+ * With one argument, it sets $rng to a random value between 1 and the arg.
+ * With no arguments, it sets $rng to a random value between 1 and 100.
+ */
+Macro.add("rng", {
 	handler() {
 		if (typeof V.rngOverride === "number" && V.debug === 1) {
-			console.log(`rng override: ${V.rngOverride}`)
+			console.log(`rng override: ${V.rngOverride}`);
 			V.rng = V.rngOverride;
 		} else {
 			let min = 1;
@@ -580,20 +527,21 @@ Macro.add('rng', {
 				max = this.args[0];
 			}
 			if (typeof min === "number" && typeof max === "number") {
-				V.rng = random(min,max);
+				V.rng = random(min, max);
 			} else {
 				throw new Error(`invalid arguments: ${min} | ${max}`);
 			}
 		}
-	}
+	},
 });
 
 /**
  * Returns the object, or a blank object if null. Replaces ?. operator.
+ *
  * @param {object} obj
  * @returns {object} - Either the passed arg or {}
  */
-const nullable = (obj) => obj || {};
+const nullable = obj => obj || {};
 window.nullable = nullable;
 
 /**
@@ -605,14 +553,14 @@ window.nullable = nullable;
 Macro.add("icon", {
 	handler() {
 		if (!V.options.images) return;
-		const name = typeof(this.args[0]) === "string" ? this.args[0] : "error";
+		const name = typeof this.args[0] === "string" ? this.args[0] : "error";
 		const iconImg = document.createElement("img");
 		iconImg.className = "icon";
 		iconImg.src = "img/misc/icon/" + name;
 		this.output.append(iconImg);
-		//append a whitespace for compatibility with old icon behavior
+		// append a whitespace for compatibility with old icon behavior
 		if (!this.args.includes("nowhitespace")) this.output.append(" ");
-	}
+	},
 });
 
 /**
@@ -624,44 +572,42 @@ Macro.add("icon", {
  */
 Macro.add("foldout", {
 	tags: null,
-	handler: function() {
+	handler() {
+		if (window.foldoutStates == null) {
+			window.foldoutStates = {};
+		}
 		function setFoldoutState(state, transition = 0) {
-			if(state) {
+			if (state) {
 				toggle.addClass("extended");
 				body.slideDown(transition);
-			}
-			else {
+			} else {
 				toggle.removeClass("extended");
 				body.slideUp(transition);
 			}
-			State.setVar(varname, foldoutState);
+			window.foldoutStates[varname] = foldoutState;
 		}
+		const def = this.args[0] !== undefined ? this.args[0] : true;
+		const varname = this.args[1] || "_lastAction";
+		let foldoutState = window.foldoutStates[varname] != null ? window.foldoutStates[varname] : def;
+		const content = this.payload[0].contents;
+
+		const e = $("<div>").addClass("foldout").append(Wikifier.wikifyEval(content));
+		const header = e.children().first().addClass("foldoutHeader");
+		const toggle = $("<span>").addClass("foldoutToggle").appendTo(header);
+		const body = e.contents().not(header).wrapAll("<div>").parent().insertAfter(header);
 
-		let def = this.args[0] !== undefined ? this.args[0] : true;
-		let varname = this.args[1] || null;
-		let foldoutState = State.getVar(varname) != null ? State.getVar(varname) : def;
-		let content = this.payload[0].contents;
-
-		let e = $("<div>")
-			.addClass("foldout")
-			.append(Wikifier.wikifyEval(content));
-		let header = e.children().first().addClass("foldoutHeader");
-		let toggle = $("<span>").addClass("foldoutToggle").appendTo(header);
-		let body = e.contents().not(header).wrapAll("<div>").parent().insertAfter(header);
-		
 		setFoldoutState(foldoutState);
 
-		header.on('click', function () {
-				foldoutState = !foldoutState;
-				setFoldoutState(foldoutState, 100);
-			});
+		header.on("click", function () {
+			foldoutState = !foldoutState;
+			setFoldoutState(foldoutState, 100);
+		});
 		e.appendTo(this.output);
-	}
+	},
 });
 
-window.pickRandom = function (list) {
-	if (!list)
-		return undefined;
-
+function pickRandom(list) {
+	if (!list) return undefined;
 	return list[Math.floor(Math.random() * list.length)];
 }
+window.pickRandom = pickRandom;
diff --git a/game/03-JavaScript/bedroomPills.js b/game/03-JavaScript/bedroomPills.js
index 211bc1a351..77e2277f0f 100644
--- a/game/03-JavaScript/bedroomPills.js
+++ b/game/03-JavaScript/bedroomPills.js
@@ -1,3 +1,4 @@
+/* eslint-disable dot-notation */
 /*
  * if display_condition is 1, item is displayed, else it's not
  * current max doses for Harper/Asylum pills is 1; 2 for every other pills
@@ -5,7 +6,7 @@
  * if you feel lost just ask away :)
  * take_condition == 1 means the "Take Pill" button is not greyed out and is clickable
  * display_condition controls whether or not pill should be displayed in the pill menu
-*/
+ */
 
 /*
 --- Please change this comment as needed when the format of setup.pills changes ---
@@ -34,583 +35,821 @@ A single pill object contains multiple 'properties' which define the pill.
 */
 setup.pills = [
 	{
-		name:'bottom reduction',
-		description: 'Each pill contains 500mg of Praberrhol, a derived molecule crafted specifically to attach to the triglyceride present in your buttocks and dissolve them over time.',
-		onTakeMessage: 'You take the pills intended to reduce your butt\'s size. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe side effects upon exceeding the maximum dose prescribed per day. Not to be associated with any other hormonal treatment.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "bottom reduction",
+		description:
+			"Each pill contains 500mg of Praberrhol, a derived molecule crafted specifically to attach to the triglyceride present in your buttocks and dissolve them over time.",
+		onTakeMessage: "You take the pills intended to reduce your butt's size. You hope it will be as effective as advertised.",
+		warning_label:
+			"Warning: Severe side effects upon exceeding the maximum dose prescribed per day. Not to be associated with any other hormonal treatment.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "bottom",
 		subtype: "reduction",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/bottomReduction.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["bottom growth"].doseTaken === 0 && V.sexStats.pills["pills"]["bottom blocker"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/bottomReduction.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 &&
+				V.sexStats.pills["pills"]["bottom growth"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["bottom blocker"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'bottom growth',
-		description: 'This pill contains a molecule, the Nynthroptechloxin, a technological prowess made possible by our most eminent pharmaceutical scientist, Dr Bancel. It increases the body production of a very particular hormone responsible for hips and buttocks\' weight gains. 190mg of this molecule is present per pill. ',
-		onTakeMessage: 'You take the pills intended to boost your butt\'s growth. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "bottom growth",
+		description:
+			"This pill contains a molecule, the Nynthroptechloxin, a technological prowess made possible by our most eminent pharmaceutical scientist, Dr Bancel. It increases the body production of a very particular hormone responsible for hips and buttocks' weight gains. 190mg of this molecule is present per pill. ",
+		onTakeMessage: "You take the pills intended to boost your butt's growth. You hope it will be as effective as advertised.",
+		warning_label:
+			"Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "bottom",
 		subtype: "growth",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/bottomGrowth.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["bottom reduction"].doseTaken === 0 && V.sexStats.pills["pills"]["bottom blocker"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/bottomGrowth.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 &&
+				V.sexStats.pills["pills"]["bottom reduction"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["bottom blocker"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'bottom blocker',
-		description: 'Each pill contains 200mg of Praberrhol-NG2, a derived molecule crafted specifically to attach to the triglyceride present in your buttocks and dissolve them over time. The right dosage allowing to keep a balance between gained fat and dissolved fat.',
-		onTakeMessage: 'You take the pills intended to block your butt\'s growth. You hope it will be as effective as advertised.',
-		warning_label: '<span class="hpi_notice_label">Notice: No side effects were determined during the trials for this drug. Taking more than 1 pill per 24 hours is ineffective</span>',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "bottom blocker",
+		description:
+			"Each pill contains 200mg of Praberrhol-NG2, a derived molecule crafted specifically to attach to the triglyceride present in your buttocks and dissolve them over time. The right dosage allowing to keep a balance between gained fat and dissolved fat.",
+		onTakeMessage: "You take the pills intended to block your butt's growth. You hope it will be as effective as advertised.",
+		warning_label:
+			"<span class='hpi_notice_label'>Notice: No side effects were determined during the trials for this drug. Taking more than 1 pill per 24 hours is ineffective</span>",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "bottom",
 		subtype: "blocker",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/bottomBlocker.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["bottom growth"].doseTaken === 0 && V.sexStats.pills["pills"]["bottom reduction"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/bottomBlocker.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() === 0 &&
+				V.sexStats.pills["pills"]["bottom growth"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["bottom reduction"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'breast reduction',
-		description: 'Each pill contains 500mg of Praberrhol (NG2), a derived molecule crafted specifically to attach to the triglyceride present in your breast and dissolve them over time.',
-		onTakeMessage: 'You take the pills intended to reduce your breasts\' size. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "breast reduction",
+		description:
+			"Each pill contains 500mg of Praberrhol (NG2), a derived molecule crafted specifically to attach to the triglyceride present in your breast and dissolve them over time.",
+		onTakeMessage: "You take the pills intended to reduce your breasts' size. You hope it will be as effective as advertised.",
+		warning_label:
+			"Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "breast",
 		subtype: "reduction",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/breastReduction.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["breast growth"].doseTaken === 0 && V.sexStats.pills["pills"]["breast blocker"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/breastReduction.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 &&
+				V.sexStats.pills["pills"]["breast growth"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["breast blocker"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'breast growth',
-		description: 'An hormonal mRNA therapy-pill. The 5mg of Dipardyn present aim at triggering natural secretion of the specific hormones in cause in breasts growth. While the mRNA will help have your cells produce a new kind of hormone increasing the tissue production in your breasts, and their capabilities to store fat, effectively making your breasts grow faster.',
-		onTakeMessage: 'You take the pills intended to boost your breasts\' growth. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "breast growth",
+		description:
+			"An hormonal mRNA therapy-pill. The 5mg of Dipardyn present aim at triggering natural secretion of the specific hormones in cause in breasts growth. While the mRNA will help have your cells produce a new kind of hormone increasing the tissue production in your breasts, and their capabilities to store fat, effectively making your breasts grow faster.",
+		onTakeMessage: "You take the pills intended to boost your breasts' growth. You hope it will be as effective as advertised.",
+		warning_label:
+			"Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "breast",
 		subtype: "growth",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/breastGrowth.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["breast reduction"].doseTaken === 0 && V.sexStats.pills["pills"]["breast blocker"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/breastGrowth.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 &&
+				V.sexStats.pills["pills"]["breast reduction"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["breast blocker"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'breast blocker',
-		description: 'A selective estrogen receptor modulator (SERM), blocking the protein receptors in cause in breast growth; Supplemented by 269mg of Tetraozealpostigyl.',
-		onTakeMessage: 'You take the pills intended to block your breasts\' growth. You hope it will be as effective as advertised.',
-		warning_label: '<span class="hpi_notice_label">Notice: No side effects were determined during the trials for this drug. Taking more than 1 pill per 24 hours is ineffective</span>',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "breast blocker",
+		description:
+			"A selective estrogen receptor modulator (SERM), blocking the protein receptors in cause in breast growth; Supplemented by 269mg of Tetraozealpostigyl.",
+		onTakeMessage: "You take the pills intended to block your breasts' growth. You hope it will be as effective as advertised.",
+		warning_label:
+			'<span class="hpi_notice_label">Notice: No side effects were determined during the trials for this drug. Taking more than 1 pill per 24 hours is ineffective</span>',
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "breast",
 		subtype: "blocker",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/breastBlocker.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["breast growth"].doseTaken === 0 && V.sexStats.pills["pills"]["breast reduction"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/breastBlocker.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() === 0 &&
+				V.sexStats.pills["pills"]["breast growth"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["breast reduction"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'penis reduction',
-		description: 'Each pill contains 50mg of Chliustose which has limited anti-androgen effects. In addition of 450mg of Phirhyn that will reduce the amount and thickness of the erectile tissue.',
-		onTakeMessage: 'You take the pills intended to reduce your penis\' size. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "penis reduction",
+		description:
+			"Each pill contains 50mg of Chliustose which has limited anti-androgen effects. In addition of 450mg of Phirhyn that will reduce the amount and thickness of the erectile tissue.",
+		onTakeMessage: "You take the pills intended to reduce your penis' size. You hope it will be as effective as advertised.",
+		warning_label:
+			"Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "penis",
 		subtype: "reduction",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/penisReduction.png',
-		display_condition: function(){return (V.player.penisExist && this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["penis growth"].doseTaken === 0 && V.sexStats.pills["pills"]["penis blocker"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/penisReduction.png",
+		display_condition() {
+			return V.player.penisExist && this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 &&
+				V.sexStats.pills["pills"]["penis growth"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["penis blocker"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'penis growth',
-		description: 'Each pill contains 780mg of Cumnictondyl, 240mg of Iphopol and 149mg of testosterone undecanoate. The two molecules enable and facilitate the action of the androgen, which has for effect to resume the natural growth of your penis.',
-		onTakeMessage: 'You take the pills intended to boost your penis\' growth. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "penis growth",
+		description:
+			"Each pill contains 780mg of Cumnictondyl, 240mg of Iphopol and 149mg of testosterone undecanoate. The two molecules enable and facilitate the action of the androgen, which has for effect to resume the natural growth of your penis.",
+		onTakeMessage: "You take the pills intended to boost your penis' growth. You hope it will be as effective as advertised.",
+		warning_label:
+			"Warning: Severe side effects upon exceeding the maximum doses per day. Refer to your doctor if in doubts. Not to be associated with any other hormonal treatment.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "penis",
 		subtype: "growth",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/penisGrowth.png',
-		display_condition: function(){return (V.player.penisExist && this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["penis reduction"].doseTaken === 0 && V.sexStats.pills["pills"]["penis blocker"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/penisGrowth.png",
+		display_condition() {
+			return V.player.penisExist && this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 &&
+				V.sexStats.pills["pills"]["penis reduction"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["penis blocker"].doseTaken === 0
+				? 1
+				: 0;
+		},
+		effects: [],
 	},
 	{
-		name:'penis blocker',
-		description: 'An anti-androgen hormonal treatment containing 370mg of Dynthryme aiming at blocking the production of androsterone and testosterone in your body, effectively blocking penile growth.',
-		onTakeMessage: 'You take the pills intended to block your penis\' growth. You hope it will be as effective as advertised.',
-		warning_label: '<span class="hpi_notice_label">Notice: No side effects were determined during the trials for this drug. Taking more than 1 pill per 24 hours is ineffective</span>',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "penis blocker",
+		description:
+			"An anti-androgen hormonal treatment containing 370mg of Dynthryme aiming at blocking the production of androsterone and testosterone in your body, effectively blocking penile growth.",
+		onTakeMessage: "You take the pills intended to block your penis' growth. You hope it will be as effective as advertised.",
+		warning_label:
+			'<span class="hpi_notice_label">Notice: No side effects were determined during the trials for this drug. Taking more than 1 pill per 24 hours is ineffective</span>',
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "penis",
 		subtype: "blocker",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/penisBlocker.png',
-		display_condition: function(){return (V.player.penisExist && this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() === 0 && V.sexStats.pills["pills"]["penis growth"].doseTaken === 0 && V.sexStats.pills["pills"]["penis reduction"].doseTaken === 0)},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/penisBlocker.png",
+		display_condition() {
+			return V.player.penisExist && this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return (
+				this.doseTaken() === 0 &&
+				V.sexStats.pills["pills"]["penis growth"].doseTaken === 0 &&
+				V.sexStats.pills["pills"]["penis reduction"].doseTaken === 0
+			);
+		},
+		effects: [],
 	},
 	{
-		name:'fertility booster',
-		description: 'Each pill contains 50mg of clomiphene citrate, a structural analogue of estrogens. It also acts on your hypothalamus which secretes the hormones necessary to trigger ovulation. In most cases effectively inducing your ovary to release eggs.',
-		onTakeMessage: 'You take the pills intended to increase your fertility. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Severe complications if exceeding the maximum doses per day.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "fertility booster",
+		description:
+			"Each pill contains 50mg of clomiphene citrate, a structural analogue of estrogens. It also acts on your hypothalamus which secretes the hormones necessary to trigger ovulation. In most cases effectively inducing your ovary to release eggs.",
+		onTakeMessage: "You take the pills intended to increase your fertility. You hope it will be as effective as advertised.",
+		warning_label: "Warning: Severe complications if exceeding the maximum doses per day.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "pregnancy",
 		subtype: "fertility",
 		shape: "pill",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/pregnancyFertility.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["contraceptive"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/pregnancyFertility.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 && V.sexStats.pills["pills"]["contraceptive"].doseTaken === 0 ? 1 : 0;
+		},
+		effects: [],
 	},
 	{
-		name:'contraceptive',
-		description: 'Estroprogestatifs associating 24mg of ethinylestradiol(synthetic estrogen) and 31mg of a synthetic progestin for a near-perfect contraceptive effect.',
-		onTakeMessage: 'You take the contraceptive pill. You hope it will be as effective as advertised.',
-		warning_label: 'Warning: Serious side effects upon exceeding the maximum doses per day. If in doubt, please consult your doctor.',
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "contraceptive",
+		description:
+			"Estroprogestatifs associating 24mg of ethinylestradiol(synthetic estrogen) and 31mg of a synthetic progestin for a near-perfect contraceptive effect.",
+		onTakeMessage: "You take the contraceptive pill. You hope it will be as effective as advertised.",
+		warning_label: "Warning: Serious side effects upon exceeding the maximum doses per day. If in doubt, please consult your doctor.",
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "pregnancy",
 		subtype: "contraceptive",
 		shape: "galenic",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/pregnancyContraceptive.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 2 && V.sexStats.pills["pills"]["fertility booster"].doseTaken === 0) ? 1 : 0},
-		effects:[]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/pregnancyContraceptive.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 2 && V.sexStats.pills["pills"]["fertility booster"].doseTaken === 0 ? 1 : 0;
+		},
+		effects: [],
 	},
 	{
-		name:'asylum\'s prescription',
-		description: 'A powerful antipsychotic.',
-		onTakeMessage: 'You take the pills prescribed in the asylum. You feel hazy.',
-		warning_label: '<span class="hpi_notice_label">Notice: No side effects could be determined during the experimental stage of this drug, and it passed all safety regulations. \
-						<span class="hpi_blur unselectable">I think this drug company is about to be the end of me. No side effects ? Who do they think they\'re kidding ?!</span></span>',
-		autoTake: false,
-		indicators: [
-			`<span class="hpi_indic_green">++ Control</span>`,
-			`<span class="hpi_indic_blue">- Awareness</span>`
-		],
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "asylum's prescription",
+		description: "A powerful antipsychotic.",
+		onTakeMessage: "You take the pills prescribed in the asylum. You feel hazy.",
+		warning_label:
+			"<span class='hpi_notice_label'>Notice: No side effects could be determined during the experimental stage of this drug, and it passed all safety regulations. <span class='hpi_blur unselectable'>I think this drug company is about to be the end of me. No side effects ? Who do they think they're kidding ?!</span></span>",
+		indicators: ["<span class='hpi_indic_green'>++ Control</span>", "<span class='hpi_indic_blue'>- Awareness</span>"],
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "asylum",
 		shape: "galenic",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/strong pills.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 1 && V.asylummedicated == 0) ? 1 : 0},
-		effects: [
-			`<<awareness -5>>`,
-			`<<control 25>>`,
-			`<<set $asylummedicated += 1>>`
-		]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/strong pills.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 1 && V.asylummedicated === 0 ? 1 : 0;
+		},
+		effects: [`<<awareness -5>>`, `<<control 25>>`, `<<set $asylummedicated += 1>>`],
 	},
 	{
-		name:'Dr Harper\'s prescription',
-		description: 'Antipsychotic medication.',
-		onTakeMessage: 'You take the pills Doctor Harper prescribed. You feel dizzy.',
-		warning_label: 'Warning: The side effects upon reaching maximum dosage have not been studied enough. Proceed with caution. \
-		<span class="hpi_blur"></span>',
-		indicators: [
-			`<span class="hpi_indic_green">+ Control</span>`,
-			`<span class="hpi_indic_blue">- Awareness</span>`
-		],
-		autoTake: function(){return V.sexStats.pills["pills"][this.name].autoTake},
-		doseTaken: function(){return V.sexStats.pills["pills"][this.name].doseTaken},
-		owned: function(){return V.sexStats.pills["pills"][this.name].owned},
+		name: "Dr Harper's prescription",
+		description: "Antipsychotic medication.",
+		onTakeMessage: "You take the pills Doctor Harper prescribed. You feel dizzy.",
+		warning_label:
+			"Warning: The side effects upon reaching maximum dosage have not been studied enough. Proceed with caution. <span class='hpi_blur'></span>",
+		indicators: ["<span class='hpi_indic_green'>+ Control</span>", "<span class='hpi_indic_blue'>- Awareness</span>"],
+		autoTake() {
+			return V.sexStats.pills["pills"][this.name].autoTake;
+		},
+		doseTaken() {
+			return V.sexStats.pills["pills"][this.name].doseTaken;
+		},
+		owned() {
+			return V.sexStats.pills["pills"][this.name].owned;
+		},
 		type: "harper",
 		shape: "galenic",
-		overdose: function(){return V.sexStats.pills["pills"][this.name].overdose},
-		icon: 'img/misc/icon/pills.png',
-		display_condition: function(){return (this.owned() > 0) ? 1 : 0},
-		take_condition: function(){return (this.doseTaken() < 1 && V.medicated == 0) ? 1 : 0},
-		effects: [
-			`<<awareness -1>>`,
-			`<<control 10>>`,
-			`<<set $medicated += 1>>`
-		]
-	}
-]
+		overdose() {
+			return V.sexStats.pills["pills"][this.name].overdose;
+		},
+		icon: "img/misc/icon/pills.png",
+		display_condition() {
+			return this.owned() > 0 ? 1 : 0;
+		},
+		take_condition() {
+			return this.doseTaken() < 1 && V.medicated === 0 ? 1 : 0;
+		},
+		effects: [`<<awareness -1>>`, `<<control 10>>`, `<<set $medicated += 1>>`],
+	},
+];
 
-window.generateHomePillsInventory = function() {
-	$(function(){
-		T.disableGridClick = false
-		for (let item of setup.pills){
-			if (item.display_condition() == 1)
-				window.addElementToGrid(item)
+function generateHomePillsInventory() {
+	$(function () {
+		T.disableGridClick = false;
+		for (const item of setup.pills) {
+			if (item.display_condition() === 1) window.addElementToGrid(item);
 		}
 	});
 }
+window.generateHomePillsInventory = generateHomePillsInventory;
 
-window.onMouseEventDisableGridClick = function(code) {
-	T.disableGridClick = code
-}
-
-window.addElementToGrid = function(item) {
-	$(function(){
-		let hpi_gridContainer = document.getElementById("homeMainPillContainer");
+function addElementToGrid(item) {
+	$(function () {
+		const hpiGridContainer = document.getElementById("homeMainPillContainer");
 
-		let item_name = item.name[0].toUpperCase() + item.name.slice(1)
-		hpi_gridContainer.innerHTML = hpi_gridContainer.innerHTML +
-		`
-		<div class="hpi_item">
-		<div class="hpi_icon"><img class="icon" src="` + item.icon + `"</img></div>
-		<div class="hpi_name" id="hpi_name_` + item_name + `" >` + item_name + ((item.autoTake() == true) ? `<span class="hpi_auto_label"> [Auto]</span>` : "") + `</div>
-		<div class="hpi_count" onmouseenter="window.onMouseEventDisableGridClick(true)" onmouseleave="window.onMouseEventDisableGridClick(false)">` + item.owned() + `</div>
-		</div>
-		`
-		hpi_gridContainer.lastElementChild.setAttribute('onclick', "window.onHomePillItemClick(" + "`" + item.name + "`" + ")")
+		const itemName = item.name[0].toUpperCase() + item.name.slice(1);
+		hpiGridContainer.innerHTML =
+			hpiGridContainer.innerHTML +
+			`
+			<div class="hpi_item">
+				<div class="hpi_icon"><img class="icon" src="` +
+			item.icon +
+			`"</img></div>
+				<div class="hpi_name" id="hpi_name_` +
+			itemName +
+			`" >` +
+			itemName +
+			(item.autoTake() === true ? `<span class="hpi_auto_label"> [Auto]</span>` : "") +
+			`</div>
+				<div class="hpi_count" onmouseenter="T.disableGridClick = true" onmouseleave="T.disableGridClick = false">` +
+			item.owned() +
+			`</div>
+			</div>
+			`;
+		hpiGridContainer.lastElementChild.setAttribute("onclick", "window.onHomePillItemClick(" + "`" + item.name + "`" + ")");
 	});
 }
+window.addElementToGrid = addElementToGrid;
 
-window.onHomePillItemClick = function(item_name) {
-	if (!T.disableGridClick){
-		document.getElementById("homeDescPillContainer").style.display = 'grid'
-		for (let item of setup.pills){
-			if (item.name == item_name){
+function onHomePillItemClick(itemName) {
+	if (!T.disableGridClick) {
+		document.getElementById("homeDescPillContainer").style.display = "grid";
+		for (const item of setup.pills) {
+			if (item.name === itemName) {
 				document.getElementById("hpi_desc").outerHTML =
-				`<div id="hpi_desc">`+ item.description +
-				`
-					<div class="hpi_warning_label">` + item.warning_label + `</div>
+					`<div id="hpi_desc">` +
+					item.description +
+					`
+					<div class="hpi_warning_label">` +
+					item.warning_label +
+					`</div>
 					<div id="hpi_desc_action">
-						<a id="hpi_take_pills" onclick="window.onTakeClick(` + "`" + item.name + "`," + "`" + item.type + "`" + `)" class="hpi_take_pills">Take pill</a>
-						<a id="hpi_take_every_morning" onclick="window.onAutoTakeClick(` + "`" + item.name + "`," + "`" + item.type + "`" + `)">Take every morning</a>
+						<a id="hpi_take_pills" onclick="window.onTakeClick(` +
+					"`" +
+					item.name +
+					"`," +
+					"`" +
+					item.type +
+					"`" +
+					`)" class="hpi_take_pills">Take pill</a>
+						<a id="hpi_take_every_morning" onclick="window.onAutoTakeClick(` +
+					"`" +
+					item.name +
+					"`," +
+					"`" +
+					item.type +
+					"`" +
+					`)">Take every morning</a>
 					</div>
 				</div>
-				`
-				window.initPillContextButtons(item)
-				document.getElementById("hpi_desc_img").innerHTML = `<img` + ((item.shape == "galenic") ? ` style="margin-left: 17%;"` : "") + ` src="` + item.icon + `"></img>` +
-				`<div id="hpi_indicator" class="hpi_indicator"></div>`
+				`;
+				window.initPillContextButtons(item);
+				document.getElementById("hpi_desc_img").innerHTML =
+					`<img` +
+					(item.shape === "galenic" ? ` style="margin-left: 17%;"` : "") +
+					` src="` +
+					item.icon +
+					`"></img>` +
+					`<div id="hpi_indicator" class="hpi_indicator"></div>`;
 				window.addIndicators(item);
 			}
 		}
 	}
 }
+window.onHomePillItemClick = onHomePillItemClick;
 
-window.addIndicators = function(item){ // Indicators are the "++Control" and "+Awareness" etc. We add them under the pill icon.
-	if (item.indicators != undefined && item.indicators.length > 0){
-		for (let indicator of item.indicators)
-			document.getElementById("hpi_indicator").innerHTML += indicator
+function addIndicators(item) {
+	// Indicators are the "++Control" and "+Awareness" etc. We add them under the pill icon.
+	if (item.indicators != null && item.indicators.length > 0 && V.statdisable !== "t") {
+		for (const indicator of item.indicators) document.getElementById("hpi_indicator").innerHTML += indicator;
 	}
 }
+window.addIndicators = addIndicators;
 
-window.initPillContextButtons = function(item){
-    // create button to "Take everyone morning" / "Stop taking them" (every morning)
-    document.getElementById("hpi_take_every_morning").innerHTML = (item.autoTake()) ? "Stop taking them" : "Take every morning"
-    
-    // special case if pill type is "asylum" or "harper"
-    if (item.type == "asylum" || item.type == "harper"){
-        document.getElementById("hpi_take_every_morning").className = "hidden" // prevent 'Take every Morning' option to be displayed for those type of pills
-        document.getElementById("hpi_take_pills").classList.add("hpi_take_me_single") // readapt css since there's only one button now
-    }
-    //  Add 'Take pill' button
-    document.getElementById("hpi_take_pills").innerHTML = "Take pill"
+function initPillContextButtons(item) {
+	// create button to "Take everyone morning" / "Stop taking them" (every morning)
+	document.getElementById("hpi_take_every_morning").innerHTML = item.autoTake() ? "Stop taking them" : "Take every morning";
 
-    // If the button doesnt exist, create it. If it exists, display the right dose Taken for that pill
-    if (document.getElementById("hpi_doseTaken") != undefined)
-        document.getElementById("hpi_doseTaken").outerHTML = `<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>` // Display today taken doses for specific pill
-    else
-        document.getElementById("hpi_take_pills").outerHTML += `<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>` // Display today taken doses for specific pill
-    
-    // Check if the player meets the criteria to take the pill.
-    if (item.take_condition() == 0){
-        document.getElementById("hpi_take_pills").classList.add("hpi_greyed_out") // grey the "Take Pill" button out
-        document.getElementById("hpi_take_pills").onclick = "" // disable "Take Pill" onclick event.
-    }
-};
+	// special case if pill type is "asylum" or "harper"
+	if (item.type === "asylum" || item.type === "harper") {
+		document.getElementById("hpi_take_every_morning").className = "hidden"; // prevent 'Take every Morning' option to be displayed for those type of pills
+		document.getElementById("hpi_take_pills").classList.add("hpi_take_me_single"); // readapt css since there's only one button now
+	}
+	//  Add 'Take pill' button
+	document.getElementById("hpi_take_pills").innerHTML = "Take pill";
+
+	// If the button doesnt exist, create it. If it exists, display the right dose Taken for that pill
+	if (document.getElementById("hpi_doseTaken") != null)
+		// todo: replace style with a proper css class
+		document.getElementById("hpi_doseTaken").outerHTML =
+			"<span id='hpi_doseTaken' style='font-size: 0.88em;color: #979797;'> [" + item.doseTaken() + " Taken]</span>";
+	// Display today taken doses for specific pill
+	else
+		document.getElementById("hpi_take_pills").outerHTML +=
+			`<span id="hpi_doseTaken" style="font-size: 0.88em;color: #979797;"> [` + item.doseTaken() + ` Taken]</span>`; // Display today taken doses for specific pill
+
+	// Check if the player meets the criteria to take the pill.
+	if (item.take_condition() === 0) {
+		document.getElementById("hpi_take_pills").classList.add("hpi_greyed_out"); // grey the "Take Pill" button out
+		document.getElementById("hpi_take_pills").onclick = ""; // disable "Take Pill" onclick event.
+	}
+}
+window.initPillContextButtons = initPillContextButtons;
 
-window.setLastTaken = function(type, subtype, fullname=null) {
-	if (fullname != null){
-		for (let p of setup.pills){
-			if (p.name == fullname){
+function setLastTaken(type, subtype, fullname = null) {
+	if (fullname != null) {
+		for (const p of setup.pills) {
+			if (p.name === fullname) {
 				type = p.type;
-				subtype = p.subtype
+				subtype = p.subtype;
 			}
 		}
 	}
-	V.sexStats.pills.lastTaken[type] = subtype
-}
-
-window.pickRandomItemInArray = function(array) {
-	if (array != null && array.length > 0 && typeof array == 'object')
-		return(array[window.getRandomIntInclusive(0, array.length-1)]);
-	console.log(array)
-	throw 'Error in bedroomPills.js line 243 : parameter is either empty/null or not an object'; //intentional, so the person using that function knows his stuff is not valid
+	V.sexStats.pills.lastTaken[type] = subtype;
 }
+window.setLastTaken = setLastTaken;
 
-window.redetermineMostTaken = function(type, subtype, fullname=null) {
-	let result = {"blocker":0,"growth":0,"reduction":0};
-	let ret;
-
-	if (fullname != null){
-		for (let p of setup.pills){
-			if (p.name == fullname){
+function redetermineMostTaken(type, subtype, fullname = null) {
+	const result = { blocker: 0, growth: 0, reduction: 0 };
+	if (fullname != null) {
+		for (const p of setup.pills) {
+			if (p.name === fullname) {
 				type = p.type;
-				subtype = p.subtype
+				subtype = p.subtype;
 			}
 		}
 	}
-	if (["breast", "bottom", "penis"].includes(type) == false)
-		return
-	for (let pill of setup.pills){
-		if (pill.type == type && ["blocker", "growth", "reduction"].includes(pill.subtype))
-			result[pill.subtype] = pill.doseTaken()
-	}
-	ret = result.growth - result.reduction;
-	if (ret == 0 && (result.growth > 0 || result.reduction > 0)){ // We enter here when growth and reduction pills neutralised each others
-		if (result.blocker > 0)
-			return (V.sexStats.pills.mostTaken[type] = "blocker")
-		else
-			return (pickRandomItemInArray(V.sexStats.pills.mostTaken[type] = ["growth", "reduction"]))
+	if (!["breast", "bottom", "penis"].includes(type)) return;
+	for (const pill of setup.pills) {
+		if (pill.type === type && ["blocker", "growth", "reduction"].includes(pill.subtype));
+		result[pill.subtype] = pill.doseTaken();
 	}
-	else if (ret == 0 && result.blocker > 0) // we enter here when player didn't take any growth/blocker but took blockers
-		return (V.sexStats.pills.mostTaken[type] = "blocker")
-	else if (ret != 0){ // we enter here when there's unbalance between growth/reduction
-		if (ret < 0) // if reduction won
-			return (ret + result.blocker >= 0) ? (V.sexStats.pills.mostTaken[type] = "blocker") : (V.sexStats.pills.mostTaken[type] = "reduction") // determine if blocker win
-		else if (ret > 0) // if growth won
-			return (ret - result.blocker <= 0) ? (V.sexStats.pills.mostTaken[type] = "blocker") : (V.sexStats.pills.mostTaken[type] = "growth") // determine if blocker win
+	const ret = result.growth - result.reduction;
+	if (ret === 0 && (result.growth > 0 || result.reduction > 0)) {
+		// We enter here when growth and reduction pills neutralised each others
+		if (result.blocker > 0) return (V.sexStats.pills.mostTaken[type] = "blocker");
+		else return (V.sexStats.pills.mostTaken[type] = ["growth", "reduction"].random());
+	} else if (ret === 0 && result.blocker > 0)
+		// we enter here when player didn't take any growth/blocker but took blockers
+		return (V.sexStats.pills.mostTaken[type] = "blocker");
+	else if (ret !== 0) {
+		// we enter here when there's unbalance between growth/reduction
+		if (ret < 0)
+			// if reduction won
+			return ret + result.blocker >= 0
+				? (V.sexStats.pills.mostTaken[type] = "blocker")
+				: (V.sexStats.pills.mostTaken[type] = "reduction");
+		// determine if blocker win
+		else if (ret > 0)
+			// if growth won
+			return ret - result.blocker <= 0
+				? (V.sexStats.pills.mostTaken[type] = "blocker")
+				: (V.sexStats.pills.mostTaken[type] = "growth"); // determine if blocker win
 	}
 }
+window.redetermineMostTaken = redetermineMostTaken;
 
-window.onTakeClick = function (item_name){
-	V.sexStats.pills["pills"][item_name].owned -= 1;
-	V.sexStats.pills["pills"][item_name].doseTaken += 1 // Stat for specific pill consumption
-	V.pillsConsumed = (typeof V.pillsConsumed == "undefined" || V.pillsConsumed == null) ? 1 : V.pillsConsumed + 1 // Stat for total pills consumption
-	for (let item of setup.pills){
-		if (item.name == item_name){
-			for (let widget of item.effects) // run the widgets associated with a pill
-				new Wikifier(null, (typeof widget == "function") ? widget() : widget);
-			V.sexStats.pills.lastTaken[item.type] = item.subtype // keep track of the category of pill we last took
-			V.sexStats.pills.mostTaken[item.type] = window.redetermineMostTaken(item.type, item.subtype)
-			if (item.doseTaken() > 1 && item.name.contains("blocker") == false){
-				if (item.type == "pregnancy"){
-					Engine.play("PillCollectionSecondDosePregnancy")
-					return
-				}
-				else{
-					Engine.play("PillCollectionSecondDose")
-					return
+function onTakeClick(itemName) {
+	V.sexStats.pills["pills"][itemName].owned -= 1;
+	V.sexStats.pills["pills"][itemName].doseTaken += 1; // Stat for specific pill consumption
+	V.pillsConsumed = typeof V.pillsConsumed === "undefined" || V.pillsConsumed == null ? 1 : V.pillsConsumed + 1; // Stat for total pills consumption
+	for (const item of setup.pills) {
+		if (item.name === itemName) {
+			for (const widget of item.effects) // run the widgets associated with a pill
+				Wikifier.wikifyEval(typeof widget === "function" ? widget() : widget);
+			V.sexStats.pills.lastTaken[item.type] = item.subtype; // keep track of the category of pill we last took
+			V.sexStats.pills.mostTaken[item.type] = window.redetermineMostTaken(item.type, item.subtype);
+			if (item.doseTaken() > 1 && item.name.contains("blocker") === false) {
+				if (item.type === "pregnancy") {
+					Engine.play("PillCollectionSecondDosePregnancy");
+					return;
+				} else {
+					Engine.play("PillCollectionSecondDose");
+					return;
 				}
 			}
-			V.lastPillTakenDescription = item.onTakeMessage
+			V.lastPillTakenDescription = item.onTakeMessage;
 		}
 	}
-	Engine.play("Take Pill From Medicine Drawer")
+	Engine.play("Take Pill From Medicine Drawer");
 }
+window.onTakeClick = onTakeClick;
 
-window.onAutoTakeClick = function(item_name, item_type){
-	for (let item in setup.pills){
-		if (setup.pills[item].name == item_name){
-			V.sexStats.pills["pills"][item_name].autoTake = !V.sexStats.pills["pills"][item_name].autoTake // toggle auto take
-			window.initPillContextButtons(setup.pills[item]) // change "Take every morning" button to "Stop taking them"
-		}
-		else if (["breast", "penis", "bottom", "pregnancy"].includes(item_type) && setup.pills[item].type == item_type)
-			V.sexStats.pills["pills"][setup.pills[item].name].autoTake = false // disable auto takes for other similar pills(bottom/penis/breast etc)
+function onAutoTakeClick(itemName, itemType) {
+	for (const item in setup.pills) {
+		if (setup.pills[item].name === itemName) {
+			V.sexStats.pills["pills"][itemName].autoTake = !V.sexStats.pills["pills"][itemName].autoTake; // toggle auto take
+			window.initPillContextButtons(setup.pills[item]); // change "Take every morning" button to "Stop taking them"
+		} else if (["breast", "penis", "bottom", "pregnancy"].includes(itemType) && setup.pills[item].type === itemType)
+			V.sexStats.pills["pills"][setup.pills[item].name].autoTake = false; // disable auto takes for other similar pills(bottom/penis/breast etc)
 	}
-	window.syncAutoTakeDisplayedState()
+	window.syncAutoTakeDisplayedState();
 }
+window.onAutoTakeClick = onAutoTakeClick;
 
-window.syncAutoTakeDisplayedState = function() { // Add or remove [Auto] tag from pill names in the pills menu
-	for (let item of setup.pills){
-		let capitalized_name = item.name[0].toUpperCase() + item.name.slice(1)
-		if (document.getElementById("hpi_name_" + capitalized_name) != null){
-			document.getElementById("hpi_name_" + capitalized_name).innerHTML = capitalized_name
-			document.getElementById("hpi_name_" + capitalized_name).innerHTML += (item.autoTake() == true) ? `<span class="hpi_auto_label"> [Auto]</span>` : ""
+function syncAutoTakeDisplayedState() {
+	// Add or remove [Auto] tag from pill names in the pills menu
+	for (const item of setup.pills) {
+		const capitalisedName = item.name[0].toUpperCase() + item.name.slice(1);
+		if (document.getElementById("hpi_name_" + capitalisedName) != null) {
+			document.getElementById("hpi_name_" + capitalisedName).innerHTML = capitalisedName;
+			document.getElementById("hpi_name_" + capitalisedName).innerHTML +=
+				item.autoTake() === true ? "<span class='hpi_auto_label'> [Auto]</span>" : "";
 		}
 	}
 }
+window.syncAutoTakeDisplayedState = syncAutoTakeDisplayedState;
 
-window.onSecondDoseTakenSetVars = function() { // If player take two doses of anything but blocker/pregnancy/harper/asylum pills, determine the risk stat and
-	let doseTaken = {"bottom":0, "penis":0, "breast":0}
-	let chosen;
-	let doseTaken_sum;
+function onSecondDoseTakenSetVars() {
+	// If player take two doses of anything but blocker/pregnancy/harper/asylum pills, determine the risk stat and
+	let doseTaken = { bottom: 0, penis: 0, breast: 0 };
 
 	T.risk = 0;
 	T.pillAmountOfCategoriesUsed = 0;
-	for (let item of setup.pills){ // determine how many pills of each have been taken.
-		if (["bottom", "penis", "breast"].contains(item.type))
-			doseTaken[item.type] += item.doseTaken()
+	for (const item of setup.pills) {
+		// determine how many pills of each have been taken.
+		if (["bottom", "penis", "breast"].contains(item.type)) doseTaken[item.type] += item.doseTaken();
 	}
 	const sumValues = obj => Object.values(obj).reduce((a, b) => a + b); // count every doses
-	let i = -1
-	doseTaken_sum = sumValues(doseTaken) // store the count in this variable
-	while (++i < doseTaken_sum) // for each dose count, increase the overall risk.
-		T.risk += window.getRandomIntInclusive(3,10) // For each dose found, add 3-10 risk points.
-	doseTaken = [["bottom", doseTaken["bottom"]], ["penis", doseTaken["penis"]], ["breast", doseTaken["breast"]]] // Changed object to array as it's easier to sort.
-	for (let array of doseTaken){
-		if (array[1] > 0)
-			T.pillAmountOfCategoriesUsed += 1 // How many different categories of pills we took ?
+	let i = -1;
+	const doseTakenSum = sumValues(doseTaken); // store the count in this variable
+	while (++i < doseTakenSum)
+		// for each dose count, increase the overall risk.
+		T.risk += random(3, 10); // For each dose found, add 3-10 risk points.
+	doseTaken = [
+		["bottom", doseTaken["bottom"]],
+		["penis", doseTaken["penis"]],
+		["breast", doseTaken["breast"]],
+	]; // Changed object to array as it's easier to sort.
+	for (const array of doseTaken) {
+		if (array[1] > 0) T.pillAmountOfCategoriesUsed += 1; // How many different categories of pills we took ?
 	}
 	i = -1;
-	while (++i < doseTaken.length - 1){ // sort categories that got the most doses
-		if (doseTaken[i][1] < doseTaken[i + 1][1]){
-			let tmp = doseTaken[i];
+	while (++i < doseTaken.length - 1) {
+		// sort categories that got the most doses
+		if (doseTaken[i][1] < doseTaken[i + 1][1]) {
+			const tmp = doseTaken[i];
 
-			doseTaken[i] = doseTaken[i + 1]
+			doseTaken[i] = doseTaken[i + 1];
 			doseTaken[i + 1] = tmp;
-			i = -1
+			i = -1;
 		}
 	}
-	i = (doseTaken[0][1] > doseTaken[1][1]) ? 1 : (doseTaken[0][1] == doseTaken[1][1]) ? 2 : (doseTaken[0][1] == doseTaken[2][1]) ? 3 : 1 // determine how many have same value
-	chosen = window.getRandomIntInclusive(0, i-1);
-	V.pillCat = doseTaken[chosen][0] // select random category among the 1st ones
-	T.secondaryPill = (chosen > 0) ? doseTaken[chosen-1][0] : doseTaken[chosen+1][0] // select second category
-}
-
-window.getRandomIntInclusive = function(min, max) { // return a random number between min max, both included.
-	min = Math.ceil(min);
-	max = Math.floor(max);
-	return Math.floor(Math.random() * (max - min +1)) + min;
+	i = doseTaken[0][1] > doseTaken[1][1] ? 1 : doseTaken[0][1] === doseTaken[1][1] ? 2 : doseTaken[0][1] === doseTaken[2][1] ? 3 : 1; // determine how many have same value
+	const chosen = random(0, i - 1);
+	V.pillCat = doseTaken[chosen][0]; // select random category among the 1st ones
+	T.secondaryPill = chosen > 0 ? doseTaken[chosen - 1][0] : doseTaken[chosen + 1][0]; // select second category
 }
+window.onSecondDoseTakenSetVars = onSecondDoseTakenSetVars;
 
-window.backCompPillsInventory = function() {
+function backCompPillsInventory() {
 	/* Return immediately if $sexStats doesn't exist. */
-	if (typeof V.sexStats == 'undefined') return;
+	if (typeof V.sexStats === "undefined") return;
 	const oPills = V.sexStats.pills;
 	const pills = {};
-	if (typeof oPills === 'object') {
+	if (typeof oPills === "object") {
 		/* If our $sexStats.pills is an object and has this property, it is ready for production. */
-		if (oPills.hasOwnProperty('mostTaken')) return;
+		if (oPills.hasOwnProperty("mostTaken")) return;
 		try {
 			pillsObjectRepair(oPills, pills);
 		} catch (error) {
-			Errors.report('Compatibility patch for pills object failed: ' + error, { oPills, pills });
+			Errors.report("Compatibility patch for pills object failed: " + error, { oPills, pills });
 		}
 	}
 	Object.assign(pills, {
-		'bottom reduction' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'bottom growth' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'bottom blocker' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'breast reduction' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'breast growth' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'breast blocker' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'penis reduction' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'penis growth' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'penis blocker' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'fertility booster' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		'contraceptive' : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		"asylum's prescription" : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
-		"Dr Harper's prescription" : { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 }
+		"bottom reduction": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"bottom growth": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"bottom blocker": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"breast reduction": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"breast growth": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"breast blocker": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"penis reduction": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"penis growth": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"penis blocker": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"fertility booster": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		contraceptive: { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"asylum's prescription": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
+		"Dr Harper's prescription": { autoTake: false, doseTaken: 0, owned: 0, overdose: 0 },
 	});
-	if (typeof oPills === 'undefined') {
+	if (typeof oPills === "undefined") {
 		/* If our $sexStats.pills was empty, simply set the object in preparation to assign. */
 		V.sexStats.pills = {};
 	}
 	Object.assign(V.sexStats.pills, {
-		"boughtOnce": pills.boughtOnce == true,
-		"lastTaken" : { "bottom":'', "breast":'', "penis":'', "pregnancy":'' },
-		"mostTaken" : { "bottom":'', "breast":'', "penis":'', "pregnancy":''},
-		"pills" : pills,
+		boughtOnce: pills.boughtOnce === true,
+		lastTaken: { bottom: "", breast: "", penis: "", pregnancy: "" },
+		mostTaken: { bottom: "", breast: "", penis: "", pregnancy: "" },
+		pills,
 	});
 }
+window.backCompPillsInventory = backCompPillsInventory;
 
 function pillsObjectRepair(oPills, pills) {
 	/* if the variable already exist, and is not of the new version(new version has "mostTaken" property that's why we check it),
 	then we try to  port the old one to the new one */
-	if (typeof oPills.bottom === 'object') {
+	if (typeof oPills.bottom === "object") {
 		Object.assign(pills, {
-			'bottom reduction' : { autoTake: oPills.bottom.autoTake === "reduction", owned: oPills.bottom.owned.reduction },
-			'bottom growth' : { autoTake: oPills.bottom.autoTake === "growth", owned: oPills.bottom.owned.growth },
-			'bottom blocker' : { autoTake: oPills.bottom.autoTake === "blocker", owned: oPills.bottom.owned.blocker }
+			"bottom reduction": { autoTake: oPills.bottom.autoTake === "reduction", owned: oPills.bottom.owned.reduction },
+			"bottom growth": { autoTake: oPills.bottom.autoTake === "growth", owned: oPills.bottom.owned.growth },
+			"bottom blocker": { autoTake: oPills.bottom.autoTake === "blocker", owned: oPills.bottom.owned.blocker },
 		});
 		delete oPills.bottom;
 	}
-	if (typeof oPills.breast === 'object') {
+	if (typeof oPills.breast === "object") {
 		Object.assign(pills, {
-			'breast reduction' : { autoTake: oPills.breast.autoTake === "reduction", owned: oPills.breast.owned.reduction },
-			'breast growth' : { autoTake: oPills.breast.autoTake === "growth", owned: oPills.breast.owned.growth },
-			'breast blocker' : { autoTake: oPills.breast.autoTake === "blocker", owned: oPills.breast.owned.blocker }
+			"breast reduction": { autoTake: oPills.breast.autoTake === "reduction", owned: oPills.breast.owned.reduction },
+			"breast growth": { autoTake: oPills.breast.autoTake === "growth", owned: oPills.breast.owned.growth },
+			"breast blocker": { autoTake: oPills.breast.autoTake === "blocker", owned: oPills.breast.owned.blocker },
 		});
 		delete oPills.breast;
 	}
-	if (typeof oPills.penis === 'object') {
+	if (typeof oPills.penis === "object") {
 		Object.assign(pills, {
-			'penis reduction' : { autoTake: oPills.penis.autoTake === "reduction", owned: oPills.penis.owned.reduction },
-			'penis growth' : { autoTake: oPills.penis.autoTake === "growth", owned: oPills.penis.owned.growth },
-			'penis blocker' : { autoTake: oPills.penis.autoTake === "blocker", owned: oPills.penis.owned.blocker }
+			"penis reduction": { autoTake: oPills.penis.autoTake === "reduction", owned: oPills.penis.owned.reduction },
+			"penis growth": { autoTake: oPills.penis.autoTake === "growth", owned: oPills.penis.owned.growth },
+			"penis blocker": { autoTake: oPills.penis.autoTake === "blocker", owned: oPills.penis.owned.blocker },
 		});
 		delete oPills.penis;
 	}
-	if (typeof V.asylumpills === 'number') {
+	if (typeof V.asylumpills === "number") {
 		Object.assign(pills, {
-			"asylum's prescription" : { owned: Number.isInteger(V.asylumpills) ? V.asylumpills : 0 }
+			"asylum's prescription": { owned: Number.isInteger(V.asylumpills) ? V.asylumpills : 0 },
 		});
 		delete V.asylumpills;
 	}
-	if (typeof V.pills === 'number') {
+	if (typeof V.pills === "number") {
 		Object.assign(pills, {
-			"Dr Harper's prescription" : { owned: Number.isInteger(V.pills) ? V.pills : 0 }
+			"Dr Harper's prescription": { owned: Number.isInteger(V.pills) ? V.pills : 0 },
 		});
 		delete V.pills;
 	}
 }
 
-window.determineAutoTakePill = function(category){
-	T.autoTakeDetermined = null
-	for (let pill of setup.pills){
-		if (pill.type == category && pill.autoTake() == true){
-			T.autoTakeDetermined = pill.name
-			return
+function determineAutoTakePill(category) {
+	T.autoTakeDetermined = null;
+	for (const pill of setup.pills) {
+		if (pill.type === category && pill.autoTake() === true) {
+			T.autoTakeDetermined = pill.name;
+			return;
 		}
 	}
 }
+window.determineAutoTakePill = determineAutoTakePill;
 
-window.resetAllDoseTaken = function() {
-		for (let pill in V.sexStats.pills["pills"])
-			V.sexStats.pills["pills"][pill].doseTaken = 0
+function resetAllDoseTaken() {
+	for (const pill in V.sexStats.pills["pills"]) V.sexStats.pills["pills"][pill].doseTaken = 0;
 }
+window.resetAllDoseTaken = resetAllDoseTaken;
 
-window.resetLastTaken = function () {
-	V.sexStats.pills.lastTaken = {"bottom":'', "breast":'', "penis":'', "pregnancy":''}
+function resetLastTaken() {
+	V.sexStats.pills.lastTaken = { bottom: "", breast: "", penis: "", pregnancy: "" };
 }
+window.resetLastTaken = resetLastTaken;
 
-window.resetMostTaken = function() {
-	V.sexStats.pills.mostTaken = {"bottom":'', "breast":'', "penis":'', "pregnancy":''}
+function resetMostTaken() {
+	V.sexStats.pills.mostTaken = { bottom: "", breast: "", penis: "", pregnancy: "" };
 }
+window.resetMostTaken = resetMostTaken;
 
-window.getAllPills = function () {
-	for (let item of Object.keys(V.sexStats.pills.pills))
-		V.sexStats.pills.pills[item].owned = 14
+function getAllPills() {
+	for (const item of Object.keys(V.sexStats.pills.pills)) V.sexStats.pills.pills[item].owned = 14;
 }
+window.getAllPills = getAllPills;
diff --git a/game/03-JavaScript/canvasmodel.js b/game/03-JavaScript/canvasmodel.js
index 4e5abaec34..53a63c41a8 100644
--- a/game/03-JavaScript/canvasmodel.js
+++ b/game/03-JavaScript/canvasmodel.js
@@ -361,3 +361,19 @@ Renderer.locateModel = function (modelName, slot) {
 		return model;
 	}
 };
+
+/**
+ * Copies to targets keys from source that are not present there.
+ * Shallow.
+ *
+ * @param {object} target Object to extend.
+ * @param {object} source Default properties.
+ * @returns {object} Target.
+ */
+function assignDefaults(target, source) {
+	for (const k in source) {
+		if (!source.hasOwnProperty(k)) continue;
+		if (!(k in target)) target[k] = source[k];
+	}
+	return target;
+}
diff --git a/game/03-JavaScript/clothing-shop-v2.js b/game/03-JavaScript/clothing-shop-v2.js
index 290692b478..597b885f5d 100644
--- a/game/03-JavaScript/clothing-shop-v2.js
+++ b/game/03-JavaScript/clothing-shop-v2.js
@@ -1,76 +1,63 @@
-window.getIntegrityInfo = function (integrity) {
-	if (integrity >= 900)
-		return [7, "green"];
-	if (integrity >= 500)
-		return [6, "teal"];
-	if (integrity >= 200)
-		return [5, "lblue"];
-	if (integrity >= 100)
-		return [4, "blue"];
-	if (integrity >= 50)
-		return [3, "purple"];
-	if (integrity >= 20)
-		return [2, "pink"];
+function getIntegrityInfo(integrity) {
+	if (integrity >= 900) return [7, "green"];
+	if (integrity >= 500) return [6, "teal"];
+	if (integrity >= 200) return [5, "lblue"];
+	if (integrity >= 100) return [4, "blue"];
+	if (integrity >= 50) return [3, "purple"];
+	if (integrity >= 20) return [2, "pink"];
 	return [1, "red"];
 }
-
-window.getRevealInfo = function (reveal) {
-	if (reveal >= 900)
-		return [7, "red"];
-	if (reveal >= 700)
-		return [6, "pink"];
-	if (reveal >= 500)
-		return [5, "purple"];
-	if (reveal >= 300)
-		return [4, "blue"];
-	if (reveal >= 200)
-		return [3, "lblue"];
-	if (reveal >= 100)
-		return [2, "teal"];
+window.getIntegrityInfo = getIntegrityInfo;
+
+function getRevealInfo(reveal) {
+	if (reveal >= 900) return [7, "red"];
+	if (reveal >= 700) return [6, "pink"];
+	if (reveal >= 500) return [5, "purple"];
+	if (reveal >= 300) return [4, "blue"];
+	if (reveal >= 200) return [3, "lblue"];
+	if (reveal >= 100) return [2, "teal"];
 	return [1, "green"];
 }
+window.getRevealInfo = getRevealInfo;
 
-window.getWarmthInfo = function (warmth) {
-	if (warmth >= 75)
-		return [5, "warm-4"];
-	if (warmth >= 50)
-		return [4, "warm-3"];
-	if (warmth >= 25)
-		return [3, "warm-2"];
-	if (warmth >= 10)
-		return [2, "warm-1"];
+function getWarmthInfo(warmth) {
+	if (warmth >= 75) return [5, "warm-4"];
+	if (warmth >= 50) return [4, "warm-3"];
+	if (warmth >= 25) return [3, "warm-2"];
+	if (warmth >= 10) return [2, "warm-1"];
 	return [1, "warm-0"];
 }
+window.getWarmthInfo = getWarmthInfo;
 
 // for outfits it adds the lower piece's warmth too
-window.getTrueWarmth = function (item) {
+function getTrueWarmth(item) {
 	let warmth = item.warmth || 0;
 
 	if (item.outfitPrimary) {
 		// sum of warmth of every secondary piece
 		// outfitPrimary looks like this {'lower': 'item_name', 'head': 'item_name'}
 		warmth += Object.keys(item.outfitPrimary) // loop through secondary items list
-		.filter(x => item.outfitPrimary[x] != "broken") // filter out broken pieces
-		.map(x => setup.clothes[x].find(z => z.name == item.outfitPrimary[x] && z.modder === item.modder)) // find items in setup.clothes
-		.reduce((sum, x) => sum + (x.warmth || 0), 0); // calculate sum of their warmth field
+			.filter(x => item.outfitPrimary[x] !== "broken") // filter out broken pieces
+			.map(x => setup.clothes[x].find(z => z.name === item.outfitPrimary[x] && z.modder === item.modder)) // find items in setup.clothes
+			.reduce((sum, x) => sum + (x.warmth || 0), 0); // calculate sum of their warmth field
 	}
 
 	if (item.outfitSecondary) {
-		if (item.outfitSecondary.length % 2 != 0)
-			console.log("WARNING: " + item.name + " has bad .outfitSecondary data!");
+		if (item.outfitSecondary.length % 2 !== 0) console.log("WARNING: " + item.name + " has bad .outfitSecondary data!");
 
 		// outfitSecondary looks like this ['upper', 'item_name', 'head', 'item_name']
 		item.outfitSecondary.forEach((x, i) => {
-			if (i % 2 == 0 && item.outfitSecondary[i + 1] != "broken") {
-				warmth += setup.clothes[x].find(z => z.name == item.outfitSecondary[i + 1] && z.modder === item.modder).warmth || 0;
+			if (i % 2 === 0 && item.outfitSecondary[i + 1] !== "broken") {
+				warmth += setup.clothes[x].find(z => z.name === item.outfitSecondary[i + 1] && z.modder === item.modder).warmth || 0;
 			}
 		});
 	}
 
 	return warmth;
 }
+window.getTrueWarmth = getTrueWarmth;
 
-window.clothingSlotToIconName = function (slotName, outfits) {
+function clothingSlotToIconName(slotName, outfits) {
 	switch (slotName) {
 		case "over_upper":
 			return "overoutfit";
@@ -84,70 +71,108 @@ window.clothingSlotToIconName = function (slotName, outfits) {
 			return slotName;
 	}
 }
+window.clothingSlotToIconName = clothingSlotToIconName;
 
 // Make .divs-links clickable as if they're anchors
-window.linkifyDivs = function (parentSelector = "") {
-	$(document).ready(() => { $(parentSelector + " .div-link").click(function (e) { $(this).find('a').first().click(); }) });
-	$(document).ready(() => { $(parentSelector + " .div-link a").click(function (e) { e.stopPropagation(); }) });
+function linkifyDivs(parentSelector = "") {
+	$(() => {
+		$(parentSelector + " .div-link").click(function (e) {
+			$(this).find("a").first().click();
+		});
+	});
+	$(() => {
+		$(parentSelector + " .div-link a").click(function (e) {
+			e.stopPropagation();
+		});
+	});
 }
+window.linkifyDivs = linkifyDivs;
 
 // Hook custom colour sliders and preset dropdowns
-window.attachCustomColourHooks = function (slot = "") {
+function attachCustomColourHooks(slot = "") {
 	$(() => {
 		// throttling for smoother experience
 		let updating = false;
-		$('.custom-colour-sliders.primary input[type=range]').on('input change', ()=>{
+		$(".custom-colour-sliders.primary input[type=range]").on("input change", () => {
 			if (updating) return;
 			updating = true;
-			requestAnimationFrame(()=>{
+			requestAnimationFrame(() => {
 				updating = false;
-				updateCustomColour('primary', slot); updateMannequin(slot);
-			})
+				updateCustomColour("primary", slot);
+				updateMannequin(slot);
+			});
 		});
-		$('.custom-colour-sliders.secondary input[type=range]').on('input change', ()=>{
+		$(".custom-colour-sliders.secondary input[type=range]").on("input change", () => {
 			if (updating) return;
 			updating = true;
-			requestAnimationFrame(()=>{
+			requestAnimationFrame(() => {
 				updating = false;
-				updateCustomColour('secondary', slot); updateMannequin(slot);
-			})
+				updateCustomColour("secondary", slot);
+				updateMannequin(slot);
+			});
+		});
+		$(".custom-colour.primary > .custom-colour-presets > .presets-dropdown > select").on("change", () => {
+			loadCustomColourPreset("primary");
+			Wikifier.wikifyEval("<<updateclotheslist>>");
+		});
+		$(".custom-colour.secondary > .custom-colour-presets > .presets-dropdown > select").on("change", () => {
+			loadCustomColourPreset("secondary");
+			Wikifier.wikifyEval("<<updateclotheslist>>");
 		});
-		$('.custom-colour.primary > .custom-colour-presets > .presets-dropdown > select').on('change', () => { loadCustomColourPreset('primary'); new Wikifier(null, '<<updateclotheslist>>'); });
-		$('.custom-colour.secondary > .custom-colour-presets > .presets-dropdown > select').on('change', () => { loadCustomColourPreset('secondary'); new Wikifier(null, '<<updateclotheslist>>'); });
 
-		$('.custom-colour-sliders.primary > .colour-slider > div > input').on('input', (e) => { V.customColors.sepia.primary = 0; });
-		$('.custom-colour-sliders.secondary > .colour-slider > div > input').on('input', (e) => { V.customColors.sepia.secondary = 0; });
+		$(".custom-colour-sliders.primary > .colour-slider > div > input").on("input", e => {
+			V.customColors.sepia.primary = 0;
+		});
+		$(".custom-colour-sliders.secondary > .colour-slider > div > input").on("input", e => {
+			V.customColors.sepia.secondary = 0;
+		});
 	});
 }
+window.attachCustomColourHooks = attachCustomColourHooks;
 
-window.updateCustomColour = function(type, slot) {
-	$('.colour-options-div.' + type + ' > .colour-button > .bg-custom').css('filter', getCustomColourStyle(type, true));
-	let model = Renderer.locateModel("main", "shop");
+function updateCustomColour(type, slot) {
+	$(".colour-options-div." + type + " > .colour-button > .bg-custom").css("filter", getCustomColourStyle(type, true));
+	const model = Renderer.locateModel("main", "shop");
 	if (model) {
-		let customColors = V.customColors;
-		model.options.filters["worn_" + slot + (type === "primary" ? "_custom" : "_acc_custom")] =
-			getCustomClothesColourCanvasFilter(customColors.color[type],
-				customColors.saturation[type],
-				customColors.brightness[type],
-				customColors.contrast[type]);
+		const customColors = V.customColors;
+		model.options.filters["worn_" + slot + (type === "primary" ? "_custom" : "_acc_custom")] = getCustomClothesColourCanvasFilter(
+			customColors.color[type],
+			customColors.saturation[type],
+			customColors.brightness[type],
+			customColors.contrast[type]
+		);
 	}
 }
+window.updateCustomColour = updateCustomColour;
 
-window.updateMannequin = function(slot = "") {
-	new Wikifier(null, '<<updatemannequin "' + slot + '">>');
+function updateMannequin(slot = "") {
+	Wikifier.wikifyEval("<<updatemannequin '" + slot + "'>>");
 }
-
-window.getCustomColourStyle = function (type, valueOnly = false) {
-	if (type != 'primary' && type != 'secondary')
-		return;
-	return (valueOnly ? '' : 'filter: ') + 'hue-rotate(' + V.customColors.color[type] + 'deg) saturate(' + V.customColors.saturation[type] + ') brightness(' + V.customColors.brightness[type] + ') contrast(' + V.customColors.contrast[type] + ')' + (valueOnly ? '' : ';');
+window.updateMannequin = updateMannequin;
+
+function getCustomColourStyle(type, valueOnly = false) {
+	if (type !== "primary" && type !== "secondary") return;
+	return (
+		(valueOnly ? "" : "filter: ") +
+		"hue-rotate(" +
+		V.customColors.color[type] +
+		"deg) saturate(" +
+		V.customColors.saturation[type] +
+		") brightness(" +
+		V.customColors.brightness[type] +
+		") contrast(" +
+		V.customColors.contrast[type] +
+		")" +
+		(valueOnly ? "" : ";")
+	);
 }
+window.getCustomColourStyle = getCustomColourStyle;
 
-window.saveCustomColourPreset = function (slot = "primary") {
-	let setName = prompt("Enter new colour preset name", "New preset");
+function saveCustomColourPreset(slot = "primary") {
+	const setName = prompt("Enter new colour preset name", "New preset");
 	if (setName != null) {
 		if (Object.keys(V.customColors.presets).includes(setName)) {
-			alert('Preset "' + setName + '" already exists!');
+			alert("Preset '" + setName + "' already exists!");
 			return;
 		}
 
@@ -157,22 +182,25 @@ window.saveCustomColourPreset = function (slot = "primary") {
 			value: V.customColors.value[slot],
 			brightness: V.customColors.brightness[slot],
 			saturation: V.customColors.saturation[slot],
-			contrast: V.customColors.contrast[slot]
+			contrast: V.customColors.contrast[slot],
 		};
 	}
 }
+window.saveCustomColourPreset = saveCustomColourPreset;
+
+const colourPickerShopCustom = {};
 
-window.loadCustomColourPreset = function (slot = "primary") {
-	let setName = T.preset_choice[slot];
-	let preset = V.customColors.presets[setName];
+function loadCustomColourPreset(slot = "primary") {
+	const setName = T.preset_choice[slot];
+	const preset = V.customColors.presets[setName];
 	if (preset) {
 		// ver 3 includes property "value" which is used to set the position of the "value"(aka brightness) custom slider at shop, see here : https://i.imgur.com/hmbFT4U.png
-		if (preset.ver >= 3){
+		if (preset.ver >= 3) {
 			V.customColors.value[slot] = preset.value;
 			// this effectively set the different sliders values
-			colorPickerShopCustom[slot].color.hue = preset.color;
-			colorPickerShopCustom[slot].color.saturation = (((preset.saturation / 32) * 100) / 4) * 100;
-			colorPickerShopCustom[slot].color.value = preset.value;
+			colourPickerShopCustom[slot].color.hue = preset.color;
+			colourPickerShopCustom[slot].color.saturation = (((preset.saturation / 32) * 100) / 4) * 100;
+			colourPickerShopCustom[slot].color.value = preset.value;
 		}
 		// new version of preset (has only one set of colour parameters and doesn't have sepia)
 		if (preset.ver >= 2) {
@@ -198,88 +226,102 @@ window.loadCustomColourPreset = function (slot = "primary") {
 		}
 	}
 }
+window.loadCustomColourPreset = loadCustomColourPreset;
 
 // adjusts available options for reveal dropdowns (makes sure upper bound is not below lower bound and vice versa)
-window.getFilterRevealOptions = function (type) {
-	let optionsFrom = { unassuming: 0, smart: 100, tasteful: 200, comfy: 300, seductive: 500, risqué: 700, lewd: 900 };
-	let optionsTo = { unassuming: 100, smart: 200, tasteful: 300, comfy: 500, seductive: 700, risqué: 900, lewd: 9999 };
+function getFilterRevealOptions(type) {
+	const optionsFrom = { unassuming: 0, smart: 100, tasteful: 200, comfy: 300, seductive: 500, risqué: 700, lewd: 900 };
+	const optionsTo = { unassuming: 100, smart: 200, tasteful: 300, comfy: 500, seductive: 700, risqué: 900, lewd: 9999 };
 
-	if (type == 'from') {
+	if (type === "from") {
 		// this line removes values that are larger than reveal.to
-		return Object.keys(optionsFrom).filter(x => optionsFrom[x] < V.shopClothingFilter.reveal.to).reduce((res, key) => (res[key] = optionsFrom[key], res), {})
-	}
-	else {
+		return Object.keys(optionsFrom)
+			.filter(x => optionsFrom[x] < V.shopClothingFilter.reveal.to)
+			.reduce((res, key) => ((res[key] = optionsFrom[key]), res), {});
+	} else {
 		// this line removes values that are smaller than reveal.from
-		return Object.keys(optionsTo).filter(x => optionsTo[x] > V.shopClothingFilter.reveal.from).reduce((res, key) => (res[key] = optionsTo[key], res), {})
+		return Object.keys(optionsTo)
+			.filter(x => optionsTo[x] > V.shopClothingFilter.reveal.from)
+			.reduce((res, key) => ((res[key] = optionsTo[key]), res), {});
 	}
 }
+window.getFilterRevealOptions = getFilterRevealOptions;
 
 // toggles checkboxes in filters menu
-window.toggleAllTraitsFilter = function () {
-	let chboxes = $('#filter-traits input:not(:checked)');
-	if (chboxes.length > 0)
-		chboxes.click();
-	else
-		$('#filter-traits input:checked').click();
+function toggleAllTraitsFilter() {
+	const chboxes = $("#filter-traits input:not(:checked)");
+	if (chboxes.length > 0) chboxes.click();
+	else $("#filter-traits input:checked").click();
 }
+window.toggleAllTraitsFilter = toggleAllTraitsFilter;
 
 // accepts a list of clothes, returns a filtered list of clothes
-window.applyClothingShopFilters = function (items) {
-	let f = V.shopClothingFilter;
-	if (!f.active)
-		return items;
+function applyClothingShopFilters(items) {
+	const f = V.shopClothingFilter;
+	if (!f.active) return items;
 
 	// (example) turns f.gender object {female: true, neutral: true, male: false} into ["f", "n"], ready to compare with gender in items
-	let allowedGenders = Object.keys(f.gender).filter(x => f.gender[x]).map(x => x.first());
-
-	return items.filter(x => allowedGenders.includes(x.gender)
-		&& x.reveal >= f.reveal.from && x.reveal < f.reveal.to
-		&& x.warmth >= f.warmth.from && x.warmth < f.warmth.to
-		&& (f.traits.length == 0 || f.traits.includesAny(x.type))
+	const allowedGenders = Object.keys(f.gender)
+		.filter(x => f.gender[x])
+		.map(x => x.first());
+
+	return items.filter(
+		x =>
+			allowedGenders.includes(x.gender) &&
+			x.reveal >= f.reveal.from &&
+			x.reveal < f.reveal.to &&
+			x.warmth >= f.warmth.from &&
+			x.warmth < f.warmth.to &&
+			(f.traits.length === 0 || f.traits.includesAny(x.type))
 	);
 }
+window.applyClothingShopFilters = applyClothingShopFilters;
 
-window.getWarmthScaleData = function(newWarmth) {
+function getWarmthScaleData(newWarmth) {
 	let maxWarmth = Math.max(260, V.warmth * 1.04);
-	if (newWarmth)
-		maxWarmth = Math.max(maxWarmth, newWarmth * 1.04);
-	let chill = V.chill;
-	let cold = chill - 90;
-	let warm = chill * 1.3 + 70;
-	let hot = chill * 1.3 + 150;
-	let minW = Math.min(V.warmth, newWarmth);
-	let maxW = Math.max(V.warmth, newWarmth);
+	if (newWarmth) maxWarmth = Math.max(maxWarmth, newWarmth * 1.04);
+	const chill = V.chill;
+	const cold = chill - 90;
+	const warm = chill * 1.3 + 70;
+	const hot = chill * 1.3 + 150;
+	const minW = Math.min(V.warmth, newWarmth);
+	const maxW = Math.max(V.warmth, newWarmth);
 
 	return {
-		cold: cold / maxWarmth * 100 + '%',
-		chill: (chill - Math.max(cold, 0)) / maxWarmth * 100 + '%',
-		ok: (Math.min(warm, maxWarmth) - chill) / maxWarmth * 100 + '%',
-		warm: (Math.min(hot, maxWarmth) - Math.min(warm, maxWarmth)) / maxWarmth * 100 + '%',
-		hot: (maxWarmth - hot) / maxWarmth * 100 + '%',
-		nowarm: warm > maxWarmth ? 'nowarm' : '',
-		nohot: hot > maxWarmth ? 'nohot' : '',
-		nocold: cold < 0 ? 'nocold' : '',
-		player: V.warmth / maxWarmth * 100 + '%',
-		playerNew: (V.warmth > newWarmth ? minW : maxW) / maxWarmth * 100 + '%',
-		diffUpDown: (V.warmth > newWarmth ? 'down' : 'up'),
-		diffStart: minW / maxWarmth * 100 + '%',
-		diffWidth: (maxW - minW) / maxWarmth * 100 + '%'
+		cold: (cold / maxWarmth) * 100 + "%",
+		chill: ((chill - Math.max(cold, 0)) / maxWarmth) * 100 + "%",
+		ok: ((Math.min(warm, maxWarmth) - chill) / maxWarmth) * 100 + "%",
+		warm: ((Math.min(hot, maxWarmth) - Math.min(warm, maxWarmth)) / maxWarmth) * 100 + "%",
+		hot: ((maxWarmth - hot) / maxWarmth) * 100 + "%",
+		nowarm: warm > maxWarmth ? "nowarm" : "",
+		nohot: hot > maxWarmth ? "nohot" : "",
+		nocold: cold < 0 ? "nocold" : "",
+		player: (V.warmth / maxWarmth) * 100 + "%",
+		playerNew: ((V.warmth > newWarmth ? minW : maxW) / maxWarmth) * 100 + "%",
+		diffUpDown: V.warmth > newWarmth ? "down" : "up",
+		diffStart: (minW / maxWarmth) * 100 + "%",
+		diffWidth: ((maxW - minW) / maxWarmth) * 100 + "%",
 	};
 }
+window.getWarmthScaleData = getWarmthScaleData;
 
-window.getWarmthWithOtherClothing = function(slot, clothingId) {
-	let newClothing = setup.clothes[slot][clothingId];
-	let worn = V.worn;
+function getWarmthWithOtherClothing(slot, clothingId) {
+	const newClothing = setup.clothes[slot][clothingId];
+	const worn = V.worn;
 
 	let newWarmth = V.warmth + getTrueWarmth(newClothing);
 
 	// subtract warmth of all clothes that would be taken off
 	if (newClothing.outfitPrimary) {
-		//newWarmth -= Object.keys(newClothing.outfitPrimary).reduce((sum, x) => sum + (worn[x].warmth || 0), 0);
+		// newWarmth -= Object.keys(newClothing.outfitPrimary).reduce((sum, x) => sum + (worn[x].warmth || 0), 0);
 
 		// compile a list of all primary clothes to be removed. It implies that item may have only one primary piece
-		let clothesToRemove = [slot, ...Object.keys(newClothing.outfitPrimary)].map(x => (worn[x].outfitSecondary && worn[x].outfitSecondary[1] != "broken") ? setup.clothes[worn[x].outfitSecondary[0]].find(z => z.name == worn[x].outfitSecondary[1]) : worn[x])
-		let removedClothes = new Set();
+		const clothesToRemove = [slot, ...Object.keys(newClothing.outfitPrimary)].map(x =>
+			worn[x].outfitSecondary && worn[x].outfitSecondary[1] !== "broken"
+				? setup.clothes[worn[x].outfitSecondary[0]].find(z => z.name === worn[x].outfitSecondary[1])
+				: worn[x]
+		);
+		const removedClothes = new Set();
 
 		clothesToRemove.forEach(x => {
 			if (!removedClothes.has(x.name)) {
@@ -287,27 +329,28 @@ window.getWarmthWithOtherClothing = function(slot, clothingId) {
 				removedClothes.add(x.name);
 			}
 		});
-	}
-	else
-		newWarmth -= worn[slot].warmth;
+	} else newWarmth -= worn[slot].warmth;
 
 	return newWarmth;
 }
+window.getWarmthWithOtherClothing = getWarmthWithOtherClothing;
 
-window.allClothesSetup = function(){
-	let clothes = []
+function allClothesSetup() {
+	let clothes = [];
 	Object.keys(setup.clothes).forEach(slot => {
-		if(['all','over_head','over_upper','over_lower'].includes(slot)) return;
-		let items = clone(setup.clothes[slot]);
-		items.forEach(item => item.realSlot = slot);
+		if (["all", "over_head", "over_upper", "over_lower"].includes(slot)) return;
+		const items = clone(setup.clothes[slot]);
+		items.forEach(item => (item.realSlot = slot));
 		clothes = clothes.concat(items);
-	})
+	});
 	setup.clothes.all = clothes;
 }
+window.allClothesSetup = allClothesSetup;
 
-window.shopSearchReplacer = function(name){
-	return name.replace(/[^a-zA-Z0-9' -]+/g,"");
+function shopSearchReplacer(name) {
+	return name.replace(/[^a-zA-Z0-9' -]+/g, "");
 }
+window.shopSearchReplacer = shopSearchReplacer;
 
 function getOwnedClothingCount(index, type) {
 	const wardrobe = V.wardrobes.shopReturn === "wardrobe" ? V.wardrobe : V.wardrobes[V.wardrobes.shopReturn] || V.wardrobe;
@@ -315,118 +358,117 @@ function getOwnedClothingCount(index, type) {
 }
 window.getOwnedClothingCount = getOwnedClothingCount;
 
-var colorPickerShopCustom = {};
-
-window.importCustomColour = function (acc) {
+function importCustomColour(acc) {
 	const setName = prompt("Enter custom code", "");
 	if (setName != null) {
 		const color = JSON.parse(window.atob(setName));
-		const colour_properties = Object.getOwnPropertyNames(color);
+		const colourProperties = Object.getOwnPropertyNames(color);
 
-		if (colour_properties.sort().join(',')=== ["color", "saturation", "value", "brightness", "contrast"].sort().join(',')){
+		if (colourProperties.sort().join(",") === ["color", "saturation", "value", "brightness", "contrast"].sort().join(",")) {
 			V.customColors.color[acc] = color.color;
 			V.customColors.saturation[acc] = color.saturation;
 			V.customColors.value[acc] = color.value;
 			V.customColors.contrast[acc] = color.contrast;
 			V.customColors.brightness[acc] = color.brightness;
-			colorPickerShopCustom[acc].color.hue = color.color;
-			colorPickerShopCustom[acc].color.saturation = (((color.saturation / 32) * 100) / 4) * 100;
-			colorPickerShopCustom[acc].color.value = color.value;
+			colourPickerShopCustom[acc].color.hue = color.color;
+			colourPickerShopCustom[acc].color.saturation = (((color.saturation / 32) * 100) / 4) * 100;
+			colourPickerShopCustom[acc].color.value = color.value;
 			document.getElementById("numberslider-input-customcolorscontrastprimary").value = color.contrast.toString();
 			document.getElementById("numberslider-value-customcolorscontrastprimary").innerText = color.contrast.toString();
 			updateMannequin();
-		}
-		else
-			throw "Invalid code. Make sure you copied it properly, without any white spaces around it.";
+		} else throw "Invalid code. Make sure you copied it properly, without any white spaces around it.";
 	}
 }
-
-window.exportCustomColour = function (acc) {
-	const obj = {color:V.customColors.color[acc], saturation:V.customColors.saturation[acc], value:V.customColors.value[acc], brightness: V.customColors.brightness[acc], contrast:V.customColors.contrast[acc]}
+window.importCustomColour = importCustomColour;
+
+function exportCustomColour(acc) {
+	const obj = {
+		color: V.customColors.color[acc],
+		saturation: V.customColors.saturation[acc],
+		value: V.customColors.value[acc],
+		brightness: V.customColors.brightness[acc],
+		contrast: V.customColors.contrast[acc],
+	};
 
 	navigator.clipboard.writeText(window.btoa(JSON.stringify(obj)));
-	document.getElementById("export-custom-colour-box").outerHTML =`
+	document.getElementById("export-custom-colour-box").outerHTML = `
 	<div id="export-custom-colour-box">
 		<span class="export-custom-colour-alert">Copied to clipboard!</span>
 	</div>`;
-	window.setTimeout(function() {
+	window.setTimeout(() => {
 		if (document.getElementById("export-custom-colour-box"))
 			document.getElementById("export-custom-colour-box").classList.add("successfully-exported");
-	},100)
+	}, 100);
 }
-
-
-function adaptSliderWidth(){
-	if (window.innerWidth > 787)
-		return 400;
-	else if (window.innerWidth > 710)
-		return 350;	
-	else if (window.innerWidth > 667)
-		return 300;
-	else if (window.innerWidth > 600)
-		return 230;
-	else if (window.innerWidth > 519)
-		return 350;
-	else if (window.innerWidth > 463)
-		return 300;
-	else
-		return 250;
+window.exportCustomColour = exportCustomColour;
+
+function adaptSliderWidth() {
+	if (window.innerWidth > 787) return 400;
+	else if (window.innerWidth > 710) return 350;
+	else if (window.innerWidth > 667) return 300;
+	else if (window.innerWidth > 600) return 230;
+	else if (window.innerWidth > 519) return 350;
+	else if (window.innerWidth > 463) return 300;
+	else return 250;
 }
 
-window.shopClothCustomColorWheel = function(acc){
-		const container = document.createElement('label');
-		colorPickerShopCustom[acc] = new iro.ColorPicker(container, {
-			color: {h:61, s:47, v:100},
-			width: adaptSliderWidth(),
-			layout: [
-				  {
-					component: iro.ui.Slider,
-					options: {
-					  sliderType: 'hue'
-					}
-				  },
-				  {
-					component: iro.ui.Slider,
-					options: {
-					  sliderType: 'saturation'
-					}
-				  },
-				  {
-					component: iro.ui.Slider,
-					options: {
-					  sliderType: 'value'
-					}
-				  }
-			]
-		});
-		colorPickerShopCustom[acc].color.hue = V.customColors.color[acc];
-		colorPickerShopCustom[acc].color.saturation = (((V.customColors.saturation[acc] / 32) * 100) / 4) * 100;
-		colorPickerShopCustom[acc].color.value = V.customColors.value[acc];
-		//
-		colorPickerShopCustom[acc].on(['color:init', 'color:change'], function(color) {
-			V.customColors.color[acc] = Math.round(color.hue);
-			V.customColors.saturation[acc] = (((color.saturation * 32) / 100) * 4) / 100;
-			V.customColors.brightness[acc] = (color.hsl.l * 4) / 100;
-			V.customColors.value[acc] = color.value;
-			if (document.getElementById("mannequin"))
-				updateMannequin();
-		});
-		return container;
+function shopClothCustomColorWheel(acc) {
+	const container = document.createElement("label");
+	colourPickerShopCustom[acc] = new iro.ColorPicker(container, {
+		color: { h: 61, s: 47, v: 100 },
+		width: adaptSliderWidth(),
+		layout: [
+			{
+				component: iro.ui.Slider,
+				options: {
+					sliderType: "hue",
+				},
+			},
+			{
+				component: iro.ui.Slider,
+				options: {
+					sliderType: "saturation",
+				},
+			},
+			{
+				component: iro.ui.Slider,
+				options: {
+					sliderType: "value",
+				},
+			},
+		],
+	});
+	colourPickerShopCustom[acc].color.hue = V.customColors.color[acc];
+	colourPickerShopCustom[acc].color.saturation = (((V.customColors.saturation[acc] / 32) * 100) / 4) * 100;
+	colourPickerShopCustom[acc].color.value = V.customColors.value[acc];
+	//
+	colourPickerShopCustom[acc].on(["color:init", "color:change"], function (color) {
+		V.customColors.color[acc] = Math.round(color.hue);
+		V.customColors.saturation[acc] = (((color.saturation * 32) / 100) * 4) / 100;
+		V.customColors.brightness[acc] = (color.hsl.l * 4) / 100;
+		V.customColors.value[acc] = color.value;
+		if (document.getElementById("mannequin")) updateMannequin();
+	});
+	return container;
 }
+window.shopClothCustomColorWheel = shopClothCustomColorWheel;
 
-function updateHueSlider(new_value, acc){
-	colorPickerShopCustom[acc].color.hue = new_value;
+function updateHueSlider(newValue, acc) {
+	colourPickerShopCustom[acc].color.hue = newValue;
 }
-
 window.updateHueSlider = updateHueSlider;
 
-window.addEventListener('resize', function(event) {
-	for (let cat in colorPickerShopCustom){
-		colorPickerShopCustom[cat].resize(adaptSliderWidth());
-	}
-}, true);
+window.addEventListener(
+	"resize",
+	function (event) {
+		for (const cat in colourPickerShopCustom) {
+			colourPickerShopCustom[cat].resize(adaptSliderWidth());
+		}
+	},
+	true
+);
 
-Macro.add('shopclothingcustomcolourwheel', {
+Macro.add("shopclothingcustomcolourwheel", {
 	handler() {
 		if (this.args[0]){
 			const resp = shopClothCustomColorWheel(this.args[0], this.args[1]);
@@ -435,4 +477,4 @@ Macro.add('shopclothingcustomcolourwheel', {
 	}
 });
 
-window.colorPickerShopCustom = colorPickerShopCustom;
+window.colourPickerShopCustom = colourPickerShopCustom;
diff --git a/game/03-JavaScript/debugMenu.js b/game/03-JavaScript/debugMenu.js
index c59e55f2ef..d9f00adf49 100644
--- a/game/03-JavaScript/debugMenu.js
+++ b/game/03-JavaScript/debugMenu.js
@@ -4,508 +4,266 @@ const stayOnPassageFn = function () {
 };
 
 setup.debugMenu = {
-	cacheDebugDiv: {}
+	cacheDebugDiv: {},
 };
 
-setup.debugMenu.event_list = {
-	Main:[
+setup.debugMenu.eventList = {
+	Main: [
 		{
-			link: [
-				`test`, `Test`
-			],
-			widgets: [
-				`<<set $molestationstart to 0>>`
-			]
+			link: [`test`, `Test`],
+			widgets: [`<<set $molestationstart to 0>>`],
 		},
 		{
-			link: [
-				`CanvasModel Example`, `CanvasModel Example`
-			],
-			widgets: [
-				``
-			]
+			link: [`CanvasModel Example`, `CanvasModel Example`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Home`, `Bedroom`
-			],
-			widgets: [
-				`<<endcombat>>`
-			]
+			link: [`Home`, `Bedroom`],
+			widgets: [`<<endcombat>>`],
 		},
 		{
-			link: [
-				`Wardrobe`, `Wardrobe`
-			],
-			widgets: [
-				``
-			]
+			link: [`Wardrobe`, `Wardrobe`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Strip`, stayOnPassageFn
-			],
-			widgets: [
-				`<<undressclothes "wardrobe">>`
-			]
+			link: [`Strip`, stayOnPassageFn],
+			widgets: [`<<undressclothes "wardrobe">>`],
 		},
 		{
-			link: [
-				`Strip to undies`, stayOnPassageFn
-			],
+			link: [`Strip to undies`, stayOnPassageFn],
 			widgets: [
 				`<<generalUndress wardrobe over_upper>>`,
 				`<<generalUndress wardrobe over_lower>>`,
 				`<<generalUndress wardrobe upper>>`,
-				`<<generalUndress wardrobe lower>>`
-			]
+				`<<generalUndress wardrobe lower>>`,
+			],
 		},
 		{
-			link: [
-				`Strip all`, stayOnPassageFn
-			],
-			widgets: [
-				`<<undress "wardrobe">>`
-			]
+			link: [`Strip all`, stayOnPassageFn],
+			widgets: [`<<undress "wardrobe">>`],
 		},
 		{
-			link: [
-				`Pass 1 minute`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 1>>`
-			]
+			link: [`Pass 1 minute`, stayOnPassageFn],
+			widgets: [`<<pass 1>>`],
 		},
 		{
-			link: [
-				`Pass 15 minutes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 15>>`
-			]
+			link: [`Pass 15 minutes`, stayOnPassageFn],
+			widgets: [`<<pass 15>>`],
 		},
 		{
-			link: [
-				`Pass 20 minutes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 20>>`
-			]
+			link: [`Pass 20 minutes`, stayOnPassageFn],
+			widgets: [`<<pass 20>>`],
 		},
 		{
-			link: [
-				`Pass 1 hour`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 60>>`
-			]
+			link: [`Pass 1 hour`, stayOnPassageFn],
+			widgets: [`<<pass 60>>`],
 		},
 		{
-			link: [
-				`Pass 3 hours`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 3 hours>>`
-			]
+			link: [`Pass 3 hours`, stayOnPassageFn],
+			widgets: [`<<pass 3 hours>>`],
 		},
 		{
-			link: [
-				`Pass 6 hours`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 6 hours>>`
-			]
+			link: [`Pass 6 hours`, stayOnPassageFn],
+			widgets: [`<<pass 6 hours>>`],
 		},
 		{
-			link: [
-				`Pass 12 hours`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 12 hours>>`
-			]
+			link: [`Pass 12 hours`, stayOnPassageFn],
+			widgets: [`<<pass 12 hours>>`],
 		},
 		{
-			link: [
-				`Pass 18 hours`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 18 hours>>`
-			]
+			link: [`Pass 18 hours`, stayOnPassageFn],
+			widgets: [`<<pass 18 hours>>`],
 		},
 		{
-			link: [
-				`Pass 23 hours`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 23 hours>>`
-			]
+			link: [`Pass 23 hours`, stayOnPassageFn],
+			widgets: [`<<pass 23 hours>>`],
 		},
 		{
-			link: [
-				`Pass 24 hours`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pass 24 hours>>`
-			]
+			link: [`Pass 24 hours`, stayOnPassageFn],
+			widgets: [`<<pass 24 hours>>`],
 		},
 		{
-			link: [
-				`Enemy Trust +++`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $enemytrust += 2000>>`,
-				`<<set $enemyanger -= 1000>>`
-			]
+			link: [`Enemy Trust +++`, stayOnPassageFn],
+			widgets: [`<<set $enemytrust += 2000>>`, `<<set $enemyanger -= 1000>>`],
 		},
 		{
-			link: [
-				`Enemy Trust ---`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $enemytrust -= 2000>>`,
-				`<<set $enemyanger += 1000>>`
-			]
+			link: [`Enemy Trust ---`, stayOnPassageFn],
+			widgets: [`<<set $enemytrust -= 2000>>`, `<<set $enemyanger += 1000>>`],
 		},
 		{
-			link: [
-				`Super Punch`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $enemyhealth to 0>>`
-			]
+			link: [`Super Punch`, stayOnPassageFn],
+			widgets: [`<<set $enemyhealth to 0>>`],
 		},
 		{
-			link: [
-				`Super Stroke`, stayOnPassageFn
-			],
-			widgets: [
-				function(){return (`<<set $enemyarousal to ` + V.enemyarousalmax + `>>`)}
-			]
+			link: [`Super Stroke`, stayOnPassageFn],
+			widgets: [() => `<<set $enemyarousal to ` + V.enemyarousalmax + `>>`],
 		},
 		{
-			link: [
-				`Scream`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $alarm to 1>>`
-			]
+			link: [`Scream`, stayOnPassageFn],
+			widgets: [`<<set $alarm to 1>>`],
 		},
 		{
-			link: [
-				`Finish Var (doesn't always work)`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $finish to 1>>`
-			]
+			link: [`Finish Var (doesn't always work)`, stayOnPassageFn],
+			widgets: [`<<set $finish to 1>>`],
 		},
 		{
-			link: [
-				`Make Rape`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $consensual to 0>>`
-			]
+			link: [`Make Rape`, stayOnPassageFn],
+			widgets: [`<<set $consensual to 0>>`],
 		},
 		{
-			link: [
-				`Make Consensual`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $consensual to 1>>`
-			]
+			link: [`Make Consensual`, stayOnPassageFn],
+			widgets: [`<<set $consensual to 1>>`],
 		},
 		{
-			link: [
-				`Enemy Arousal ---`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $enemyarousal to 0>>`
-			]
+			link: [`Enemy Arousal ---`, stayOnPassageFn],
+			widgets: [`<<set $enemyarousal to 0>>`],
 		},
 		{
-			link: [
-				`Roll Over`, stayOnPassageFn
-			],
-			widgets: [
-				function(){return (`<<set $position to ` + (V.position == "doggy" ? "doggy" : "missionary") + `>>`)}
-			],
-			condition: function (){return (V.position == "doggy" || V.position == "missionary") ? 1 : 0}
+			link: [`Roll Over`, stayOnPassageFn],
+			widgets: [() => `<<set $position to ` + (V.position === "doggy" ? "doggy" : "missionary") + `>>`],
+			condition: () => (V.position === "doggy" || V.position === "missionary" ? 1 : 0),
 		},
 		{
-			link: [
-				`RNG 1`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 1>>`
-			]
+			link: [`RNG 1`, stayOnPassageFn],
+			widgets: [`<<set $rng to 1>>`],
 		},
 		{
-			link: [
-				`RNG 11`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 11>>`
-			]
+			link: [`RNG 11`, stayOnPassageFn],
+			widgets: [`<<set $rng to 11>>`],
 		},
 		{
-			link: [
-				`RNG 21`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 21>>`
-			]
+			link: [`RNG 21`, stayOnPassageFn],
+			widgets: [`<<set $rng to 21>>`],
 		},
 		{
-			link: [
-				`RNG 31`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 31>>`
-			]
+			link: [`RNG 31`, stayOnPassageFn],
+			widgets: [`<<set $rng to 31>>`],
 		},
 		{
-			link: [
-				`RNG 41`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 41>>`
-			]
+			link: [`RNG 41`, stayOnPassageFn],
+			widgets: [`<<set $rng to 41>>`],
 		},
 		{
-			link: [
-				`RNG 51`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 51>>`
-			]
+			link: [`RNG 51`, stayOnPassageFn],
+			widgets: [`<<set $rng to 51>>`],
 		},
 		{
-			link: [
-				`RNG 61`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 61>>`
-			]
+			link: [`RNG 61`, stayOnPassageFn],
+			widgets: [`<<set $rng to 61>>`],
 		},
 		{
-			link: [
-				`RNG 71`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 71>>`
-			]
+			link: [`RNG 71`, stayOnPassageFn],
+			widgets: [`<<set $rng to 71>>`],
 		},
 		{
-			link: [
-				`RNG 81`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 81>>`
-			]
+			link: [`RNG 81`, stayOnPassageFn],
+			widgets: [`<<set $rng to 81>>`],
 		},
 		{
-			link: [
-				`RNG 91`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to 91>>`
-			]
+			link: [`RNG 91`, stayOnPassageFn],
+			widgets: [`<<set $rng to 91>>`],
 		},
 		{
-			link: [
-				`RNG reroll x1`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $rng to random(1,100)>>`
-			]
+			link: [`RNG reroll x1`, stayOnPassageFn],
+			widgets: [`<<set $rng to random(1,100)>>`],
 		},
 		{
-			link: [
-				`RNG reroll x3`, stayOnPassageFn
-			],
-			widgets: [
-				`<<run random(1,100)>>`,
-				`<<run random(1,100)>>`,
-				`<<set $rng to random(1,100)>>`
-			]
+			link: [`RNG reroll x3`, stayOnPassageFn],
+			widgets: [`<<run random(1,100)>>`, `<<run random(1,100)>>`, `<<set $rng to random(1,100)>>`],
 		},
 		{
-			link: [
-				`RNG reroll x5`, stayOnPassageFn
-			],
+			link: [`RNG reroll x5`, stayOnPassageFn],
 			widgets: [
 				`<<run random(1,100)>>`,
 				`<<run random(1,100)>>`,
 				`<<run random(1,100)>>`,
 				`<<run random(1,100)>>`,
-				`<<set $rng to random(1,100)>>`
-			]
+				`<<set $rng to random(1,100)>>`,
+			],
 		},
 		{
-			link: [
-				`Wear sundress`, stayOnPassageFn
-			],
-			widgets: [
-				`<<upperwear 1>>`
-			]
+			link: [`Wear sundress`, stayOnPassageFn],
+			widgets: [`<<upperwear 1>>`],
 		},
 		{
-			link: [
-				`Wear swimsuit`, stayOnPassageFn
-			],
-			widgets: [
-				`<<underlowerwear 6>>`
-			]
+			link: [`Wear swimsuit`, stayOnPassageFn],
+			widgets: [`<<underlowerwear 6>>`],
 		},
 		{
-			link: [
-				`Testing Room`, `Testing Room`
-			],
-			widgets: [
-				`<<upperstrip>>`,
-				`<<lowerstrip>>`,
-				`<<underlowerstrip>>`
-			]
+			link: [`Testing Room`, `Testing Room`],
+			widgets: [`<<upperstrip>>`, `<<lowerstrip>>`, `<<underlowerstrip>>`],
 		},
 		{
-			link: [
-				`End Event`, stayOnPassageFn
-			],
-			widgets: [
-				`<<endevent>>`
-			]
+			link: [`End Event`, stayOnPassageFn],
+			widgets: [`<<endevent>>`],
 		},
 		{
-			link: [
-				`Escape Vore`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $vorestage to 0>>`
-			]
+			link: [`Escape Vore`, stayOnPassageFn],
+			widgets: [`<<set $vorestage to 0>>`],
 		},
 		{
-			text_only: `\n`
+			text_only: `\n`,
 		},
 		{
-			link: [
-				`Make all beasts male`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $monsterchance to 0>>`,
-				`<<set $beastmalechance to 100>>`
-			]
+			link: [`Make all beasts male`, stayOnPassageFn],
+			widgets: [`<<set $monsterchance to 0>>`, `<<set $beastmalechance to 100>>`],
 		},
 		{
-			link: [
-				`Make all beasts female`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $monsterchance to 0>>`,
-				`<<set $beastmalechance to 0>>`
-			]
+			link: [`Make all beasts female`, stayOnPassageFn],
+			widgets: [`<<set $monsterchance to 0>>`, `<<set $beastmalechance to 0>>`],
 		},
 		{
-			link: [
-				`Make all beasts cuntboys`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $beastmalechance to 100>>`,
-				`<<set $cbchance to 100>>`
-			]
+			link: [`Make all beasts cuntboys`, stayOnPassageFn],
+			widgets: [`<<set $beastmalechance to 100>>`, `<<set $cbchance to 100>>`],
 		},
 		{
-			link: [
-				`Make all beasts dickgirls`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $beastmalechance to 0>>`,
-				`<<set $dgchance to 100>>`
-			]
+			link: [`Make all beasts dickgirls`, stayOnPassageFn],
+			widgets: [`<<set $beastmalechance to 0>>`, `<<set $dgchance to 100>>`],
 		},
 		{
-			link: [
-				`Make all beasts monster people`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $monsterchance to 100>>`,
-				`<<set $monsterhallucinations to "f">>`
-			]
+			link: [`Make all beasts monster people`, stayOnPassageFn],
+			widgets: [`<<set $monsterchance to 100>>`, `<<set $monsterhallucinations to "f">>`],
 		},
 		{
-			text_only: `\n`
+			text_only: `\n`,
 		},
 		{
-			link: [
-				`Spring`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $season to "spring">>`
-			]
+			link: [`Spring`, stayOnPassageFn],
+			widgets: [`<<set $season to "spring">>`],
 		},
 		{
-			link: [
-				`Summer`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $season to "summer">>`
-			]
+			link: [`Summer`, stayOnPassageFn],
+			widgets: [`<<set $season to "summer">>`],
 		},
 		{
-			link: [
-				`Autumn`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $season to "autumn">>`
-			]
+			link: [`Autumn`, stayOnPassageFn],
+			widgets: [`<<set $season to "autumn">>`],
 		},
 		{
-			link: [
-				`Winter`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $season to "winter">>`
-			]
+			link: [`Winter`, stayOnPassageFn],
+			widgets: [`<<set $season to "winter">>`],
 		},
 		{
-			text_only: `\n`
+			text_only: `\n`,
 		},
 		{
-			link: [
-				`Enable basic Pregnancy features`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $sexStats.anus.pregnancy.seenDoctor to 2>>`,
-				`<<set $sexStats.anus.pregnancy.maxCount to 2>>`
-			]
+			link: [`Enable basic Pregnancy features`, stayOnPassageFn],
+			widgets: [`<<set $sexStats.anus.pregnancy.seenDoctor to 2>>`, `<<set $sexStats.anus.pregnancy.maxCount to 2>>`],
 		},
 		{
-			link: [
-				`Get Initial Mother Trait`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $sexStats.anus.pregnancy.motherStatus to 1>>`
-			]
+			link: [`Get Initial Mother Trait`, stayOnPassageFn],
+			widgets: [`<<set $sexStats.anus.pregnancy.motherStatus to 1>>`],
 		},
 		{
-			link: [
-				`Fertilise New Eggs`, stayOnPassageFn
-			],
-			widgets: [
-				`<<fertilise>>`
-			]
+			link: [`Fertilise New Eggs`, stayOnPassageFn],
+			widgets: [`<<fertilise>>`],
 		},
 		{
-			link: [
-				`Pregnancy Progress Day`, stayOnPassageFn
-			],
-			widgets: [
-				`<<pregProgressDay>>`
-			]
+			link: [`Pregnancy Progress Day`, stayOnPassageFn],
+			widgets: [`<<pregProgressDay>>`],
 		},
 		{
-			link: [
-				`Pregnancy Progress Week`, stayOnPassageFn
-			],
+			link: [`Pregnancy Progress Week`, stayOnPassageFn],
 			widgets: [
 				`<<pregProgressDay>>`,
 				`<<pregProgressDay>>`,
@@ -514,269 +272,156 @@ setup.debugMenu.event_list = {
 				`<<pregProgressDay>>`,
 				`<<pregProgressDay>>`,
 				`<<pregProgressDay>>`,
-				`<<pregProgressDay>>`
-			]
+				`<<pregProgressDay>>`,
+			],
 		},
 		{
-			link: [
-				function(){return `Set all pregnancy events to next ` + V.pass}, stayOnPassageFn
-			],
+			link: [() => `Set all pregnancy events to next ` + V.pass, stayOnPassageFn],
 			widgets: [
 				`<<set _pregnancy to $sexStats.anus.pregnancy>>`,
-				function(){return (T.pregnancy[0] == null ? "" : `<<set _pregnancy[0].timeLeft to 1>>`)},
-				function(){return (T.pregnancy[1] == null ? "" : `<<set _pregnancy[1].timeLeft to 1>>`)},
-				function(){return (T.pregnancy[2] == null ? "" : `<<set _pregnancy[2].timeLeft to 1>>`)},
-				function(){return (T.pregnancy[3] == null ? "" : `<<set _pregnancy[3].timeLeft to 1>>`)},
-			]
+				() => (T.pregnancy[0] == null ? "" : `<<set _pregnancy[0].timeLeft to 1>>`),
+				() => (T.pregnancy[1] == null ? "" : `<<set _pregnancy[1].timeLeft to 1>>`),
+				() => (T.pregnancy[2] == null ? "" : `<<set _pregnancy[2].timeLeft to 1>>`),
+				() => (T.pregnancy[3] == null ? "" : `<<set _pregnancy[3].timeLeft to 1>>`),
+			],
 		},
 		{
-			text_only: `\nThese still require Fertilise`
+			text_only: `\nThese still require Fertilise`,
 		},
 		{
-			link: [
-				`Get Pregnant with an eel`, stayOnPassageFn
-			],
-			widgets: [
-				`<<impregnate "eels" 1000>>`
-			]
+			link: [`Get Pregnant with an eel`, stayOnPassageFn],
+			widgets: [`<<impregnate "eels" 1000>>`],
 		},
 		{
-			link: [
-				`Get Pregnant with an slime`, stayOnPassageFn
-			],
-			widgets: [
-				`<<impregnate "slimes" 1000>>`
-			]
+			link: [`Get Pregnant with an slime`, stayOnPassageFn],
+			widgets: [`<<impregnate "slimes" 1000>>`],
 		},
 		{
-			link: [
-				`Get Pregnant with an worm`, stayOnPassageFn
-			],
-			widgets: [
-				`<<impregnate "worms" 1000>>`
-			]
+			link: [`Get Pregnant with an worm`, stayOnPassageFn],
+			widgets: [`<<impregnate "worms" 1000>>`],
 		},
 		{
-			link: [
-				`Get Pregnant with an tentacle`, stayOnPassageFn
-			],
-			widgets: [
-				`<<impregnate "tentacle" 1000>>`
-			]
+			link: [`Get Pregnant with an tentacle`, stayOnPassageFn],
+			widgets: [`<<impregnate "tentacle" 1000>>`],
 		},
 		{
-			text_only:`\n`
+			text_only: `\n`,
 		},
 		{
-			link: [
-				`Repair Pregnancy Objects`, stayOnPassageFn
-			],
-			widgets: [
-				`<<prenancyObjectRepair>>`
-			]
+			link: [`Repair Pregnancy Objects`, stayOnPassageFn],
+			widgets: [`<<prenancyObjectRepair>>`],
 		},
 		{
-			link: [
-				`Reset Pregnancy Objects`, stayOnPassageFn
-			],
-			widgets: [
-				`<<unset $container>>`,
-				`<<run delete $sexStats.anus>>`,
-				`<<physicalAdjustmentsInit>>`,
-				`<<containersInit>>`
-			]
+			link: [`Reset Pregnancy Objects`, stayOnPassageFn],
+			widgets: [`<<unset $container>>`, `<<run delete $sexStats.anus>>`, `<<physicalAdjustmentsInit>>`, `<<containersInit>>`],
 		},
 		{
-			text_only: `\nVaginal Pregnancy<br>
-						(New Pregnancy will only occur if not pregnant)\n`,
-			condition: function(){return V.pregnancyTesting}
+			text_only: `\nVaginal Pregnancy<br>(New Pregnancy will only occur if not pregnant)\n`,
+			condition: () => V.pregnancyTesting,
 		},
 		{
-			link: [
-				`Get Pregnant with humans`, stayOnPassageFn
-			],
+			link: [`Get Pregnant with humans`, stayOnPassageFn],
 			widgets: [
-				function() {if (V.sexStats.vagina.menstruation.currentState == "normal"){
-						return `<<set $sexStats.vagina.sperm["Debug Man"] = {"type":"human", "count":[[4,1000]]}>>`}},
-				function() {if (V.sexStats.vagina.menstruation.currentState == "normal"){
-					return `<<set $sexStats.vagina.menstruation.currentDay to $sexStats.vagina.menstruation.stages[2]>>`}},
-				function() {if (V.sexStats.vagina.menstruation.currentState == "normal"){
-					return `<<menstruationCycle>>`}}
+				() => {
+					if (V.sexStats.vagina.menstruation.currentState === "normal") {
+						return `<<set $sexStats.vagina.sperm["Debug Man"] = {"type":"human", "count":[[4,1000]]}>>
+						<<set $sexStats.vagina.menstruation.currentDay to $sexStats.vagina.menstruation.stages[2]>>
+						<menstruationCycle>>`;
+					}
+				},
 			],
-			condition: function(){return V.pregnancyTesting}
+			condition: () => V.pregnancyTesting,
 		},
 		{
-			link: [
-				`Get Pregnant with wolves`, stayOnPassageFn
-			],
+			link: [`Get Pregnant with wolves`, stayOnPassageFn],
 			widgets: [
-				function() {if (V.sexStats.vagina.menstruation.currentState == "normal"){
-						return `<<set $sexStats.vagina.sperm["Debug Wolf"] = {"type":"wolf", "count":[[4,1000]]}>>`}},
-				function() {if (V.sexStats.vagina.menstruation.currentState == "normal"){
-					return `<<set $sexStats.vagina.menstruation.currentDay to $sexStats.vagina.menstruation.stages[2]>>`}},
-				function() {if (V.sexStats.vagina.menstruation.currentState == "normal"){
-					return `<<menstruationCycle>>`}}
+				() => {
+					if (V.sexStats.vagina.menstruation.currentState === "normal") {
+						return `<<set $sexStats.vagina.sperm["Debug Wolf"] = {"type":"wolf", "count":[[4,1000]]}>>
+						<<set $sexStats.vagina.menstruation.currentDay to $sexStats.vagina.menstruation.stages[2]>>
+						<<menstruationCycle>>`;
+					}
+				},
 			],
-			condition: function(){return V.pregnancyTesting}
+			condition: () => V.pregnancyTesting,
 		},
 		{
-			link: [
-				`Get Robin Pregnant with PCs children`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _sperm to ["pc"]>>`,
-				`<<humanPregnancy "Robin" "pc" true>>`
-			],
-			condition: function(){return V.pregnancyTesting}
+			link: [`Get Robin Pregnant with PCs children`, stayOnPassageFn],
+			widgets: [`<<set _sperm to ["pc"]>>`, `<<humanPregnancy "Robin" "pc" true>>`],
+			condition: () => V.pregnancyTesting,
 		},
 		{
-			link: [
-				`Get Bailey Pregnant with Black wolf`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _sperm to ["Black Wolf"]>>`,
-				`<<wolfPregnancy "Bailey" "Black Wolf" true>>`
-			],
-			condition: function(){return V.pregnancyTesting}
+			link: [`Get Bailey Pregnant with Black wolf`, stayOnPassageFn],
+			widgets: [`<<set _sperm to ["Black Wolf"]>>`, `<<wolfPregnancy "Bailey" "Black Wolf" true>>`],
+			condition: () => V.pregnancyTesting,
 		},
 		{
-			link: [
-				`Enable Debug Lines`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $debugLines to true>>`
-			]
+			link: [`Enable Debug Lines`, stayOnPassageFn],
+			widgets: [`<<set $debugLines to true>>`],
 		},
 		{
-			link: [
-				`Disable Debug Lines`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $debugLines to false>>`
-			]
+			link: [`Disable Debug Lines`, stayOnPassageFn],
+			widgets: [`<<set $debugLines to false>>`],
 		},
 		{
-			text_only: `\n`
+			text_only: `\n`,
 		},
 	],
-	Events:[
+	Events: [
 		{
-			link: [
-				`Sex Shop`, `Adult Shop Menu`
-			],
-			widgets: []
+			link: [`Sex Shop`, `Adult Shop Menu`],
+			widgets: [],
 		},
 		{
-			link: [
-				`Sextoys Inventory`, `Sextoys Inventory`
-			],
-			widgets: []
+			link: [`Sextoys Inventory`, `Sextoys Inventory`],
+			widgets: [],
 		},
 		{
-			link: [
-				`Imprison Me`, `Underground Intro`
-			],
-			widgets: [
-				`<<generate1>>`,
-				`<<generate2>>`,
-				`<<person1>>`
-			]
+			link: [`Imprison Me`, `Underground Intro`],
+			widgets: [`<<generate1>>`, `<<generate2>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Imprison Me with Robin`, `Underground Intro`
-			],
-			widgets: [
-				`<<set $phase to 1>>`
-			]
+			link: [`Imprison Me with Robin`, `Underground Intro`],
+			widgets: [`<<set $phase to 1>>`],
 		},
 		{
-			link: [
-				`Start Robin Event`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $robindebt to 9>>`
-			]
+			link: [`Start Robin Event`, stayOnPassageFn],
+			widgets: [`<<set $robindebt to 9>>`],
 		},
 		{
-			link: [
-				`School Start`, `Oxford Street`
-			],
-			widgets: [
-				`<<pass 1 day>>`
-			]
+			link: [`School Start`, `Oxford Street`],
+			widgets: [`<<pass 1 day>>`],
 		},
 		{
-			link: [
-				`Rape Me`, `Molestation`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Rape Me`, `Molestation`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Double Rape Me`, `Forest Molestation`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Double Rape Me`, `Forest Molestation`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Gang Rape Me w/ Audience`, `The Pod`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Gang Rape Me w/ Audience`, `The Pod`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Sex Me [M]`, `Beach Day Encounter Sex`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<generateNPC 1 a m m>>`,
-				`<<person1>>`,
-				`<<set $sexstart to 1>>`
-			]
+			link: [`Sex Me [M]`, `Beach Day Encounter Sex`],
+			widgets: [`<<endcombat>>`, `<<generateNPC 1 a m m>>`, `<<person1>>`, `<<set $sexstart to 1>>`],
 		},
 		{
-			link: [
-				`Sex Me [F]`, `Beach Day Encounter Sex`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<generateNPC 1 a f f>>`,
-				`<<person1>>`,
-				`<<set $sexstart to 1>>`
-			]
+			link: [`Sex Me [F]`, `Beach Day Encounter Sex`],
+			widgets: [`<<endcombat>>`, `<<generateNPC 1 a f f>>`, `<<person1>>`, `<<set $sexstart to 1>>`],
 		},
 		{
-			link: [
-				`Gang Sex Me w/ Audience`, `Maths Lesson Gang Bang`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $sexstart to 1>>`
-			]
+			link: [`Gang Sex Me w/ Audience`, `Maths Lesson Gang Bang`],
+			widgets: [`<<endcombat>>`, `<<set $sexstart to 1>>`],
 		},
 		{
-			link: [
-				`DP Test`, `DP Test`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`DP Test`, `DP Test`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Choke Suffocate Test`, `Beach Day Encounter Sex`,
-			],
+			link: [`Choke Suffocate Test`, `Beach Day Encounter Sex`],
 			widgets: [
 				`<<endcombat>>`,
 				`<<generate1>>`,
@@ -786,196 +431,107 @@ setup.debugMenu.event_list = {
 				`<<set $suffocating to 3>>`,
 				`<<set $NPCList[0].righthand to "throat">>`,
 				`<<set $neckuse to "hand">>`,
-				`<<set $askedtochoke to 1>>`
-			]
+				`<<set $askedtochoke to 1>>`,
+			],
 		},
 		{
-			link: [
-				`Named NPC Gangbang Test`,
-				`Named NPC Gangbang Select`
-			],
-			widgets: [
-				`<<endcombat>>`
-			]
+			link: [`Named NPC Gangbang Test`, `Named NPC Gangbang Select`],
+			widgets: [`<<endcombat>>`],
 		},
 		{
-			link: [
-				`NPC role select`, `NPC Role Select`
-			],
-			widgets: [
-				`<<endcombat>>`
-			]
+			link: [`NPC role select`, `NPC Role Select`],
+			widgets: [`<<endcombat>>`],
 		},
 		{
-			link: [
-				`NPC clothing select`, `NPC Clothing Select`
-			],
-			widgets: [
-				`<<endcombat>>`
-			]
+			link: [`NPC clothing select`, `NPC Clothing Select`],
+			widgets: [`<<endcombat>>`],
 		},
 		{
-			link: [
-				`NNPC Strapon test`, `NNPC Strapon Generator`
-			],
-			widgets: [
-				`<<endcombat>>`
-			]
+			link: [`NNPC Strapon test`, `NNPC Strapon Generator`],
+			widgets: [`<<endcombat>>`],
 		},
 		{
-			link: [
-				`Plantperson Test`, `Plantperson Test`
-			],
-			widgets: [
-				`<<endcombat>>`
-			]
+			link: [`Plantperson Test`, `Plantperson Test`],
+			widgets: [`<<endcombat>>`],
 		},
 		{
-			link: [
-				"Hypnotist Test", "Hypnotist Test"
-			],
-			widgets: [
-				"<<endcombat>>"
-			]
+			link: ["Hypnotist Test", "Hypnotist Test"],
+			widgets: ["<<endcombat>>"],
 		},
 		{
-			link: [
-				`Eels Swarm Me`, `Sea Eels`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Eels Swarm Me`, `Sea Eels`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Machine`, `Machine`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Machine`, `Machine`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Struggle`, `Struggle`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $struggle_start to 1>>`
-			]
+			link: [`Struggle`, `Struggle`],
+			widgets: [`<<endcombat>>`, `<<set $struggle_start to 1>>`],
 		},
 		{
-			link: [
-				`Bus Rape`, `Bus move`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<generate1>>`,
-				`<<person1>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Bus Rape`, `Bus move`],
+			widgets: [`<<endcombat>>`, `<<generate1>>`, `<<person1>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Whale Vore Me`, `Monster Test`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Whale Vore Me`, `Monster Test`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Dogs Rape Me`, "Street Dogs"
-			],
+			link: [`Dogs Rape Me`, "Street Dogs"],
 			widgets: [
 				`<<endcombat>>`,
 				`<<set $molestationstart to 1>>`,
 				`<<beastNEWinit 3 dog>>`,
 				`<<set $outside to 1>>`,
 				`<<set $location to "town">>`,
-				`<<set $bus to "domus">>`
-			]
+				`<<set $bus to "domus">>`,
+			],
 		},
 		{
-			link: [
-				`Beast Gang Test (currently broken)`, `The Farm`
-			],
+			link: [`Beast Gang Test (currently broken)`, `The Farm`],
 			widgets: [
 				`<<endcombat>>`,
 				`<<set $molestationstart to 1>>`,
 				`<<set $outside to 1>>`,
 				`<<location "forest">>`,
-				`<<set $bus to "forest">>`
-			]
+				`<<set $bus to "forest">>`,
+			],
 		},
 		{
-			link: [
-				`Dolphin Sex Me`, `Sea Dolphins Sex`
-			],
+			link: [`Dolphin Sex Me`, `Sea Dolphins Sex`],
 			widgets: [
 				`<<endcombat>>`,
 				`<<set $sexstart to 1>>`,
 				`<<beastNEWinit 3 dolphin>>`,
 				`<<set $outside to 1>>`,
 				`<<location to "sea">>`,
-				`<<set $bus to "sea">>`
-			]
+				`<<set $bus to "sea">>`,
+			],
 		},
 		{
-			link: [
-				`Cow Test`, `Cow Test Sex`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $sexstart to 1>>`
-			]
+			link: [`Cow Test`, `Cow Test Sex`],
+			widgets: [`<<endcombat>>`, `<<set $sexstart to 1>>`],
 		},
 		{
-			link: [
-				`Tentacle Rape Me`, `Sea Tentacles`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Tentacle Rape Me`, `Sea Tentacles`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Bailey Test`, `Bus move`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`,
-				`<<npc Bailey>>`,
-				`<<person1>>`
-			]
+			link: [`Bailey Test`, `Bus move`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`, `<<npc Bailey>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Leighton Office Spank`, `School Detention`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $detention to 55>>`
-			]
+			link: [`Leighton Office Spank`, `School Detention`],
+			widgets: [`<<endcombat>>`, `<<set $detention to 55>>`],
 		},
 		{
-			link: [
-				`Enslave Me`, `Underground Intro`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<generate1>>`,
-				`<<generate2>>`,
-				`<<person1>>`
-			]
+			link: [`Enslave Me`, `Underground Intro`],
+			widgets: [`<<endcombat>>`, `<<generate1>>`, `<<generate2>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Work as a dancer`, `Brothel Dance`
-			],
+			link: [`Work as a dancer`, `Brothel Dance`],
 			widgets: [
 				`<<endcombat>>`,
 				`<<danceinit>>`,
@@ -983,13 +539,11 @@ setup.debugMenu.event_list = {
 				`<<set $venuemod to 3>>`,
 				`<<stress -4>>`,
 				`<<tiredness 4>>`,
-				`<<set $dancelocation to "brothel">>`
-			]
+				`<<set $dancelocation to "brothel">>`,
+			],
 		},
 		{
-			link: [
-				`Eden Start`, `Eden Cabin`
-			],
+			link: [`Eden Start`, `Eden Cabin`],
 			widgets: [
 				`<<endcombat>>`,
 				`<<set $syndromeeden to 1>>`,
@@ -997,267 +551,127 @@ setup.debugMenu.event_list = {
 				`<<set $edenshrooms to 0>>`,
 				`<<set $edengarden to 0>>`,
 				`<<set $edenspring to 0>>`,
-				`<<set $wardrobes.edensCabin.unlocked to true>>`
-			]
+				`<<set $wardrobes.edensCabin.unlocked to true>>`,
+			],
 		},
 		{
-			link: [
-				`Kylar Basement Rape`, `Kylar Basement Rape`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`,
-				`<<npc Kylar>>`,
-				`<<person1>>`
-			]
+			link: [`Kylar Basement Rape`, `Kylar Basement Rape`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`, `<<npc Kylar>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Kylar Sex`, `Street Kylar Sex`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $sexstart to 1>>`,
-				`<<set $location to "town">>`,
-				`<<npc Kylar>>`,
-				`<<person1>>`
-			]
+			link: [`Kylar Sex`, `Street Kylar Sex`],
+			widgets: [`<<endcombat>>`, `<<set $sexstart to 1>>`, `<<set $location to "town">>`, `<<npc Kylar>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Robin Sex Start`, `Bed Robin Sex`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $sexstart to 1>>`,
-				`<<npc Robin>>`,
-				`<<person1>>`
-			]
+			link: [`Robin Sex Start`, `Bed Robin Sex`],
+			widgets: [`<<endcombat>>`, `<<set $sexstart to 1>>`, `<<npc Robin>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Briar Pay Refuse`, `Brothel Pay Refuse`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`,
-				`<<npc Briar>>`,
-				`<<generate2>>`,
-				`<<generate3>>`,
-				`<<person1>>`
-			]
+			link: [`Briar Pay Refuse`, `Brothel Pay Refuse`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`, `<<npc Briar>>`, `<<generate2>>`, `<<generate3>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Leighton Sex`, `Head's Office Photoshoot Sex`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $sexstart to 1>>`,
-				`<<set $phase to 1>>`,
-				`<<npc Leighton>>`,
-				`<<person1>>`
-			]
+			link: [`Leighton Sex`, `Head's Office Photoshoot Sex`],
+			widgets: [`<<endcombat>>`, `<<set $sexstart to 1>>`, `<<set $phase to 1>>`, `<<npc Leighton>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Leighton Forced`, `Head's Office Blackmail Rape`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $molestationstart to 1>>`,
-				`<<npc Leighton>>`,
-				`<<person1>>`
-			]
+			link: [`Leighton Forced`, `Head's Office Blackmail Rape`],
+			widgets: [`<<endcombat>>`, `<<set $molestationstart to 1>>`, `<<npc Leighton>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Avery Date`, `Domus Street`
-			],
-			widgets: [
-				`<<set $averydate to 1>>`,
-				`<<set $time to 1200>>`
-			]
+			link: [`Avery Date`, `Domus Street`],
+			widgets: [`<<set $averydate to 1>>`, `<<set $time to 1200>>`],
 		},
 		{
-			link: [
-				`Black Wolf Forced`, `Forest Wolf Molestation`
-			],
+			link: [`Black Wolf Forced`, `Forest Wolf Molestation`],
 			widgets: [
-				/*`<<beastNNPCinit>>`,*/
+				/* `<<beastNNPCinit>>`, */
 				`<<endcombat>>`,
 				`<<npc "Black Wolf">>`,
-				`<<set $molestationstart to 1>>`
-			]
+				`<<set $molestationstart to 1>>`,
+			],
 		},
 		{
-			link: [
-				`Police Pillory Start`, `Police Pillory Start`
-			],
-			widgets: [
-				`<<set $crime to 5000>>`,
-				`<<generate1>>`,
-				`<<person1>>`
-			]
+			link: [`Police Pillory Start`, `Police Pillory Start`],
+			widgets: [`<<set $crime to 5000>>`, `<<generate1>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Hole in wall`, `Temple Arcade 2`
-			],
-			widgets: [
-				``
-			]
+			link: [`Hole in wall`, `Temple Arcade 2`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Brothel Punishment`, `Brothel Punishment`
-			],
-			widgets: [
-				``
-			]
+			link: [`Brothel Punishment`, `Brothel Punishment`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Brothel Gloryhole`, `Brothel Gloryhole`
-			],
-			widgets: [
-				``
-			]
+			link: [`Brothel Gloryhole`, `Brothel Gloryhole`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Clothing Shop`, `Clothing Shop`
-			],
-			widgets: [
-				``
-			]
+			link: [`Clothing Shop`, `Clothing Shop`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Forest Shop`, `Forest Shop`
-			],
-			widgets: [
-				``
-			]
+			link: [`Forest Shop`, `Forest Shop`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Sea`, `Sea`
-			],
-			widgets: [
-				`<<set $sea to 0>>`
-			]
+			link: [`Sea`, `Sea`],
+			widgets: [`<<set $sea to 0>>`],
 		},
 		{
-			link: [
-				`Hospital`, `Hospital Foyer`
-			],
-			widgets: [
-				``
-			]
+			link: [`Hospital`, `Hospital Foyer`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Wolf Pack`, `Forest Wolf Cave`
-			],
-			widgets: [
-				`<<set $wolfpacktrust to 12>>`
-			]
+			link: [`Wolf Pack`, `Forest Wolf Cave`],
+			widgets: [`<<set $wolfpacktrust to 12>>`],
 		},
 		{
-			link: [
-				`Halloween`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $days to 47>>`,
-				`<<set $monthday to 21>>`,
-				`<<set $yeardays to 47>>`,
-				`<<set $month to "october">>`
-			]
+			link: [`Halloween`, stayOnPassageFn],
+			widgets: [`<<set $days to 47>>`, `<<set $monthday to 21>>`, `<<set $yeardays to 47>>`, `<<set $month to "october">>`],
 		},
 		{
-			link: [
-				`Full winter`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $days to 92>>`,
-				`<<set $yeardays to 92>>`,
-				`<<set $monthday to 1>>`,
-				`<<set $month to "december">>`
-			]
+			link: [`Full winter`, stayOnPassageFn],
+			widgets: [`<<set $days to 92>>`, `<<set $yeardays to 92>>`, `<<set $monthday to 1>>`, `<<set $month to "december">>`],
 		},
 		{
-			link: [
-				`Christmas`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $days to 110>>`,
-				`<<set $yeardays to 110>>`,
-				`<<set $monthday to 18>>`,
-				`<<set $month to "december">>`
-			]
+			link: [`Christmas`, stayOnPassageFn],
+			widgets: [`<<set $days to 110>>`, `<<set $yeardays to 110>>`, `<<set $monthday to 18>>`, `<<set $month to "december">>`],
 		},
 		{
-			link: [
-				`Blood moon`, stayOnPassageFn
-			],
+			link: [`Blood moon`, stayOnPassageFn],
 			widgets: [
 				`<<set $monthday to 31>>`,
 				`<<set $daystate to "night">>`,
 				`<<set $hour to 21>>`,
 				`<<set $minute to 0>>`,
 				`<<set $time to 1260>>`,
-				`<<set $moonstate to "evening">>`
-			]
+				`<<set $moonstate to "evening">>`,
+			],
 		},
 		{
-			link: [
-				`Month is October`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $month to "october">>`
-			]
+			link: [`Month is October`, stayOnPassageFn],
+			widgets: [`<<set $month to "october">>`],
 		},
 		{
-			link: [
-				`Ambulance Rescue Wakeup`, `Ambulance rescue`
-			],
-			widgets: [
-				`<<pass 1 hour>>`
-			]
+			link: [`Ambulance Rescue Wakeup`, `Ambulance rescue`],
+			widgets: [`<<pass 1 hour>>`],
 		},
 		{
-			link: [
-				`Harper Appointment`, `Hospital Foyer`
-			],
-			widgets: [
-				`<<set $weekday to 6>>`,
-				`<<set $time to 960>>`
-			]
+			link: [`Harper Appointment`, `Hospital Foyer`],
+			widgets: [`<<set $weekday to 6>>`, `<<set $time to 960>>`],
 		},
 		{
-			link: [
-				`Deep forest`, `Forest`
-			],
-			widgets: [
-				`<<set $forest to 80>>`
-			]
+			link: [`Deep forest`, `Forest`],
+			widgets: [`<<set $forest to 80>>`],
 		},
 		{
-			link: [
-				`Street Police Extreme`, `Street Police Extreme`
-			],
-			widgets: [
-				`<pass 1 week>>`,
-				`<<pass 1 week>>`,
-				`<<npc Leighton>>`,
-				`<<person1>>`
-			]
+			link: [`Street Police Extreme`, `Street Police Extreme`],
+			widgets: [`<pass 1 week>>`, `<<pass 1 week>>`, `<<npc Leighton>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Brothel Show Swarm`, `Brothel Show Swarm`
-			],
+			link: [`Brothel Show Swarm`, `Brothel Show Swarm`],
 			widgets: [
 				`<<leash 1>>`,
 				`<<set $leftarm to "bound">>`,
@@ -1266,128 +680,63 @@ setup.debugMenu.event_list = {
 				`<<set $sexstart to 1>>`,
 				`<<set $rng to random(1,100)>>`,
 				`<<npc Briar>>`,
-				`<<person1>>`
-			]
+				`<<person1>>`,
+			],
 		},
 		{
-			link: [
-				`Pussy Inspection`, `Pussy Inspection`
-			],
-			widgets: [
-				`<<pass 1 week>>`,
-				`<<pass 1 week>>`,
-				`<<npc Leighton>>`,
-				`<<person1>>`
-			]
+			link: [`Pussy Inspection`, `Pussy Inspection`],
+			widgets: [`<<pass 1 week>>`, `<<pass 1 week>>`, `<<npc Leighton>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Penis Inspection`, `Penis Inspection`
-			],
-			widgets: [
-				`<<pass 1 week>>`,
-				`<<pass 1 week>>`,
-				`<<npc Leighton>>`,
-				`<<person1>>`
-			]
+			link: [`Penis Inspection`, `Penis Inspection`],
+			widgets: [`<<pass 1 week>>`, `<<pass 1 week>>`, `<<npc Leighton>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Breast Inspection`, `Breast Inspection`
-			],
-			widgets: [
-				`<<pass 1 week>>`,
-				`<<pass 1 week>>`,
-				`<<npc Leighton>>`,
-				`<<person1>>`
-			]
+			link: [`Breast Inspection`, `Breast Inspection`],
+			widgets: [`<<pass 1 week>>`, `<<pass 1 week>>`, `<<npc Leighton>>`, `<<person1>>`],
 		},
 		{
-			link: [
-				`Science Class Exposure`, `Science Event3`
-			],
-			widgets: [
-				`<<set $scienceprogression to 3>>`,
-				`<<set $delinquency to 600>>`
-			]
+			link: [`Science Class Exposure`, `Science Event3`],
+			widgets: [`<<set $scienceprogression to 3>>`, `<<set $delinquency to 600>>`],
 		},
 		{
-			link: [
-				`History Class Pillory`, `History Lesson Pillory`
-			],
-			widgets: [
-				``
-			]
+			link: [`History Class Pillory`, `History Lesson Pillory`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Alley Dog`, `Alley Dog`
-			],
-			widgets: [
-				``
-			]
+			link: [`Alley Dog`, `Alley Dog`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`NNPC Parade`, `NNPC Parade`
-			],
-			widgets: [
-				``
-			]
+			link: [`NNPC Parade`, `NNPC Parade`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Beast Parade`, `Beast Parade`
-			],
-			widgets: [
-				``
-			]
+			link: [`Beast Parade`, `Beast Parade`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Beast Train`, `Beast Train`
-			],
-			widgets: [
-				``
-			]
+			link: [`Beast Train`, `Beast Train`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Demon Encounter`, `Demon Start`
-			],
-			widgets: [
-				``
-			]
+			link: [`Demon Encounter`, `Demon Start`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Temple Initiate`, `Temple`
-			],
-			widgets: [
-				`<<inittemple>>`
-			]
+			link: [`Temple Initiate`, `Temple`],
+			widgets: [`<<inittemple>>`],
 		},
 		{
-			link: [
-				`Strip Club`, `Strip Club`
-			],
-			widgets: [
-				`<<set $id to 1>>`,
-				`<<set $wardrobes.stripClub.unlocked to true>>`
-			]
+			link: [`Strip Club`, `Strip Club`],
+			widgets: [`<<set $id to 1>>`, `<<set $wardrobes.stripClub.unlocked to true>>`],
 		},
 		{
-			link: [
-				`Asylum`, `Hospital Bed`
-			],
-			widgets: [
-				`<<set $trauma to 4900>>`
-			]
+			link: [`Asylum`, `Hospital Bed`],
+			widgets: [`<<set $trauma to 4900>>`],
 		},
 		{
-			link: [
-				`Prison`, `Police Prison Intro Bailey`
-			],
+			link: [`Prison`, `Police Prison Intro Bailey`],
 			widgets: [
 				`<<npc Bailey>>`,
 				`<<generate2>>`,
@@ -1395,98 +744,54 @@ setup.debugMenu.event_list = {
 				`<<generate4>>`,
 				`<<person2>>`,
 				`<<neckwear 1>>`,
-				`<<crimeup 5000>>`
-			]
+				`<<crimeup 5000>>`,
+			],
 		},
 		{
-			link: [
-				`Remy's Farm`, `Livestock Intro`
-			],
-			widgets: [
-				``
-			]
+			link: [`Remy's Farm`, `Livestock Intro`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Farmlands`, `Farmland`
-			],
-			widgets: [
-				``
-			]
+			link: [`Farmlands`, `Farmland`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Museum`, `Museum`
-			],
-			widgets: [
-				``
-			]
+			link: [`Museum`, `Museum`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Beach Cave`, `Beach Cave`
-			],
-			widgets: [
-				`<<set $cave to 0>>`,
-				`<<beach_cave_init>>`
-			]
+			link: [`Beach Cave`, `Beach Cave`],
+			widgets: [`<<set $cave to 0>>`, `<<beach_cave_init>>`],
 		},
 		{
-			link: [
-				`Stall Rent`, `Stall Rent`
-			],
-			widgets: [
-				`<<set $time to 360>>`,
-				`<<set $daystate to "dawn">>`
-			]
+			link: [`Stall Rent`, `Stall Rent`],
+			widgets: [`<<set $time to 360>>`, `<<set $daystate to "dawn">>`],
 		},
 		{
-			link: [
-				`Estate`, `Estate`
-			],
-			widgets: [
-				`<<estate_end>>`,
-				`<<estate_init secret>>`
-			]
+			link: [`Estate`, `Estate`],
+			widgets: [`<<estate_end>>`, `<<estate_init secret>>`],
 		},
 		{
-			link: [
-				`Stalk me`, `Street Stalk`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<generate1>>`,
-				`<<person1>>`,
-				`<<set $molestationstart to 1>>`
-			]
+			link: [`Stalk me`, `Street Stalk`],
+			widgets: [`<<endcombat>>`, `<<generate1>>`, `<<person1>>`, `<<set $molestationstart to 1>>`],
 		},
 		{
-			link: [
-				`Named NPC stalk test`,
-				`Named NPC Stalk Select`
-			],
-			widgets: [
-				`<<endcombat>>`,
-				`<<set $phase to 0>>`
-			]
+			link: [`Named NPC stalk test`, `Named NPC Stalk Select`],
+			widgets: [`<<endcombat>>`, `<<set $phase to 0>>`],
 		},
 		{
-			link: [
-				`Bailey selling Robin`, `Orphanage`
-			],
+			link: [`Bailey selling Robin`, `Orphanage`],
 			widgets: [
 				`<<set $renttime to 0>>`,
 				`<<set $baileydefeatedchain to 3>>`,
 				`<<set $robinpaid to 1>>`,
 				`<<set $robinromance to 1>>`,
 				`<<set $bus to "home">>`,
-				`<<set $location to "home">>`
-			]
+				`<<set $location to "home">>`,
+			],
 		},
 		{
-			link: [
-				`Summon the Wraith`, `Wraith Test Start`
-			],
+			link: [`Summon the Wraith`, `Wraith Test Start`],
 			widgets: [
 				`<<endcombat>>`,
 				`<<set $monthday to 31>>`,
@@ -1494,254 +799,148 @@ setup.debugMenu.event_list = {
 				`<<set $hour to 21>>`,
 				`<<set $minute to 0>>`,
 				`<<set $time to 1260>>`,
-				`<<set $moonstate to "evening">>`
-			]
+				`<<set $moonstate to "evening">>`,
+			],
 		},
 		{
-			link: [
-				`Possessed Fight`, `Possessed Fight Test`
-			],
-			widgets: [
-				`<<set $control to 0>>`,
-				`<<set $possessed to true>>`,
-			]
+			link: [`Possessed Fight`, `Possessed Fight Test`],
+			widgets: [`<<set $control to 0>>`, `<<set $possessed to true>>`],
 		},
 		{
-			text_only: "\n\nTurn beast into: "
+			text_only: "\n\nTurn beast into: ",
 		},
 		{
-			link: [
-				`Creature`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "creature">>`
-			]
+			link: [`Creature`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "creature">>`],
 		},
 		{
-			link: [
-				`Dog`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "dog">>`
-			]
+			link: [`Dog`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "dog">>`],
 		},
 		{
-			link: [
-				`Wolf`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "wolf">>`
-			]
+			link: [`Wolf`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "wolf">>`],
 		},
 		{
-			link: [
-				`Dolphin`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "dolphin">>`
-			]
+			link: [`Dolphin`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "dolphin">>`],
 		},
 		{
-			link: [
-				`Bear`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "bear">>`
-			]
+			link: [`Bear`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "bear">>`],
 		},
 		{
-			link: [
-				`Boar`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "boar">>`
-			]
+			link: [`Boar`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "boar">>`],
 		},
 		{
-			link: [
-				`Pig`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "pig">>`
-			]
+			link: [`Pig`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "pig">>`],
 		},
 		{
-			link: [
-				`Lizard`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set _xy to $enemyno-1>>`,
-				`<<set $NPCList[_xy].type to "lizard">>`
-			]
+			link: [`Lizard`, stayOnPassageFn],
+			widgets: [`<<set _xy to $enemyno-1>>`, `<<set $NPCList[_xy].type to "lizard">>`],
 		},
 		{
-			text_only: "\n\nSwarm Encounters:"
+			text_only: "\n\nSwarm Encounters:",
 		},
 		{
-			link: [
-				`Ruin Fish`, `Swarm Test`
-			],
+			link: [`Ruin Fish`, `Swarm Test`],
 			widgets: [
 				`<<set $molestationstart to 1>>`,
 				`<<swarminit "fish" "container" "shaking" "shatter" "steady" 4 6>>`,
-				`<<set $water to 1>>`
-			]
+				`<<set $water to 1>>`,
+			],
 		},
 		{
-			link: [
-				`Lake Fish`, `Swarm Test`
-			],
+			link: [`Lake Fish`, `Swarm Test`],
 			widgets: [
 				`<<set $molestationstart to 1>>`,
 				`<<swarminit "fish" "swarm" "moving towards you" "encircle you" "fend off" 1 7>>`,
-				`<<set $water to 1>>`
-			]
+				`<<set $water to 1>>`,
+			],
 		},
 		{
-			link: [
-				`Forest Snakes`, `Swarm Test`
-			],
-			widgets: [
-				`<<set $molestationstart to 1>>`,
-				`<<swarminit "snakes" "swarm" "slithering" "slither" "keep back" 10 0>>`
-			]
+			link: [`Forest Snakes`, `Swarm Test`],
+			widgets: [`<<set $molestationstart to 1>>`, `<<swarminit "snakes" "swarm" "slithering" "slither" "keep back" 10 0>>`],
 		},
 		{
-			link: [
-				`Danube Spiders`, `Swarm Test`
-			],
-			widgets: [
-				`<<set $molestationstart to 1>>`,
-				`<<swarminit "spiders" "sac" "slipping" "break" "steady" 1 9>>`
-			]
+			link: [`Danube Spiders`, `Swarm Test`],
+			widgets: [`<<set $molestationstart to 1>>`, `<<swarminit "spiders" "sac" "slipping" "break" "steady" 1 9>>`],
 		},
 		{
-			link: [
-				`Bath Slimes`, `Swarm Test`
-			],
+			link: [`Bath Slimes`, `Swarm Test`],
 			widgets: [
 				`<<set $molestationstart to 1>>`,
-				`<<swarminit "slimes" "slime mass" "moving towards you" "encircle you" "fend off" 8 0>>`
-			]
+				`<<swarminit "slimes" "slime mass" "moving towards you" "encircle you" "fend off" 8 0>>`,
+			],
 		},
 		{
-			link: [
-				`Trash Maggots`, `Swarm Test`
-			],
-			widgets: [
-				`<<set $molestationstart to 1>>`,
-				`<<swarminit "maggots" "swarm" "crawling" "crawl" "keep back" 2 8>>`
-			]
+			link: [`Trash Maggots`, `Swarm Test`],
+			widgets: [`<<set $molestationstart to 1>>`, `<<swarminit "maggots" "swarm" "crawling" "crawl" "keep back" 2 8>>`],
 		},
 		{
-			link: [
-				`Science Worms`, `Swarm Test`
-			],
+			link: [`Science Worms`, `Swarm Test`],
 			widgets: [
 				`<<set $molestationstart to 1>>`,
-				`<<swarminit "worms" "jar" "held above the terrarium" "fall into the terrarium" "block" 0 10>>`
-			]
+				`<<swarminit "worms" "jar" "held above the terrarium" "fall into the terrarium" "block" 0 10>>`,
+			],
 		},
 		{
-			link: [
-				`Sea Eels`, `Swarm Test`
-			],
+			link: [`Sea Eels`, `Swarm Test`],
 			widgets: [
 				`<<set $molestationstart to 1>>`,
 				`<<swarminit "eels" "swarm" "moving towards you" "encircle you" "fend off" 1 9>>`,
-				`<<set $water to 1>>`
-			]
+				`<<set $water to 1>>`,
+			],
 		},
 		{
-			link: [
-				`Crate Worms`, `Swarm Test`
-			],
-			widgets: [
-				`<<set $molestationstart to 1>>`,
-				`<<swarminit "worms" "container" "shaking" "shatter" "steady" 1 9>>`
-			]
+			link: [`Crate Worms`, `Swarm Test`],
+			widgets: [`<<set $molestationstart to 1>>`, `<<swarminit "worms" "container" "shaking" "shatter" "steady" 1 9>>`],
 		},
 		{
-			text_only: `\nEvent Debugging:`
+			text_only: `\nEvent Debugging:`,
 		},
 		{
-			link: [
-				`Test NPC Insertion`, `NPCInsertionAssert`
-			],
-			widgets: [
-				``
-			]
+			link: [`Test NPC Insertion`, `NPCInsertionAssert`],
+			widgets: [``],
 		},
 		{
-			link: [
-				`Time Test`, `TimeTest`
-			],
-			widgets: [
-				`<<set $prevPassage to $passage>>`,
-				`<<set $timeDistortion to 5>>`
-			]
+			link: [`Time Test`, `TimeTest`],
+			widgets: [`<<set $prevPassage to $passage>>`, `<<set $timeDistortion to 5>>`],
 		},
 	],
-	Character:[
+	Character: [
 		{
-			link: [
-				`Default allure`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $alluretest to 0>>`
-			],
-			condition: function(){return V.alluretest >= 1}
+			link: [`Default allure`, stayOnPassageFn],
+			widgets: [`<<set $alluretest to 0>>`],
+			condition: () => V.alluretest >= 1,
 		},
 		{
-			link: [
-				`Become Alluring`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $alluretest to 1>>`
-			],
-			condition: function(){return V.alluretest < 1}
+			link: [`Become Alluring`, stayOnPassageFn],
+			widgets: [`<<set $alluretest to 1>>`],
+			condition: () => V.alluretest < 1,
 		},
 		{
-			link: [
-				`Become Unalluring`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $alluretest to 2>>`
-			],
-			condition: function(){return V.alluretest < 1}
+			link: [`Become Unalluring`, stayOnPassageFn],
+			widgets: [`<<set $alluretest to 2>>`],
+			condition: () => V.alluretest < 1,
 		},
 		{
-			link: [
-				`Hide`, stayOnPassageFn
-			],
-			widgets: [
-				`<<dontHideRevert>>`
-			],
-			condition: function(){return V.dontHide}
+			link: [`Hide`, stayOnPassageFn],
+			widgets: [`<<dontHideRevert>>`],
+			condition: () => V.dontHide,
 		},
 		{
-			link: [
-				`Don't hide`, stayOnPassageFn
-			],
-			widgets: [
-				`<<dontHideForNow>>`
-			],
-			condition: function(){return V.dontHide != true}
+			link: [`Don't hide`, stayOnPassageFn],
+			widgets: [`<<dontHideForNow>>`],
+			condition: () => !V.dontHide,
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`All Fame Up`, stayOnPassageFn
-			],
+			link: [`All Fame Up`, stayOnPassageFn],
 			widgets: [
 				`<<fameexhibitionism 1000 "none" true>>`,
 				`<<fameprostitution 1000 "none" true>>`,
@@ -1754,477 +953,254 @@ setup.debugMenu.event_list = {
 				`<<famepimp 1000 "none" true>>`,
 				`<<famescrap 1000 "none" true>>`,
 				`<<famesocial 1000 "none" true>>`,
-				`<<famemodel 1000 "none" true>>`
-			]
-		},
-		{
-			link: [
-				`Fame Sex Up`, stayOnPassageFn
+				`<<famemodel 1000 "none" true>>`,
 			],
-			widgets: [
-				`<<famesex 2000 "none" true>>`
-			]
 		},
 		{
-			link: [
-				`Timer Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $timer -= 60>>`
-			]
+			link: [`Fame Sex Up`, stayOnPassageFn],
+			widgets: [`<<famesex 2000 "none" true>>`],
 		},
 		{
-			link: [
-				`Size Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $devlevel += 1>>`
-			]
+			link: [`Timer Down`, stayOnPassageFn],
+			widgets: [`<<set $timer -= 60>>`],
 		},
 		{
-			link: [
-				`Full Lewd Characteristics`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $promiscuity += 100>>`,
-				`<<set $exhibitionism += 100>>`,
-				`<<set $deviancy += 100>>`
-			]
+			link: [`Size Up`, stayOnPassageFn],
+			widgets: [`<<set $devlevel += 1>>`],
 		},
 		{
-			link: [
-				`Exhibitionism`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $exhibitionism += 20>>`
-			]
+			link: [`Full Lewd Characteristics`, stayOnPassageFn],
+			widgets: [`<<set $promiscuity += 100>>`, `<<set $exhibitionism += 100>>`, `<<set $deviancy += 100>>`],
 		},
 		{
-			link: [
-				`Promiscuity`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $promiscuity += 20>>`
-			]
+			link: [`Exhibitionism`, stayOnPassageFn],
+			widgets: [`<<set $exhibitionism += 20>>`],
 		},
 		{
-			link: [
-				`Deviancy`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $deviancy += 20>>`
-			]
+			link: [`Promiscuity`, stayOnPassageFn],
+			widgets: [`<<set $promiscuity += 20>>`],
 		},
 		{
-			link: [
-				`Beauty`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $beauty += 10000>>`
-			]
+			link: [`Deviancy`, stayOnPassageFn],
+			widgets: [`<<set $deviancy += 20>>`],
 		},
 		{
-			link: [
-				`Physique`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $physique += 2000>>`
-			]
+			link: [`Beauty`, stayOnPassageFn],
+			widgets: [`<<set $beauty += 10000>>`],
+		},
+		{
+			link: [`Physique`, stayOnPassageFn],
+			widgets: [`<<set $physique += 2000>>`],
 		},
 		{
-			link: [
-				`Awareness up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $awareness += 200>>`
-			]
+			link: [`Awareness up`, stayOnPassageFn],
+			widgets: [`<<set $awareness += 200>>`],
 		},
 		{
-			link: [
-				`Awareness down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $awareness -= 200>>`
-			]
+			link: [`Awareness down`, stayOnPassageFn],
+			widgets: [`<<set $awareness -= 200>>`],
 		},
 		{
-			link: [
-				`Purity Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $purity += 500>>`
-			]
+			link: [`Purity Up`, stayOnPassageFn],
+			widgets: [`<<set $purity += 500>>`],
 		},
 		{
-			link: [
-				`Purity Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $purity -= 500>>`
-			]
+			link: [`Purity Down`, stayOnPassageFn],
+			widgets: [`<<set $purity -= 500>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Pain Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $pain += 50>>`
-			]
+			link: [`Pain Up`, stayOnPassageFn],
+			widgets: [`<<set $pain += 50>>`],
 		},
 		{
-			link: [
-				`Pain Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $pain -= 50>>`
-			]
+			link: [`Pain Down`, stayOnPassageFn],
+			widgets: [`<<set $pain -= 50>>`],
 		},
 		{
-			link: [
-				`Stress Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $stress += 5000>>`
-			]
+			link: [`Stress Up`, stayOnPassageFn],
+			widgets: [`<<set $stress += 5000>>`],
 		},
 		{
-			link: [
-				`Stress Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $stress -= 5000>>`
-			]
+			link: [`Stress Down`, stayOnPassageFn],
+			widgets: [`<<set $stress -= 5000>>`],
 		},
 		{
-			link: [
-				`Trauma Way Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $trauma += 2000>>`
-			]
+			link: [`Trauma Way Up`, stayOnPassageFn],
+			widgets: [`<<set $trauma += 2000>>`],
 		},
 		{
-			link: [
-				`Trauma Way Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $trauma -= 2000>>`
-			]
+			link: [`Trauma Way Down`, stayOnPassageFn],
+			widgets: [`<<set $trauma -= 2000>>`],
 		},
 		{
-			link: [
-				`Arousal max`, stayOnPassageFn
-			],
-			widgets: [
-				`<<arousal $arousalmax>>`
-			]
+			link: [`Arousal max`, stayOnPassageFn],
+			widgets: [`<<arousal $arousalmax>>`],
 		},
 		{
-			link: [
-				`Arousal zero`, stayOnPassageFn
-			],
-			widgets: [
-				`<<arousal 0>>`
-			]
+			link: [`Arousal zero`, stayOnPassageFn],
+			widgets: [`<<arousal 0>>`],
 		},
 		{
-			link: [
-				`Booze`, stayOnPassageFn
-			],
-			widgets: [
-				`<<alcohol 60>>`
-			]
+			link: [`Booze`, stayOnPassageFn],
+			widgets: [`<<alcohol 60>>`],
 		},
 		{
-			link: [
-				`Drugged`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $drugged += 600>>`
-			]
+			link: [`Drugged`, stayOnPassageFn],
+			widgets: [`<<set $drugged += 600>>`],
 		},
 		{
-			link: [
-				`Hallucinogen`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $hallucinogen += 600>>`
-			]
+			link: [`Hallucinogen`, stayOnPassageFn],
+			widgets: [`<<set $hallucinogen += 600>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Sunlight`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $weather to "clear">>`
-			]
+			link: [`Sunlight`, stayOnPassageFn],
+			widgets: [`<<set $weather to "clear">>`],
 		},
 		{
-			link: [
-				`Wash`, stayOnPassageFn
-			],
-			widgets: [
-				`<<wash>>`
-			]
+			link: [`Wash`, stayOnPassageFn],
+			widgets: [`<<wash>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Seduction Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $seductionskill += 200>>`
-			]
+			link: [`Seduction Up`, stayOnPassageFn],
+			widgets: [`<<set $seductionskill += 200>>`],
 		},
 		{
-			link: [
-				`Skulduggery Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $skulduggery += 200>>`
-			]
+			link: [`Skulduggery Up`, stayOnPassageFn],
+			widgets: [`<<set $skulduggery += 200>>`],
 		},
 		{
-			link: [
-				`Swimming Skill Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $swimmingskill += 100>>`
-			]
+			link: [`Swimming Skill Up`, stayOnPassageFn],
+			widgets: [`<<set $swimmingskill += 100>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Crime Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $crime += 500>>`
-			]
+			link: [`Crime Up`, stayOnPassageFn],
+			widgets: [`<<set $crime += 500>>`],
 		},
 		{
-			link: [
-				`Crime Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $crime -= 500>>`
-			]
+			link: [`Crime Down`, stayOnPassageFn],
+			widgets: [`<<set $crime -= 500>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Reset NPC[0]'s Hand`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $NPCList[0].lefthand to 0>>`,
-				`<<set $NPCList[0].righthand to 0>>`
-			]
+			link: [`Reset NPC[0]'s Hand`, stayOnPassageFn],
+			widgets: [`<<set $NPCList[0].lefthand to 0>>`, `<<set $NPCList[0].righthand to 0>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Chastity Belt`, stayOnPassageFn
-			],
-			widgets: [
-				`<<genitalswear 1>>`
-			]
+			link: [`Chastity Belt`, stayOnPassageFn],
+			widgets: [`<<genitalswear 1>>`],
 		},
 		{
-			link: [
-				`Chastity Cage`, stayOnPassageFn
-			],
-			widgets: [
-				`<<genitalswear 2>>`
-			]
+			link: [`Chastity Cage`, stayOnPassageFn],
+			widgets: [`<<genitalswear 2>>`],
 		},
 		{
-			link: [
-				`Collar`, stayOnPassageFn
-			],
-			widgets: [
-				`<<leash 21>>`
-			]
+			link: [`Collar`, stayOnPassageFn],
+			widgets: [`<<leash 21>>`],
 		},
 		{
-			link: [
-				`Bind`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $leftarm to "bound">>`,
-				`<<set $rightarm to "bound">>`
-			]
+			link: [`Bind`, stayOnPassageFn],
+			widgets: [`<<set $leftarm to "bound">>`, `<<set $rightarm to "bound">>`],
 		},
 		{
-			link: [
-				`UnBind`, stayOnPassageFn
-			],
-			widgets: [
-				`<<unbind>>`
-			]
+			link: [`UnBind`, stayOnPassageFn],
+			widgets: [`<<unbind>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Breasts Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $player.breastsize += 1>>`
-			]
+			link: [`Breasts Up`, stayOnPassageFn],
+			widgets: [`<<set $player.breastsize += 1>>`],
 		},
 		{
-			link: [
-				`Breasts Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $player.breastsize -= 1>>`
-			]
+			link: [`Breasts Down`, stayOnPassageFn],
+			widgets: [`<<set $player.breastsize -= 1>>`],
 		},
 		{
-			link: [
-				`Butt Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $player.bottomsize += 1>>`
-			]
+			link: [`Butt Up`, stayOnPassageFn],
+			widgets: [`<<set $player.bottomsize += 1>>`],
 		},
 		{
-			link: [
-				`Butt Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $player.bottomsize -= 1>>`
-			]
+			link: [`Butt Down`, stayOnPassageFn],
+			widgets: [`<<set $player.bottomsize -= 1>>`],
 		},
 		{
-			link: [
-				`Penis Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $player.penissize += 1>>`
-			]
+			link: [`Penis Up`, stayOnPassageFn],
+			widgets: [`<<set $player.penissize += 1>>`],
 		},
 		{
-			link: [
-				`Penis Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $player.penissize -= 1>>`
-			]
+			link: [`Penis Down`, stayOnPassageFn],
+			widgets: [`<<set $player.penissize -= 1>>`],
 		},
 		{
-			link: [
-				`Balls Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $ballssize += 1>>`
-			]
+			link: [`Balls Up`, stayOnPassageFn],
+			widgets: [`<<set $ballssize += 1>>`],
 		},
 		{
-			link: [
-				`Balls Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $ballssize -= 1>>`
-			]
+			link: [`Balls Down`, stayOnPassageFn],
+			widgets: [`<<set $ballssize -= 1>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Money`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $money += 500000>>`
-			]
+			link: [`Money`, stayOnPassageFn],
+			widgets: [`<<set $money += 500000>>`],
 		},
 		{
-			link: [
-				`Grow hair`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $hairlength += 100>>`
-			]
+			link: [`Grow hair`, stayOnPassageFn],
+			widgets: [`<<set $hairlength += 100>>`],
 		},
 		{
-			link: [
-				`Grow fringe`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $fringelength += 100>>`
-			]
+			link: [`Grow fringe`, stayOnPassageFn],
+			widgets: [`<<set $fringelength += 100>>`],
 		},
 		{
-			link: [
-				`Chest Parasite`, stayOnPassageFn
-			],
-			widgets: [
-				`<<parasite nipples urchin>>`
-			]
+			link: [`Chest Parasite`, stayOnPassageFn],
+			widgets: [`<<parasite nipples urchin>>`],
 		},
 		{
-			link: [
-				`Penis Parasite`, stayOnPassageFn
-			],
-			widgets: [
-				`<<parasite penis urchin>>`
-			]
+			link: [`Penis Parasite`, stayOnPassageFn],
+			widgets: [`<<parasite penis urchin>>`],
 		},
 		{
-			link: [
-				`Chastity Parasite`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $analchastityparasite to "worms">>`
-			]
+			link: [`Chastity Parasite`, stayOnPassageFn],
+			widgets: [`<<set $analchastityparasite to "worms">>`],
 		},
 		{
-			link: [
-				`Month`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $monthday += 31>>`,
-				`<<day>>`
-			]
+			link: [`Month`, stayOnPassageFn],
+			widgets: [`<<set $monthday += 31>>`, `<<day>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Delinquency`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $delinquency += 1000>>`
-			]
+			link: [`Delinquency`, stayOnPassageFn],
+			widgets: [`<<set $delinquency += 1000>>`],
 		},
 		{
-			link: [
-				`Detention`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $detention += 10>>`
-			]
+			link: [`Detention`, stayOnPassageFn],
+			widgets: [`<<set $detention += 10>>`],
 		},
 		{
-			link: [
-				`School Skills`, stayOnPassageFn
-			],
+			link: [`School Skills`, stayOnPassageFn],
 			widgets: [
 				`<<set $school += 8000>>`,
 				`<<set $science += 800>>`,
@@ -2234,24 +1210,20 @@ setup.debugMenu.event_list = {
 				`<<set $sciencetrait to 4>>`,
 				`<<set $mathstrait to 4>>`,
 				`<<set $englishtrait to 4>>`,
-				`<<set $historytrait to 4>>`
-			]
+				`<<set $historytrait to 4>>`,
+			],
 		},
 		{
-			link: [
-				`School Exam Skill`, stayOnPassageFn
-			],
+			link: [`School Exam Skill`, stayOnPassageFn],
 			widgets: [
 				`<<set $science_exam += 1000>>`,
 				`<<set $maths_exam += 1000>>`,
 				`<<set $english_exam += 1000>>`,
-				`<<set $history_exam += 1000>>`
-			]
+				`<<set $history_exam += 1000>>`,
+			],
 		},
 		{
-			link: [
-				`All Skills`, stayOnPassageFn
-			],
+			link: [`All Skills`, stayOnPassageFn],
 			widgets: [
 				`<<set $school += 448>>`,
 				`<<set $science += 112>>`,
@@ -2270,13 +1242,11 @@ setup.debugMenu.event_list = {
 				`<<set $oralskill += 112>>`,
 				`<<set $analskill += 112>>`,
 				`<<set $vaginalskill += 112>>`,
-				`<<set $penileskill += 112>>`
-			]
+				`<<set $penileskill += 112>>`,
+			],
 		},
 		{
-			link: [
-				`All Skills Super`, stayOnPassageFn
-			],
+			link: [`All Skills Super`, stayOnPassageFn],
 			widgets: [
 				`<<set $school += 4000>>`,
 				`<<set $science += 1000>>`,
@@ -2299,105 +1269,60 @@ setup.debugMenu.event_list = {
 				`<<set $oralskill += 1000>>`,
 				`<<set $analskill += 1000>>`,
 				`<<set $vaginalskill += 1000>>`,
-				`<<set $penileskill += 1000>>`
-			]
+				`<<set $penileskill += 1000>>`,
+			],
 		},
 		{
-			link: [
-				`School Status Up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $cool += 400>>`
-			]
+			link: [`School Status Up`, stayOnPassageFn],
+			widgets: [`<<set $cool += 400>>`],
 		},
 		{
-			link: [
-				`School Status Down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $cool -= 400>>`
-			]
+			link: [`School Status Down`, stayOnPassageFn],
+			widgets: [`<<set $cool -= 400>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Destroy Swimming Outfits`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $upperschoolswimsuitno to 0>>`,
-				`<<set $lowerschoolswimsuitno to 0>>`,
-				`<<set $schoolswimshortsno to 0>>`
-			]
+			link: [`Destroy Swimming Outfits`, stayOnPassageFn],
+			widgets: [`<<set $upperschoolswimsuitno to 0>>`, `<<set $lowerschoolswimsuitno to 0>>`, `<<set $schoolswimshortsno to 0>>`],
 		},
 		{
-			link: [
-				`Towels`, stayOnPassageFn
-			],
-			widgets: [
-				`<<clothesontowel>>`
-			]
+			link: [`Towels`, stayOnPassageFn],
+			widgets: [`<<clothesontowel>>`],
 		},
 		{
-			link: [
-				`Towels Please`, stayOnPassageFn
-			],
-			widgets: [
-				`<<towelup>>`
-			]
+			link: [`Towels Please`, stayOnPassageFn],
+			widgets: [`<<towelup>>`],
 		},
 		{
-			link: [
-				`Submission`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $submissive += 250>>`
-			]
+			link: [`Submission`, stayOnPassageFn],
+			widgets: [`<<set $submissive += 250>>`],
 		},
 		{
-			link: [
-				`Defiance`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $submissive -= 250>>`
-			]
+			link: [`Defiance`, stayOnPassageFn],
+			widgets: [`<<set $submissive -= 250>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Robin Love`, stayOnPassageFn
-			],
-			widgets: [
-				`<<npcincr Robin love 100>>`,
-				`<<npcincr Robin lust 100>>`
-			]
+			link: [`Robin Love`, stayOnPassageFn],
+			widgets: [`<<npcincr Robin love 100>>`, `<<npcincr Robin lust 100>>`],
 		},
 		{
-			link: [
-				`Robin Note`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $robinnote to 1>>`
-			]
+			link: [`Robin Note`, stayOnPassageFn],
+			widgets: [`<<set $robinnote to 1>>`],
 		},
 		{
-			link: [
-				`Robin Romance`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $robinromance to 1>>`
-			]
+			link: [`Robin Romance`, stayOnPassageFn],
+			widgets: [`<<set $robinromance to 1>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Sex Statistics Up`, stayOnPassageFn
-			],
+			link: [`Sex Statistics Up`, stayOnPassageFn],
 			widgets: [
 				`<<set $orgasmstat += 2000>>`,
 				`<<set $ejacstat += 2000>>`,
@@ -2406,643 +1331,525 @@ setup.debugMenu.event_list = {
 				`<<set $beastrapestat += 500>>`,
 				`<<set $tentaclerapestat += 200>>`,
 				`<<set $swallowedstat += 100>>`,
-				`<<set $prostitutionstat += 10>>`
-			]
+				`<<set $prostitutionstat += 10>>`,
+			],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Almost Destroy Lowerclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.lower.integrity to 1>>`
-			]
+			link: [`Almost Destroy Lowerclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.lower.integrity to 1>>`],
 		},
 		{
-			link: [
-				`Almost Destroy Upperclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.upper.integrity to 1>>`
-			]
+			link: [`Almost Destroy Upperclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.upper.integrity to 1>>`],
 		},
 		{
-			link: [
-				`Almost Destroy Underclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.under_lower.integrity to 1>>`
-			]
+			link: [`Almost Destroy Underclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.under_lower.integrity to 1>>`],
 		},
 		{
-			link: [
-				`Almost Destroy Underupperclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.under_upper.integrity to 1>>`
-			]
+			link: [`Almost Destroy Underupperclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.under_upper.integrity to 1>>`],
 		},
 		{
-			link: [
-				`Damage Lowerclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.lower.integrity -= 200>>`
-			]
+			link: [`Damage Lowerclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.lower.integrity -= 200>>`],
 		},
 		{
-			link: [
-				`Damage Upperclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.upper.integrity -= 200>>`
-			]
+			link: [`Damage Upperclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.upper.integrity -= 200>>`],
 		},
 		{
-			link: [
-				`Damage Underupperclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.under_upper.integrity -= 200>>`
-			]
+			link: [`Damage Underupperclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.under_upper.integrity -= 200>>`],
 		},
 		{
-			link: [
-				`Damage Underclothes`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.under_lower.integrity -= 200>>`
-			]
+			link: [`Damage Underclothes`, stayOnPassageFn],
+			widgets: [`<<set $worn.under_lower.integrity -= 200>>`],
 		},
 		{
-			link: [
-				`Damage Chastity`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $worn.genitals.integrity -= 5000>>`
-			]
+			link: [`Damage Chastity`, stayOnPassageFn],
+			widgets: [`<<set $worn.genitals.integrity -= 5000>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Cat up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $cat += 1>>`
-			]
+			link: [`Cat up`, stayOnPassageFn],
+			widgets: [`<<set $cat += 1>>`],
 		},
 		{
-			link: [
-				`Cat build up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $catbuild += 80>>`
-			]
+			link: [`Cat build up`, stayOnPassageFn],
+			widgets: [`<<set $catbuild += 80>>`],
 		},
 		{
-			link: [
-				`Cat off`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $cat = 0>>`
-			]
+			link: [`Cat off`, stayOnPassageFn],
+			widgets: [`<<set $cat = 0>>`],
 		},
 		{
-			link: [
-				`Wolf off`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $wolfgirl to 0>>`
-			]
+			link: [`Wolf off`, stayOnPassageFn],
+			widgets: [`<<set $wolfgirl to 0>>`],
 		},
 		{
-			link: [
-				`Wolf up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $wolfgirl += 1>>`
-			]
+			link: [`Wolf up`, stayOnPassageFn],
+			widgets: [`<<set $wolfgirl += 1>>`],
 		},
 		{
-			link: [
-				`Wolf build up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $wolfbuild += 40>>`
-			]
+			link: [`Wolf build up`, stayOnPassageFn],
+			widgets: [`<<set $wolfbuild += 40>>`],
 		},
 		{
-			link: [
-				`Wolf build down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $wolfbuild -= 40>>`
-			]
+			link: [`Wolf build down`, stayOnPassageFn],
+			widgets: [`<<set $wolfbuild -= 40>>`],
 		},
 		{
-			link: [
-				`Cow build up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $cowbuild += 40>>`
-			]
+			link: [`Cow build up`, stayOnPassageFn],
+			widgets: [`<<set $cowbuild += 40>>`],
 		},
 		{
-			link: [
-				`Cow build down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $cowbuild -= 40>>`
-			]
+			link: [`Cow build down`, stayOnPassageFn],
+			widgets: [`<<set $cowbuild -= 40>>`],
 		},
 		{
-			link: [
-				`Angel build up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $angelbuild += 40>>`
-			]
+			link: [`Angel build up`, stayOnPassageFn],
+			widgets: [`<<set $angelbuild += 40>>`],
 		},
 		{
-			link: [
-				`Angel build down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $angelbuild -= 40>>`
-			]
+			link: [`Angel build down`, stayOnPassageFn],
+			widgets: [`<<set $angelbuild -= 40>>`],
 		},
 		{
-			link: [
-				`Demon build up`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $demonbuild += 40>>`
-			]
+			link: [`Demon build up`, stayOnPassageFn],
+			widgets: [`<<set $demonbuild += 40>>`],
 		},
 		{
-			link: [
-				`Demon build down`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $demonbuild -= 40>>`
-			]
+			link: [`Demon build down`, stayOnPassageFn],
+			widgets: [`<<set $demonbuild -= 40>>`],
 		},
 		{
-			link: [
-				`Undertemp off`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $undertemp to 0>>`
-			]
+			link: [`Undertemp off`, stayOnPassageFn],
+			widgets: [`<<set $undertemp to 0>>`],
 		},
 		{
-			link: [
-				`Goo Me`, stayOnPassageFn
-			],
-			widgets: [
-				`<<drench "semen" "slime" 5>>`
-			]
+			link: [`Goo Me`, stayOnPassageFn],
+			widgets: [`<<drench "semen" "slime" 5>>`],
 		},
 		{
-			link: [
-				`Goo Me Small`, stayOnPassageFn
-			],
-			widgets: [
-				`<<drench "semen" "slime" 1>>`
-			]
+			link: [`Goo Me Small`, stayOnPassageFn],
+			widgets: [`<<drench "semen" "slime" 1>>`],
 		},
 		{
-			link: [
-				`Drench me`, stayOnPassageFn
-			],
+			link: [`Drench me`, stayOnPassageFn],
 			widgets: [
 				`<<set $upperwet to 200>>`,
 				`<<set $lowerwet to 200>>`,
 				`<<set $underupperwet to 200>>`,
-				`<<set $underlowerwet to 200>>`
-			]
+				`<<set $underlowerwet to 200>>`,
+			],
 		},
 		{
-			link: [
-				`Drench over-outfit only`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $overupperwet to 200>>`,
-				`<<set $overlowerwet to 200>>`
-			]
+			link: [`Drench over-outfit only`, stayOnPassageFn],
+			widgets: [`<<set $overupperwet to 200>>`, `<<set $overlowerwet to 200>>`],
 		},
 		{
-			link: [
-				`Drench middle-outfit only`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $upperwet to 200>>`,
-				`<<set $lowerwet to 200>>`
-			]
+			link: [`Drench middle-outfit only`, stayOnPassageFn],
+			widgets: [`<<set $upperwet to 200>>`, `<<set $lowerwet to 200>>`],
 		},
 		{
-			link: [
-				`Drench under-outfit only`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $underupperwet to 200>>`,
-				`<<set $underlowerwet to 200>>`
-			]
+			link: [`Drench under-outfit only`, stayOnPassageFn],
+			widgets: [`<<set $underupperwet to 200>>`, `<<set $underlowerwet to 200>>`],
 		},
 		{
-			link: [
-				`Soak me in water`, stayOnPassageFn
-			],
-			widgets: [
-				`<<water>>`
-			]
+			link: [`Soak me in water`, stayOnPassageFn],
+			widgets: [`<<water>>`],
 		},
 		{
-			link: [
-				`Bully Timer`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $bullytimer to 100>>`,
-				`<<set $bullytimeroutside to 100>>`
-			]
+			link: [`Bully Timer`, stayOnPassageFn],
+			widgets: [`<<set $bullytimer to 100>>`, `<<set $bullytimeroutside to 100>>`],
 		},
 		{
-			link: [
-				`Whitney Lower Dominance`, stayOnPassageFn
-			],
-			widgets: [
-				`<<npcincr Whitney dom -20>>`
-			]
+			link: [`Whitney Lower Dominance`, stayOnPassageFn],
+			widgets: [`<<npcincr Whitney dom -20>>`],
 		},
 		{
-			link: [
-				`Whitney Raise Dominance`, stayOnPassageFn
-			],
-			widgets: [
-				`<<npcincr Whitney dom 20>>`
-			]
+			link: [`Whitney Raise Dominance`, stayOnPassageFn],
+			widgets: [`<<npcincr Whitney dom 20>>`],
 		},
 		{
-			link: [
-				`Whitney Love`, stayOnPassageFn
-			],
-			widgets: [
-				`<<npcincr Whitney love 20>>`,
-				`<<npcincr Whitney lust 20>>`
-			]
+			link: [`Whitney Love`, stayOnPassageFn],
+			widgets: [`<<npcincr Whitney love 20>>`, `<<npcincr Whitney lust 20>>`],
 		},
 		{
-			link: [
-				`Whitney Romance`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $whitneyromance to 1>>`
-			]
+			link: [`Whitney Romance`, stayOnPassageFn],
+			widgets: [`<<set $whitneyromance to 1>>`],
 		},
 		{
-			link: [
-				`Pub Whore`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $pubwhore += 10>>`
-			]
+			link: [`Pub Whore`, stayOnPassageFn],
+			widgets: [`<<set $pubwhore += 10>>`],
 		},
 		{
-			link: [
-				`Make Creature`, stayOnPassageFn
-			],
-			widgets: [
-				`<<beasttype bear>>`
-			]
+			link: [`Make Creature`, stayOnPassageFn],
+			widgets: [`<<beasttype bear>>`],
 		},
 		{
-			link: [
-				`Full Spray`, stayOnPassageFn
-			],
-			widgets: [
-				`<<set $spraymax to 5>>`,
-				`<<spray 5>>`
-			]
+			link: [`Full Spray`, stayOnPassageFn],
+			widgets: [`<<set $spraymax to 5>>`, `<<spray 5>>`],
 		},
 		{
-			text_only: "\n\n"
+			text_only: "\n\n",
 		},
 		{
-			link: [
-				`Unlock all seeds`, stayOnPassageFn
-			],
-			widgets: [
-				`<<run unlockAllSeeds()>>`
-			]
+			link: [`Unlock all seeds`, stayOnPassageFn],
+			widgets: [`<<run unlockAllSeeds()>>`],
 		},
 		{
-			link: [
-				`Super Debug Character`, stayOnPassageFn
-			],
+			link: [`Super Debug Character`, stayOnPassageFn],
 			widgets: [
-				`<<set $school += 4000>>`,`<<set $science += 1000>>`,`<<set $maths += 1000>>`,`<<set $english += 1000>>`,`<<set $history += 1000>>`,`<<set $sciencetrait to 4>>`,
-				`<<set $mathstrait to 4>>`,`<<set $englishtrait to 4>>`,`<<set $historytrait to 4>>`,`<<set $skulduggery += 1000>>`,`<<set $danceskill += 1000>>`,
-				`<<set $swimmingskill += 1000>>`,`<<set $bottomskill += 1000>>`,`<<set $seductionskill += 1000>>`,`<<set $handskill += 1000>>`,`<<set $feetskill += 1000>>`,
-				`<<set $chestskill += 1000>>`,`<<set $thighskill += 1000>>`,`<<set $oralskill += 1000>>`,`<<set $analskill += 1000>>`,`<<set $vaginalskill += 1000>>`,
-				`<<set $penileskill += 1000>>`,`<<set $promiscuity += 100>>`,`<<set $exhibitionism += 100>>`,`<<set $deviancy += 100>>`,`<<set $awareness to 1000>>`,
-				`<<set $willpower to 1000>>`,`<<set $physique to 12000>>`,`<<set $orgasmtrait to 1>>`,`<<set $ejactrait to 1>>`,`<<set $molesttrait to 1>>`,
-				`<<set $rapetrait to 1>>`,`<<set $bestialitytrait to 1>>`,`<<set $tentacletrait to 1>>`,`<<set $choketrait to 1>>`
-			]
-		},
-		{
-			link: [
-				`Unlock all pills`, stayOnPassageFn
+				`<<set $school += 4000>>`,
+				`<<set $science += 1000>>`,
+				`<<set $maths += 1000>>`,
+				`<<set $english += 1000>>`,
+				`<<set $history += 1000>>`,
+				`<<set $sciencetrait to 4>>`,
+				`<<set $mathstrait to 4>>`,
+				`<<set $englishtrait to 4>>`,
+				`<<set $historytrait to 4>>`,
+				`<<set $skulduggery += 1000>>`,
+				`<<set $danceskill += 1000>>`,
+				`<<set $swimmingskill += 1000>>`,
+				`<<set $bottomskill += 1000>>`,
+				`<<set $seductionskill += 1000>>`,
+				`<<set $handskill += 1000>>`,
+				`<<set $feetskill += 1000>>`,
+				`<<set $chestskill += 1000>>`,
+				`<<set $thighskill += 1000>>`,
+				`<<set $oralskill += 1000>>`,
+				`<<set $analskill += 1000>>`,
+				`<<set $vaginalskill += 1000>>`,
+				`<<set $penileskill += 1000>>`,
+				`<<set $promiscuity += 100>>`,
+				`<<set $exhibitionism += 100>>`,
+				`<<set $deviancy += 100>>`,
+				`<<set $awareness to 1000>>`,
+				`<<set $willpower to 1000>>`,
+				`<<set $physique to 12000>>`,
+				`<<set $orgasmtrait to 1>>`,
+				`<<set $ejactrait to 1>>`,
+				`<<set $molesttrait to 1>>`,
+				`<<set $rapetrait to 1>>`,
+				`<<set $bestialitytrait to 1>>`,
+				`<<set $tentacletrait to 1>>`,
+				`<<set $choketrait to 1>>`,
 			],
-			widgets: [
-				`<<run window.getAllPills()>>`
-			]
-		}
+		},
+		{
+			link: [`Unlock all pills`, stayOnPassageFn],
+			widgets: [`<<run window.getAllPills()>>`],
+		},
 	],
-	Favourites: []
+	Favourites: [],
 };
 
-window.returnEventList = function(){
-	return setup.debugMenu.event_list
+function returnEventList() {
+	return setup.debugMenu.eventList;
 }
+window.returnEventList = returnEventList;
 
-window.getNameAndPassage = function(section, index){
-	if (typeof setup.debugMenu.event_list[section][index].link[0] == "function")
-		T.link_name = setup.debugMenu.event_list[section][index].link[0]();
-	else
-		T.link_name = setup.debugMenu.event_list[section][index].link[0];
-	if (typeof setup.debugMenu.event_list[section][index].link[1] == "function")
-		T.link_passage = setup.debugMenu.event_list[section][index].link[1]();
-	else
-		T.link_passage = setup.debugMenu.event_list[section][index].link[1];
+function getNameAndPassage(section, index) {
+	if (typeof setup.debugMenu.eventList[section][index].link[0] === "function")
+		T.link_name = setup.debugMenu.eventList[section][index].link[0]();
+	else T.link_name = setup.debugMenu.eventList[section][index].link[0];
+	if (typeof setup.debugMenu.eventList[section][index].link[1] === "function")
+		T.link_passage = setup.debugMenu.eventList[section][index].link[1]();
+	else T.link_passage = setup.debugMenu.eventList[section][index].link[1];
 }
+window.getNameAndPassage = getNameAndPassage;
 
-window.runWidgetsInsideLink = function(section, index){
+function runWidgetsInsideLink(section, index) {
 	let widget = 0;
-	for (widget in setup.debugMenu.event_list[section][index].widgets)
-		new Wikifier(null, (typeof setup.debugMenu.event_list[section][index].widgets[widget] == "function") ? setup.debugMenu.event_list[section][index].widgets[widget]() : setup.debugMenu.event_list[section][index].widgets[widget]);
+	for (widget in setup.debugMenu.eventList[section][index].widgets)
+		Wikifier.wikifyEval(
+			typeof setup.debugMenu.eventList[section][index].widgets[widget] === "function"
+				? setup.debugMenu.eventList[section][index].widgets[widget]()
+				: setup.debugMenu.eventList[section][index].widgets[widget]
+		);
 }
+window.runWidgetsInsideLink = runWidgetsInsideLink;
 
-window.changeBorderColor = function(){
-	let inputVal = document.getElementById("formChangeColor")
-	$(inputVal).toggleClass("searchBorderColour")
+function changeBorderColor() {
+	const inputVal = document.getElementById("formChangeColor");
+	$(inputVal).toggleClass("searchBorderColour");
 }
+window.changeBorderColor = changeBorderColor;
 
-var categories = ["debugEventsMain", "debugEventsCharacter", "debugEventsEvents"]
-var categories2 = ["debugMain", "debugCharacter", "debugEvents", "debugFavourites", "debugAdd"]
+// const categories = ["debugEventsMain", "debugEventsCharacter", "debugEventsEvents"];
+const categories2 = ["debugMain", "debugCharacter", "debugEvents", "debugFavourites", "debugAdd"];
 
-window.researchEvents = function(default_value){
-	$(function(){
-		var needle = (default_value != undefined) ? default_value : document.getElementById('searchEvents').value;
-		let list_events = [document.getElementById("debugEventsMain").getElementsByTagName("div"), document.getElementById("debugEventsMain").getElementsByTagName("br"), document.getElementById("debugEventsCharacter").getElementsByTagName("div"), document.getElementById("debugEventsCharacter").getElementsByTagName("br"), document.getElementById("debugEventsEvents").getElementsByTagName("div"), document.getElementById("debugEventsEvents").getElementsByTagName("br")];
+function researchEvents(defaultValue) {
+	$(function () {
+		let needle = defaultValue != null ? defaultValue : document.getElementById("searchEvents").value;
+		const eventsList = [
+			document.getElementById("debugEventsMain").getElementsByTagName("div"),
+			document.getElementById("debugEventsMain").getElementsByTagName("br"),
+			document.getElementById("debugEventsCharacter").getElementsByTagName("div"),
+			document.getElementById("debugEventsCharacter").getElementsByTagName("br"),
+			document.getElementById("debugEventsEvents").getElementsByTagName("div"),
+			document.getElementById("debugEventsEvents").getElementsByTagName("br"),
+		];
 
-		if (default_value != undefined)
-			document.getElementById('searchEvents').value = default_value
-		needle = needle.toLowerCase()
-		for (let i1 = 0; i1 < list_events.length; i1++){
-			for (let i2 = 0; i2 < list_events[i1].length; i2++){
-				let haystack = list_events[i1][i2].getAttribute("name")
+		if (defaultValue != null) document.getElementById("searchEvents").value = defaultValue;
+		needle = needle.toLowerCase();
+		for (let i1 = 0; i1 < eventsList.length; i1++) {
+			for (let i2 = 0; i2 < eventsList[i1].length; i2++) {
+				let haystack = eventsList[i1][i2].getAttribute("name");
 
-				if (haystack != null){
-					haystack = haystack.toLowerCase()
-					if (haystack.contains(needle) == false)
-						list_events[i1][i2].style.display = 'none'
-					else
-						list_events[i1][i2].style.display = ''
+				if (haystack != null) {
+					haystack = haystack.toLowerCase();
+					if (haystack.contains(needle) === false) eventsList[i1][i2].style.display = "none";
+					else eventsList[i1][i2].style.display = "";
 				}
 			}
 		}
-		if (needle != undefined && needle.length > 0){
-			document.getElementById("debugMain").classList.remove("hidden")
-			document.getElementById("debugCharacter").classList.remove("hidden")
-			document.getElementById("debugEvents").classList.remove("hidden")
-			document.getElementById("debugFavourites").classList.add("hidden")
-			document.getElementById("debugAdd").classList.add("hidden")
-		}
-		else if (V.debugMenu[2] != undefined && V.debugMenu[2].length > 0 && needle.length == 0) {
-			for (let divToHide of categories2){
-				if (divToHide != V.debugMenu[1])
-					document.getElementById(divToHide).classList.add("hidden")
-				else
-					document.getElementById(divToHide).classList.remove("hidden")
+		if (needle != null && needle.length > 0) {
+			document.getElementById("debugMain").classList.remove("hidden");
+			document.getElementById("debugCharacter").classList.remove("hidden");
+			document.getElementById("debugEvents").classList.remove("hidden");
+			document.getElementById("debugFavourites").classList.add("hidden");
+			document.getElementById("debugAdd").classList.add("hidden");
+		} else if (V.debugMenu[2] != null && V.debugMenu[2].length > 0 && needle.length === 0) {
+			for (const divToHide of categories2) {
+				if (divToHide !== V.debugMenu[1]) document.getElementById(divToHide).classList.add("hidden");
+				else document.getElementById(divToHide).classList.remove("hidden");
 			}
 		}
-		if ((V.debugMenu[1] == "debugAdd" || V.debugMenu[1] == "debugFavourites") && (needle == "" || needle == undefined)){
-			document.getElementById(V.debugMenu[1]).classList.remove("hidden")
+		if ((V.debugMenu[1] === "debugAdd" || V.debugMenu[1] === "debugFavourites") && (needle === "" || needle == null)) {
+			document.getElementById(V.debugMenu[1]).classList.remove("hidden");
 		}
-		V.debugMenu[2] = needle
-		window.toggleClassDebug(V.debugMenu[1]+"Button", "bg-color")
-		window.cacheDebugDiv()
+		V.debugMenu[2] = needle;
+		window.toggleClassDebug(V.debugMenu[1] + "Button", "bg-color");
+		window.cacheDebugDiv();
 	});
 }
+window.researchEvents = researchEvents;
 
-window.addFavouriteIcon = function(section, index, id){
-	$(function(){
-		if (V.debug_favourite == undefined){
-			V.debug_favourite = []
+function addFavouriteIcon(section, index, id) {
+	$(function () {
+		if (V.debug_favourite == null) {
+			V.debug_favourite = [];
 		}
-		window.syncFavourites()
-		var input = document.createElement("input");
-		var parent = document.getElementById(id);
+		window.syncFavourites();
+		const input = document.createElement("input");
+		const parent = document.getElementById(id);
 
-		input.type = "image"
-		input.className = "heart"
-		input.src = "img/ui/heart_favourite.svg"
-		for (let i = 0; i < V.debug_favourite.length; i++){
-			if (V.debug_favourite[i].link[0] == setup.debugMenu.event_list[section][index].link[0])
-				input.classList.toggle('liked'); // on load up if already favourite set heart red
+		input.type = "image";
+		input.className = "heart";
+		input.src = "img/ui/heart_favourite.svg";
+		for (let i = 0; i < V.debug_favourite.length; i++) {
+			if (V.debug_favourite[i].link[0] === setup.debugMenu.eventList[section][index].link[0]) input.classList.toggle("liked"); // on load up if already favourite set heart red
 		}
-		input.setAttribute("onclick","window.onClickFavourite('"+section+"',"+index+",'"+id+"');");
-		if (parent != null)
-			parent.appendChild(input);
+		input.setAttribute("onclick", "window.onClickFavourite('" + section + "'," + index + ",'" + id + "');");
+		if (parent != null) parent.appendChild(input);
 	});
 }
+window.addFavouriteIcon = addFavouriteIcon;
 
-window.onClickFavourite = function(section, index, id) {
-	$(function(){
-	window.syncFavourites()
-	let element_clicked = document.getElementById(id).children[1];
-	if (element_clicked.classList.contains("liked")){
-		for (let i = 0; i < V.debug_favourite.length; i++){
-			if (V.debug_favourite[i].link[0] == setup.debugMenu.event_list[section][index].link[0])
-				V.debug_favourite.splice(i, 1); // remove from favourites
-		}
-		setup.debugMenu.event_list.Favourites = V.debug_favourite // sync constant to ephemere variable
-		element_clicked.classList.toggle('liked'); // removes favourites css
-	}
-	else{
-		let fav_object = {
-			link: setup.debugMenu.event_list[section][index].link,
-			widgets: setup.debugMenu.event_list[section][index].widgets,
-			condition: (setup.debugMenu.event_list[section][index].condition != undefined) ? setup.debugMenu.event_list[section][index].condition : 1
+function onClickFavourite(section, index, id) {
+	$(function () {
+		window.syncFavourites();
+		const elementClicked = document.getElementById(id).children[1];
+		if (elementClicked.classList.contains("liked")) {
+			for (let i = 0; i < V.debug_favourite.length; i++) {
+				if (V.debug_favourite[i].link[0] === setup.debugMenu.eventList[section][index].link[0]) V.debug_favourite.splice(i, 1); // remove from favourites
+			}
+			setup.debugMenu.eventList.Favourites = V.debug_favourite; // sync constant to ephemere variable
+			elementClicked.classList.toggle("liked"); // removes favourites css
+		} else {
+			const favObject = {
+				link: setup.debugMenu.eventList[section][index].link,
+				widgets: setup.debugMenu.eventList[section][index].widgets,
+				condition:
+					setup.debugMenu.eventList[section][index].condition != null ? setup.debugMenu.eventList[section][index].condition : 1,
+			};
+			V.debug_favourite.push(favObject); // constant variable
+			setup.debugMenu.eventList.Favourites = V.debug_favourite;
+			elementClicked.classList.toggle("liked"); // add favourites
 		}
-		V.debug_favourite.push(fav_object) // constant variable
-		setup.debugMenu.event_list.Favourites = V.debug_favourite
-		element_clicked.classList.toggle('liked'); // add favourites
-	}
-	if (section == "Favourites"){
-		let to_search = document.getElementById("Favourites-"+index).children[0].text;
-		let break_signal = 0;
-		for (let cat of ["debugEventsEvents", "debugEventsMain", "debugEventsCharacter"]){
-			let div_search = document.getElementById(cat).children
-			for (let div of div_search){
-				if (div.getAttribute("name") == to_search){
-					div.children[1].classList.remove("liked")
-					break_signal = 1
-					break
+		if (section === "Favourites") {
+			const toSearch = document.getElementById("Favourites-" + index).children[0].text;
+			let breakSignal = 0;
+			for (const cat of ["debugEventsEvents", "debugEventsMain", "debugEventsCharacter"]) {
+				const divSearch = document.getElementById(cat).children;
+				for (const div of divSearch) {
+					if (div.getAttribute("name") === toSearch) {
+						div.children[1].classList.remove("liked");
+						breakSignal = 1;
+						break;
+					}
 				}
+				if (breakSignal) break;
 			}
-			if (break_signal)
-				break
 		}
-	}
-	new Wikifier(null, `<<debugFavourites "replace">>`)
+		Wikifier.wikifyEval(`<<debugFavourites "replace">>`);
 	});
 	window.cacheDebugDiv();
 }
+window.onClickFavourite = onClickFavourite;
 
-window.syncFavourites = function(){
-	setup.debugMenu.event_list.Favourites = V.debug_favourite
+function syncFavourites() {
+	setup.debugMenu.eventList.Favourites = V.debug_favourite;
 }
+window.syncFavourites = syncFavourites;
 
-window.cacheDebugDiv = function() {
+function cacheDebugDiv() {
 	$(() => {
 		const overlay = document.getElementById("debugOverlay");
-		if (overlay instanceof HTMLElement){
-			let div = overlay.outerHTML
+		if (overlay instanceof HTMLElement) {
+			const div = overlay.outerHTML;
 			setup.debugMenu.cacheDebugDiv.debugOverlay = div;
 		}
 	});
 }
+window.cacheDebugDiv = cacheDebugDiv;
 
-window.loadCachedDebugDiv = function() {
-	if (typeof setup.debugMenu.cacheDebugDiv.debugOverlay != undefined) {
+function loadCachedDebugDiv() {
+	if (typeof setup.debugMenu.cacheDebugDiv.debugOverlay !== "undefined") {
 		document.getElementById("debugOverlay").outerHTML = setup.debugMenu.cacheDebugDiv.debugOverlay;
 	}
 	window.patchDebugMenu();
 }
+window.loadCachedDebugDiv = loadCachedDebugDiv;
 
-window.debugCreateLinkAndRedirect = function(section, index, id) {
-	$(function(){
-	let target = document.getElementById(id).children[0]
-	if (typeof $._data($(target).get(0), "events") == "undefined" || $._data($(target).get(0), "events").length == 0){
-		let passage_title = (typeof setup.debugMenu.event_list[section][index].link[0] == "function") ? setup.debugMenu.event_list[section][index].link[0]() : setup.debugMenu.event_list[section][index].link[0]
-		let passage_name = (typeof setup.debugMenu.event_list[section][index].link[1] == "function") ? setup.debugMenu.event_list[section][index].link[1]() : setup.debugMenu.event_list[section][index].link[1]
-		let widgets = ''
+function debugCreateLinkAndRedirect(section, index, id) {
+	$(function () {
+		const target = document.getElementById(id).children[0];
+		if (typeof $._data($(target).get(0), "events") === "undefined" || $._data($(target).get(0), "events").length === 0) {
+			const passageTitle =
+				typeof setup.debugMenu.eventList[section][index].link[0] === "function"
+					? setup.debugMenu.eventList[section][index].link[0]()
+					: setup.debugMenu.eventList[section][index].link[0];
+			const passageName =
+				typeof setup.debugMenu.eventList[section][index].link[1] === "function"
+					? setup.debugMenu.eventList[section][index].link[1]()
+					: setup.debugMenu.eventList[section][index].link[1];
+			let widgets = "";
 
-		for (let widget of setup.debugMenu.event_list[section][index].widgets)
-			widgets += (typeof widget == "function") ? widget() : widget
-		let new_link = new Wikifier(null, `<<link [[`+passage_title+`|`+passage_name+`]]>>` + widgets + `<</link>>`)
-		new_link.output.children[0].click()
-	}
+			for (const widget of setup.debugMenu.eventList[section][index].widgets)
+				widgets += typeof widget === "function" ? widget() : widget;
+			const newLink = new Wikifier(null, `<<link [[` + passageTitle + `|` + passageName + `]]>>` + widgets + `<</link>>`);
+			newLink.output.children[0].click();
+		}
 	});
 }
+window.debugCreateLinkAndRedirect = debugCreateLinkAndRedirect;
 
-window.addonClickDivPassage = function(section, index, id) {
-	$(function() {
-		let target = document.getElementById(id).children[0]
-		target.setAttribute("onclick", "window.debugCreateLinkAndRedirect("+"'"+section+"'"+","+index+","+"'"+section+"-"+index+"'"+");");
+function addonClickDivPassage(section, index, id) {
+	$(function () {
+		const target = document.getElementById(id).children[0];
+		target.setAttribute(
+			"onclick",
+			"window.debugCreateLinkAndRedirect(" + "'" + section + "'" + "," + index + "," + "'" + section + "-" + index + "'" + ");"
+		);
 	});
 }
+window.addonClickDivPassage = addonClickDivPassage;
 
-window.toggleClassDebug = function(selected, mode) {
-	$(function(){
-	if (document.getElementById(selected) == null)
-		return
-	var list = ["debugMain", "debugCharacter", "debugEvents", "debugFavourites", "debugAdd"]
-	if (mode == "bg-color"){
-		for (let div of list){
-			if (div+"Button" == selected)
-				document.getElementById(selected).classList.add("bg-color-debug-selected");
-			else
-				document.getElementById(div+"Button").classList.remove("bg-color-debug-selected");
-		}
-	}
-	else if (mode == "hideWhileSearching"){
-		if (selected == "debugFavourites" || selected == "debugAdd"){
-			for (let div of list)
-				(div != "debugFavourites" || div != "debugAdd") ? document.getElementById(div).classList.add("hidden") : document.getElementById(div).classList.remove("hidden");
-		}
-		else{
-			for (let div of list)
-				(div == "debugFavourites" || div == "debugAdd") ? document.getElementById(div).classList.add("hidden") : document.getElementById(div).classList.remove("hidden");
+function toggleClassDebug(selected, mode) {
+	$(function () {
+		if (document.getElementById(selected) == null) return;
+		const list = ["debugMain", "debugCharacter", "debugEvents", "debugFavourites", "debugAdd"];
+		if (mode === "bg-color") {
+			for (const div of list) {
+				if (div + "Button" === selected) document.getElementById(selected).classList.add("bg-color-debug-selected");
+				else document.getElementById(div + "Button").classList.remove("bg-color-debug-selected");
+			}
+		} else if (mode === "hideWhileSearching") {
+			if (selected === "debugFavourites" || selected === "debugAdd") {
+				for (const div of list)
+					div !== "debugFavourites" || div !== "debugAdd"
+						? document.getElementById(div).classList.add("hidden")
+						: document.getElementById(div).classList.remove("hidden");
+			} else {
+				for (const div of list)
+					div === "debugFavourites" || div === "debugAdd"
+						? document.getElementById(div).classList.add("hidden")
+						: document.getElementById(div).classList.remove("hidden");
+			}
+		} else if (mode === "classicHide") {
+			for (const div of list)
+				div !== selected
+					? document.getElementById(div).classList.add("hidden")
+					: document.getElementById(div).classList.remove("hidden");
 		}
-	}
-	else if (mode == "classicHide"){
-		for (let div of list)
-				(div != selected) ? document.getElementById(div).classList.add("hidden") : document.getElementById(div).classList.remove("hidden");
-	}
-});
+	});
 }
+window.toggleClassDebug = toggleClassDebug;
 
-window.patchDebugMenu = function() {
-	let catg = ["debugEventsMain", "debugEventsCharacter", "debugEventsEvents", "debugEventsFavourites"]
-	let break_if_all_good;
+function patchDebugMenu() {
+	const catg = ["debugEventsMain", "debugEventsCharacter", "debugEventsEvents", "debugEventsFavourites"];
+	let breakIfAllGood;
 
-	for (let cat of catg){
+	for (const cat of catg) {
 		let haystack = document.getElementById(cat);
-		if (haystack == null)
-			return;
-		else
-			haystack = haystack.children
-		for (let i = 0; i < haystack.length; i++){
-			let value = haystack[i].id
+		if (haystack == null) return;
+		else haystack = haystack.children;
+		for (let i = 0; i < haystack.length; i++) {
+			const value = haystack[i].id;
 
-			break_if_all_good = 0;
-			if (haystack[i].children.length < 1)
-				break
-			if (haystack[i].children.length < 2)
-				window.addFavouriteIcon(value.split('-')[0],value.split('-')[1],value)
-			else
-				break_if_all_good += 1;
+			breakIfAllGood = 0;
+			if (haystack[i].children.length < 1) break;
+			if (haystack[i].children.length < 2) window.addFavouriteIcon(value.split("-")[0], value.split("-")[1], value);
+			else breakIfAllGood += 1;
 			if (haystack[i].children[0].getAttribute("onclick") == null)
-				haystack[i].children[0].setAttribute("onclick","window.debugCreateLinkAndRedirect('"+value.split('-')[0]+"',"+value.split('-')[1]+",'"+value+"');");
-			else
-				break_if_all_good += 1;
-			if (break_if_all_good == 2)
-				break
+				haystack[i].children[0].setAttribute(
+					"onclick",
+					"window.debugCreateLinkAndRedirect('" + value.split("-")[0] + "'," + value.split("-")[1] + ",'" + value + "');"
+				);
+			else breakIfAllGood += 1;
+			if (breakIfAllGood === 2) break;
 		}
 	}
-	document.getElementById("MainDebugInfo").innerHTML = "Allure: "+V.allure+"<br>Rng: "+V.rng+"<br>Danger: "+V.danger+"<br>Passage: "+V.passage+"<br>";
+	document.getElementById("MainDebugInfo").innerHTML =
+		"Allure: " + V.allure + "<br>Rng: " + V.rng + "<br>Danger: " + V.danger + "<br>Passage: " + V.passage + "<br>";
 	window.cacheDebugDiv();
 }
+window.patchDebugMenu = patchDebugMenu;
 
-window.checkEventCondition = function() {
-	$(function() {
-		for (let section of ["Character", "Events", "Favourites", "Main"]){
-			let ev = setup.debugMenu.event_list[section]
-			for (let i in ev){
-				if (ev[i].hasOwnProperty("condition")){
-					if ((typeof ev[i].condition == "function" && ev[i].condition() == 1) || ((typeof ev[i].condition != "function" && ev[i].condition == 1))){
-						if (document.getElementById(section+'-'+i) == null)
-							return
-						document.getElementById(section+'-'+i).classList.remove("condhide")
-					}
-					else{
-						if (document.getElementById(section+'-'+i) == null)
-							return
-						document.getElementById(section+'-'+i).classList.add("condhide")
+function checkEventCondition() {
+	$(function () {
+		for (const section of ["Character", "Events", "Favourites", "Main"]) {
+			const ev = setup.debugMenu.eventList[section];
+			for (const i in ev) {
+				if (ev[i].hasOwnProperty("condition")) {
+					if (
+						(typeof ev[i].condition === "function" && ev[i].condition() === 1) ||
+						(typeof ev[i].condition !== "function" && ev[i].condition === 1)
+					) {
+						if (document.getElementById(section + "-" + i) == null) return;
+						document.getElementById(section + "-" + i).classList.remove("condhide");
+					} else {
+						if (document.getElementById(section + "-" + i) == null) return;
+						document.getElementById(section + "-" + i).classList.add("condhide");
 					}
 				}
 			}
 		}
 	});
 }
+window.checkEventCondition = checkEventCondition;
 
-window.addDebugForm = function() {
-	$(function() {
-	let op = ''
-	if (V.debug_custom_events == undefined)
-		V.debug_custom_events = {Main:[], Character:[], Events:[]}
-	for (let section of ["Main", "Character", "Events"]){
-		for (let ev of V.debug_custom_events[section])
-			op += "<option value=" +'"'+ev.link[0]+'" '+">"+ev.link[0]+"</option>";
-	}
-	if (document.getElementById("debugEventsAdd") != null)
-		document.getElementById("debugEventsAdd").innerHTML = `
+function addDebugForm() {
+	$(function () {
+		let op = "";
+		if (V.debug_custom_events == null) V.debug_custom_events = { Main: [], Character: [], Events: [] };
+		for (const section of ["Main", "Character", "Events"]) {
+			for (const ev of V.debug_custom_events[section])
+				op += "<option value=" + '"' + ev.link[0] + '" ' + ">" + ev.link[0] + "</option>";
+		}
+		if (document.getElementById("debugEventsAdd") != null)
+			document.getElementById("debugEventsAdd").innerHTML =
+				`
 		<abbr>Event Title:</abbr>
 		<div class="addevent-content-search-content" id="formChangeColor2" style="">
 			<input name="addEvents" id="addEventsTitle" placeholder="Event Title..." onfocusout="" onfocus="" oninput="" />
@@ -3066,106 +1873,114 @@ window.addDebugForm = function() {
 		<div id="debugRemovePassage">
 			<h3>Remove passages from the Menu</h3>
 			<select name="catlist" id="debugEvList">
-			`+
-			op
-			+
-			`</select><br><br>
+			` +
+				op +
+				`</select><br><br>
 			<button type="button" id="button-remove" onclick="window.removeDebugCustomPassage()">Remove</button><br><br>
 			<div id="debugRemoveResult"></div>
 		</div>
-	`
+	`;
 	});
 }
+window.addDebugForm = addDebugForm;
 
-window.submitNewDebugPassage = function() {
-	let input_list = [document.getElementById("addEventsTitle"), document.getElementById("addEventsPassage"), document.getElementById("addEventsWidgets"), document.getElementById("debugCatList")]
+function submitNewDebugPassage() {
+	const inputList = [
+		document.getElementById("addEventsTitle"),
+		document.getElementById("addEventsPassage"),
+		document.getElementById("addEventsWidgets"),
+		document.getElementById("debugCatList"),
+	];
 	let sigerror = 0;
 
-	for (let element of input_list){
-		if ((element.id == "addEventsTitle" || element.id == "addEventsPassage" || element.id == "debugCatList") && element.value.length < 1){
+	for (const element of inputList) {
+		if (
+			(element.id === "addEventsTitle" || element.id === "addEventsPassage" || element.id === "debugCatList") &&
+			element.value.length < 1
+		) {
 			element.setCustomValidity("Fill this value!");
 			element.reportValidity();
-			document.getElementById("debugAddResult").innerHTML = ''
-			sigerror = 1
+			document.getElementById("debugAddResult").innerHTML = "";
+			sigerror = 1;
 		}
-		if (element.id == "addEventsWidgets" && element.value.length > 0){
-			let match = element.value.match('<<.+>>{0,}')
+		if (element.id === "addEventsWidgets" && element.value.length > 0) {
+			const match = element.value.match("<<.+>>{0,}");
 
-			if (match == null || match[0] != match.input){
+			if (match == null || match[0] !== match.input) {
 				element.setCustomValidity("Invalid widget format. Valid : <<widget @params>>");
 				element.reportValidity();
-				document.getElementById("debugAddResult").innerHTML = ''
-				sigerror = 1
+				document.getElementById("debugAddResult").innerHTML = "";
+				sigerror = 1;
 			}
 		}
 	}
-	for (let section of ["Character", "Events", "Favourites", "Main"]) {
-		for (let ev of setup.debugMenu.event_list[section]) {
-			if (ev.hasOwnProperty("link") && ev.link[0] == input_list[0].value) {
-				input_list[0].setCustomValidity("This event title already exists. It needs to be unique!");
-				input_list[0].reportValidity();
-				document.getElementById("debugAddResult").innerHTML = '';
+	for (const section of ["Character", "Events", "Favourites", "Main"]) {
+		for (const ev of setup.debugMenu.eventList[section]) {
+			if (ev.hasOwnProperty("link") && ev.link[0] === inputList[0].value) {
+				inputList[0].setCustomValidity("This event title already exists. It needs to be unique!");
+				inputList[0].reportValidity();
+				document.getElementById("debugAddResult").innerHTML = "";
 				sigerror = 1;
 			}
 		}
 	}
-	if (sigerror == 0) {
-		if (V.debug_custom_events == undefined)
-			V.debug_custom_events = {Main:[], Character:[], Events:[]}
-		let event_title = input_list[0].value
-		let passage_name = input_list[1].value.match(/function{1}[ \t]{0,1}\(\)[ \t]{0,2}{.*return.*}[;]{0,1}/g) == null ? input_list[1].value : eval("("+input_list[1].value.match(/function{1}[ \t]{0,1}\(\)[ \t]{0,2}{.*return.*}[;]{0,1}/g)[0]+")")
-		let new_obj = {
-			link: [
-				event_title, passage_name
-			],
-			widgets: [
-				input_list[2].value
-			]
-		}
-		V.debug_custom_events[input_list[3].value].unshift(new_obj)
-		setup.debugMenu.event_list[input_list[3].value].unshift(new_obj)
-		document.getElementById("debugAddResult").innerHTML = '<span style="color: #5eac5e;">Event Added<br>Click any blue regular link in-game<br>for changes to apply.<br>(No reload, No links in debug menu)</span>'
+	if (sigerror === 0) {
+		if (V.debug_custom_events == null) V.debug_custom_events = { Main: [], Character: [], Events: [] };
+		const eventTitle = inputList[0].value;
+		const passageName =
+			inputList[1].value.match(/function{1}[ \t]{0,1}\(\)[ \t]{0,2}{.*return.*}[;]{0,1}/g) == null
+				? inputList[1].value
+				: eval("(" + inputList[1].value.match(/function{1}[ \t]{0,1}\(\)[ \t]{0,2}{.*return.*}[;]{0,1}/g)[0] + ")");
+		const newObj = {
+			link: [eventTitle, passageName],
+			widgets: [inputList[2].value],
+		};
+		V.debug_custom_events[inputList[3].value].unshift(newObj);
+		setup.debugMenu.eventList[inputList[3].value].unshift(newObj);
+		document.getElementById("debugAddResult").innerHTML =
+			'<span style="color: #5eac5e;">Event Added<br>Click any blue regular link in-game<br>for changes to apply.<br>(No reload, No links in debug menu)</span>';
 		setup.debugMenu.cacheDebugDiv = {};
 	}
 }
+window.submitNewDebugPassage = submitNewDebugPassage;
 
-window.syncDebugAddedEvents = function() {
-	if (V.debug_custom_events == undefined)
-		V.debug_custom_events = {Main:[], Character:[], Events:[]};
-	for (let section of ["Main", "Character", "Events"]) {
-		if (V.debug_custom_events.hasOwnProperty(section) == false)
-			V.debug_custom_events[section] = [];
-		for (let ev of V.debug_custom_events[section])
-			setup.debugMenu.event_list[section].unshift(ev);
+function syncDebugAddedEvents() {
+	if (V.debug_custom_events == null) V.debug_custom_events = { Main: [], Character: [], Events: [] };
+	for (const section of ["Main", "Character", "Events"]) {
+		if (V.debug_custom_events.hasOwnProperty(section) === false) V.debug_custom_events[section] = [];
+		for (const ev of V.debug_custom_events[section]) setup.debugMenu.eventList[section].unshift(ev);
 	}
 }
+window.syncDebugAddedEvents = syncDebugAddedEvents;
 
-window.removeDebugCustomPassage = function() {
-	let selected_for_removal = document.getElementById("debugEvList").value
-	let exit_code = 0
-	for (let section of ["Main", "Character", "Events"]){
-		for (let ev in V.debug_custom_events[section]){
-			if (V.debug_custom_events[section][ev].link[0] == selected_for_removal)
-				V.debug_custom_events[section].splice(ev, 1)
-			for (let ev2 in setup.debugMenu.event_list[section]){
-				if (setup.debugMenu.event_list[section][ev2].hasOwnProperty("link") && setup.debugMenu.event_list[section][ev2].link[0] == selected_for_removal){
-					setup.debugMenu.event_list[section].splice(ev2, 1)
-					document.getElementById("debugRemoveResult").innerHTML = '<span style="color: #5eac5e;">Event Removed<br>Click any blue regular link in-game<br>for changes to apply.<br>(No reload, No links in debug menu)</span>'
-					let op = '<br>'
-					for (let section of ["Main", "Character", "Events"]){
-						for (let ev of V.debug_custom_events[section])
-							op += "<option value=" +'"'+ev.link[0]+'" '+">"+ev.link[0]+"</option>";
+function removeDebugCustomPassage() {
+	const selectedForRemoval = document.getElementById("debugEvList").value;
+	let exitCode = 0;
+	for (const section of ["Main", "Character", "Events"]) {
+		for (const ev in V.debug_custom_events[section]) {
+			if (V.debug_custom_events[section][ev].link[0] === selectedForRemoval) V.debug_custom_events[section].splice(ev, 1);
+			for (const ev2 in setup.debugMenu.eventList[section]) {
+				if (
+					setup.debugMenu.eventList[section][ev2].hasOwnProperty("link") &&
+					setup.debugMenu.eventList[section][ev2].link[0] === selectedForRemoval
+				) {
+					setup.debugMenu.eventList[section].splice(ev2, 1);
+					document.getElementById("debugRemoveResult").innerHTML =
+						'<span style="color: #5eac5e;">Event Removed<br>Click any blue regular link in-game<br>for changes to apply.<br>(No reload, No links in debug menu)</span>';
+					let op = "<br>";
+					for (const section of ["Main", "Character", "Events"]) {
+						for (const ev of V.debug_custom_events[section])
+							op += "<option value=" + '"' + ev.link[0] + '" ' + ">" + ev.link[0] + "</option>";
 					}
-					document.getElementById("debugEvList").innerHTML = op
+					document.getElementById("debugEvList").innerHTML = op;
 					setup.debugMenu.cacheDebugDiv = {};
-					exit_code = 1;
+					exitCode = 1;
 					break;
 				}
 			}
-			if (exit_code == 1)
-				break;
+			if (exitCode === 1) break;
 		}
-		if (exit_code == 1)
-			break;
+		if (exitCode === 1) break;
 	}
 }
+window.removeDebugCustomPassage = removeDebugCustomPassage;
diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index 893ae71cc8..aee93ad674 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -1,594 +1,499 @@
-window.mapMove = function (moveTo) {
-	var currentPassage = V.passage;
-	var destination_table = [];
-	for (var i = 1; i < V.link_table.length; i++) {
-		var temp = V.link_table[i].split("|")[1];
+/* eslint-disable dot-notation */
+function mapMove(moveTo) {
+	const currentPassage = V.passage;
+	const destinationTable = [];
+	for (let i = 1; i < V.link_table.length; i++) {
+		const temp = V.link_table[i].split("|")[1];
 		if (temp) {
-			destination_table[destination_table.length] = temp.split("]]")[0];
+			destinationTable.push(temp.split("]]")[0]);
 		}
 	}
-	var available = V.map.available;
-
-	if (V.debug == 1 || available[currentPassage].includes(moveTo) && destination_table.includes(moveTo))
-	//if(V.debug == 1 || available[currentPassage].includes(moveTo))
-	{
-		new Wikifier(null, '<<pass 5>>');
+	const available = V.map.available;
+
+	// if(V.debug == 1 || available[currentPassage].includes(moveTo))
+	if (
+		V.debug === 1 ||
+		(available[currentPassage].includes(moveTo) && destinationTable.includes(moveTo))
+	) {
+		Wikifier.wikifyEval("<<pass 5>>");
 		SugarCube.State.display(moveTo);
 	}
 }
+window.mapMove = mapMove;
 
-window.shopClothingFilterToggleTrait = function(trait) {
-	let traits = V.shopClothingFilter.traits;
+function shopClothingFilterToggleTrait(trait) {
+	const traits = V.shopClothingFilter.traits;
 	if (traits) {
-		let index = traits.indexOf(trait)
-		if (index == -1) {
-			traits.push(trait)
+		const index = traits.indexOf(trait);
+		if (index === -1) {
+			traits.push(trait);
 		} else {
-			traits.splice(index, 1)
+			traits.splice(index, 1);
 		}
 	}
 }
+window.shopClothingFilterToggleTrait = shopClothingFilterToggleTrait;
 
-window.shopClothingFilterSortOnDescription = function(traitOne, traitTwo) {
-	let descriptionOne = Wikifier.wikifyEval(`<<shopTraitDescription ${traitOne}>>`).textContent.trim();
-	let descriptionTwo = Wikifier.wikifyEval(`<<shopTraitDescription ${traitTwo}>>`).textContent.trim();
+function shopClothingFilterSortOnDescription(traitOne, traitTwo) {
+	const descriptionOne = Wikifier.wikifyEval(
+		`<<shopTraitDescription ${traitOne}>>`
+	).textContent.trim();
+	const descriptionTwo = Wikifier.wikifyEval(
+		`<<shopTraitDescription ${traitTwo}>>`
+	).textContent.trim();
 
-	return descriptionOne > descriptionTwo
+	return descriptionOne > descriptionTwo;
 }
+window.shopClothingFilterSortOnDescription = shopClothingFilterSortOnDescription;
 
 window.wikifier = function (widget, arg1, arg2, arg3) {
 	if (arg3 !== undefined) {
-		new Wikifier(null, '<<' + widget + ' ' + arg1 + ' ' + arg2 + ' ' + arg3 + '>>');
-	}
-	else if (arg2 !== undefined) {
-		new Wikifier(null, '<<' + widget + ' ' + arg1 + ' ' + arg2 + '>>');
-	}
-	else if (arg1 !== undefined) {
-		new Wikifier(null, '<<' + widget + ' ' + arg1 + '>>');
-	}
-	else if (arg1 === undefined) {
-		new Wikifier(null, '<<' + widget + '>>');
+		Wikifier.wikifyEval("<<" + widget + " " + arg1 + " " + arg2 + " " + arg3 + ">>");
+	} else if (arg2 !== undefined) {
+		Wikifier.wikifyEval("<<" + widget + " " + arg1 + " " + arg2 + ">>");
+	} else if (arg1 !== undefined) {
+		Wikifier.wikifyEval("<<" + widget + " " + arg1 + ">>");
+	} else if (arg1 === undefined) {
+		Wikifier.wikifyEval("<<" + widget + ">>");
 	}
-}
+};
 
 window.wikifier2 = function (str) {
+	// eslint-disable-next-line no-new
 	new Wikifier(null, str);
-}
-
-window.actionsreplace = function (bodypart) {
-	var check = bodypart+"target";
-	if (V[check] == "tentacles"){
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInitTentacle>><</replace>>');
-	}else if (V[check] == "swarm"){
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInitSwarm>><</replace>>');
-	}else if (V[check] == "vore"){
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInitVore>><</replace>>');
-	}else if (V[check] == "struggle"){
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInitStruggle>><</replace>>');
-	}else if (V[check] == "machine"){
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInitMachine>><</replace>>');
-	}else if (V[check] == "self"){
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInitSelf>><</replace>>');
-	}else{
-		new Wikifier(null, '<<replace #'+ bodypart + 'action>><<'+ bodypart + 'ActionInit>><</replace>>');
-	}
-}
+};
 
-window.combatListColor = function (name, value, type) {
-	var color = "";
-	var check = "";
-	if (value != undefined) {
-		check = value;
+function actionsreplace(bodypart) {
+	const check = bodypart + "target";
+	if (V[check] === "tentacles") {
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInitTentacle>><</replace>>"
+		);
+	} else if (V[check] === "swarm") {
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInitSwarm>><</replace>>"
+		);
+	} else if (V[check] === "vore") {
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInitVore>><</replace>>"
+		);
+	} else if (V[check] === "struggle") {
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInitStruggle>><</replace>>"
+		);
+	} else if (V[check] === "machine") {
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInitMachine>><</replace>>"
+		);
+	} else if (V[check] === "self") {
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInitSelf>><</replace>>"
+		);
 	} else {
-		check = V[name];
-	}
-	if (type === "") {
-		switch (check) {
-			/*leftaction or rightaction*/
-			case "steal": case "penwhack": case "freeface": case "leftcovervagina": case "leftcoverpenis": case "leftcoveranus":
-			case "rightcovervagina": case "rightcoverpenis": case "rightcoveranus":
-			case "leftunderpull": case "leftskirtpull": case "leftlowerpull": case "leftupperpull":
-			case "rightunderpull": case "rightskirtpull": case "rightlowerpull": case "rightupperpull": case "rightUndressOther": case "leftUndressOther":
-			case "stopchoke": case "clench": case "shacklewhack": case "leftfold": case "rightfold": case "dildowhack": case "hypnosiswhack":
-			case "leftstruggleweak": case "rightstruggleweak":
-			case "leftresistW": case "rightresistW": case "leftstillW": case "rightstillW":
-			/*feetaction*/
-			case "run": case "hide": case "confront": case "feetresistW":
-			/*mouthaction*/
-			case "pullaway": case "pullawayvagina": case "finish": case "novaginal": case "nopenile": case "noanal": case "scream":
-			case "mock": case "breastclosed": case "breastpull": case "pullawaykiss": case "noupper":
-			case "up": case "stifleorgasm": case "stifle":
-			case "mouthresistW": case "handcloseW":
-			/*penisaction*/
-			case "othermouthescape": case "escape": case "otheranusescape": case "fencingescape" :
-			/*vaginaaction*/
-			case "tribescape":
-			/*anusaction*/
-			case "doubleescape":
-				color = "brat";
-				break;
-
-			/*leftaction or rightaction*/
-			case "spray": case "lefthit": case "righthit": case "leftstruggle": case "rightstruggle": case "stopchokenoncon": case "pursuit_grab":
-			/*feetaction*/
-			case "kick":
-			/*mouthaction*/
-			case "bite": case "demand": case "breastbite": case "handbite": case "headbutt": case "bitepussy":
-				color = "def";
-				break;
-			/*leftaction or rightaction*/
-			case "behind": case "fold":
-			case "leftcovervaginameek": case "leftcoverpenismeek": case "leftcoveranusmeek":
-			case "rightcovervaginameek": case "rightcoverpenismeek": case "rightcoveranusmeek":
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip":
-			case "leftcurl": case "rightcurl": case "pickupSexToy": case "leftcamerapose": case "rightcamerapose":
-			/*mouthaction*/
-			case "grasp": case "plead": case "forgive": case "down":
-			case "letout": case "letoutorgasm": case "noises": case "pay":
-			/*penisaction*/
-			case "thighbay": case "bay": case "otheranusbay":
-			/*vaginaaction*/
-			case "penisthighs":
-			/*anusaction*/
-			case "bottombay": case "penischeeks": case "penispussy": case "penispussydap": case "penisanus": case "bottomhandbay":
-				color = "meek";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftplay": case "leftgrab": case "leftstroke": case "leftchest": case "rightplay": case "rightgrab": case "rightstroke": case "rightchest":
-			case "leftchest": case "rightchest": case "leftwork": case "rightwork": case "leftclit": case "rightclit": case "keepchoke":
-			case "leftmasturbatepussy" : case "rightmasturbatepussy" : case "leftmasturbatepenis" : case "rightmasturbatepenis" :
-			case "lefthandholdkeep" : case "righthandholdkeep" : case "lefthandholdnew" : case "righthandholdnew" :
-			case "lubeanus": case "lubepussy": case "lubepenis": case "removebuttplug":
-			case "dildoOtherPussyTease": case "dildoOtherPussyFuck": case "dildoOtherAnusTease": case "dildoOtherAnusFuck": case "strokerOtherPenisTease": case "strokerOtherPenisFuck":
-			case "dildoSelfPussyEntrance": case "dildoSelfAnusEntrance": case "dildoSelfPussy": case "dildoSelfAnus": case "strokerSelfPenisEntrance": case "strokerSelfPenis":
-			/*feetaction*/
-			case "grab": case "vaginagrab": case "grabrub": case "vaginagrabrub": case "rub":
-			/*mouthaction*/
-			case "peniskiss": case "kisslips" : case "kissskin": case "suck": case "lick": case "moan": case "breastsuck": case "breastlick": case "swallow": case "movetochest":
-			case "othervagina": case "mouth": case "kissback": case "vaginalick": case "askchoke": case "anallick": case "analkiss": case "askrough":
-			/*penisaction*/
-			case "penistovagina": case "penistoanus": case "penisvaginafuck": case "penisanusfuck": case "othermouthtease": case "othermouthrub":
-			case "othermouthcooperate": case "tease": case "cooperate": case "otheranustease": case "otheranusrub": case "otheranuscooperate": case "clitrub":
-			case "vaginaEdging": case "otheranusEdging": case "handtease": case "handAnusRub": case "handcooperate": case "strokerCooperate":
-			/*fencing*/
-			case "otherpenisrub": case "penistopenis": case "penistopenisfuck": case "fencingcooperate":
-			/*vaginaaction*/
-			case "vaginatopenis": case "vaginapenisfuck": case "othervaginarub": case "vaginatovagina": case "vaginatovaginafuck": case "tribcooperate": case "penisEdging":
-			case "vaginatopenisdouble": case "vaginapenisdoublefuck": case "penispussydouble": case "penisanusdvp":
-			/*anusaction*/
-			case "anustopenis": case "anuspenisfuck": case "penistease": case "otherMouthAnusRub": case "otherAnusRub": case "penisEdging":
-			/*doubleanusaction*/
-			case "anustopenisdouble": case "anuspenisdoublefuck": case "penisdoubletease": case "penisDoubleEdging": case "doublecooperate": case "penisanusdouble":
-				color = "sub";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftacceptW": case "rightacceptW": case "leftstruggleW": case "rightstruggleW":
-			/*feetaction*/
-			case "feetacceptW":
-			/*mouthaction*/
-			case "mouthacceptW": case "handbiteW":
-				color = "wraith";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
+		Wikifier.wikifyEval(
+			"<<replace #" + bodypart + "action>><<" + bodypart + "ActionInit>><</replace>>"
+		);
 	}
-	else if (type === "Tentacle") {
-		switch (check.replace(/\d+/g, '')) {
-			/*leftaction or rightaction*/
-			case "lefthittentacle": case "righthittentacle":
-			case "lefthit": case "righthit":
-			case "leftbanish": case "rightbanish":
-			/*feetaction*/
-			case "feethit":
-			/*mouthaction*/
-			case "mouthbitetentacle":
-				color = "def";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftfold": case "rightfold": case "leftstruggleweak": case "rightstruggleweak":
-			/*mouthaction*/
-			case "mouthpullawaytentacle": case "stifleorgasm": case "stifle":
-			/*penisaction*/
-			case "penispullawaytentacle":
-			/*vaginaaction*/
-			case "vaginapullawaytentacle":
-			/*anusaction*/
-			case "anuspullawaytentacle":
-				color = "brat";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftgrabtentacle": case "rightgrabtentacle": case "leftrubtentacle": case "rightrubtentacle":
-			case "showbottomtentacle": case "showthighstentacle": case "showmouthtentacle": case "showpenistentacle": case "showvaginatentacle":
-			case "leftgrab": case "rightgrab": case "leftrub": case "rightrub":
-			case "showbottom": case "showthighs": case "showmouth":
-			/*feetaction*/
-			case "feetgrab": case "feetrubtentacle":
-			/*mouthaction*/
-			case "mouthlicktentacle": case "mouthkisstentacle": case "mouthcooperatetentacle":
-			/*penisaction*/
-			case "penisrubtentacle": case "peniscooperatetentacle":
-			/*vaginaaction*/
-			case "vaginarubtentacle": case "vaginacooperatetentacle":
-			/*anusaction*/
-			case "anusrubtentacle": case "anuscooperatetentacle":
-			/*bottomuse*/
-			case "bottomrubtentacle":
-			/*breastuse*/
-			case "chestrubtentacle":
-				color = "sub";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip": case "leftcurl": case "rightcurl":
-			/*mouthaction*/
-			case "letout": case "letoutorgasm": case "noises":
-				color = "meek";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
-	}
-	else if (type === "Vore") {
-		switch (check.replace(/\d+/g, '')) {
-			case "leftescape": case "rightescape": case "lefthold": case "righthold": case "leftvorefree": case "rightvorefree":
-			case "leftfold": case "rightfold": case "leftstruggleweak": case "rightstruggleweak":
-				color = "brat";
-				break;
-
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip": case "leftcurl": case "rightcurl":
-				color = "meek";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
-
-	}
-	else if (type === "Swarm") {
-		switch (check.replace(/\d+/g, '')) {
-			/*leftaction or rightaction*/
-			case "leftfree": case "rightfree": case "frontpurgeleft": case "frontpurgeright":
-			case "frontclearleft": case "frontclearright": case "backpurgeleft": case "backpurgeright":
-			case "backclearleft": case "backclearright": case "chestclearleft": case "chestclearright":
-			case "leftfold": case "rightfold": case "leftstruggleweak": case "rightstruggleweak":
-				color = "brat";
-				break;
-
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip": case "leftcurl": case "rightcurl":
-				color = "meek";
-				break;
-
-			case "swim":
-				color = "teal";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
-
-	}
-	else if (type === "Struggle") {
-		switch (check.replace(/\d+/g, '')) {
-			/*leftaction or rightaction*/
-			case "mouth_strengthen": case "mouth_grasp": case "vagina_strengthen": case "vagina_grasp":
-			case "penis_strengthen": case "penis_grasp": case "anus_strengthen": case "anus_grasp":
-			case "chest_strengthen": case "chest_grasp":
-			case "leftfold": case "rightfold": case "leftstruggleweak": case "rightstruggleweak":
-				color = "brat";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip": case "leftcurl": case "rightcurl":
-			case "rest":
-			/*feetaction*/
-			case "evade": case "plant":
-				color = "meek";
-				break;
-
-			/*leftaction or rightaction*/
-			case "capture": case "mouth_pull": case "mouth_spray": case "vagina_pull": case "vagina_spray": case "guard":
-			case "penis_pull": case "penis_spray": case "anus_pull": case "anus_spray": case "chest_pull": case "chest_spray":
-			/*mouthaction*/
-			case "bite":
-				color = "def";
-				break;
-
-			/*leftaction or rightaction*/
- 			case "mouth_stroke": case "vagina_stroke": case "penis_stroke": case "anus_stroke": case "chest_stroke":
-			/*mouthaction*/
-			case "open": case "suck":
-				color = "sub";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
-
-	}
-	else if (type === "Machine") {
-		switch (check.replace(/\d+/g, '')) {
-			case "leftfold": case "rightfold": case "leftstruggleweak": case "rightstruggleweak": case "vaginal_push": case "anal_push":
-				color = "brat";
-				break;
-
-			case "chain_struggle": case "whack": case "vaginal_whack": case "anal_whack":
-				color = "def";
-				break;
-
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip": case "leftcurl": case "rightcurl":
-				color = "meek";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
-
-	}
-	else if (type === "Self") {
-		switch (check.replace(/\d+/g, '')) {
-			/*leftaction or rightaction*/
-			case "leftfree": case "rightfree":
-			case "leftcovervagina": case "leftcoverpenis": case "leftcoveranus":
-			case "rightcovervagina": case "rightcoverpenis": case "rightcoveranus":
-			case "leftunderpull": case "leftskirtpull": case "leftlowerpull": case "leftupperpull":
-			case "rightunderpull": case "rightskirtpull": case "rightlowerpull": case "rightupperpull":
-			case "leftcovervagina": case "leftcoverpenis": case "leftcoveranus":
-			case "rightcovervagina": case "rightcoverpenis": case "rightcoveranus":
-			case "leftunderpull": case "leftskirtpull": case "leftlowerpull": case "leftupperpull":
-			case "rightunderpull": case "rightskirtpull": case "rightlowerpull": case "rightupperpull":
-			case "leftfold": case "rightfold": case "leftstruggleweak": case "rightstruggleweak":
-				color = "brat";
-				break;
-
-			/*leftaction or rightaction*/
-			case "leftprotect": case "rightprotect": case "leftgrip": case "rightgrip": case "leftcurl":
-			case "rightcurl": case "behind": case "pickupSexToy":
-			/*feetaction*/
-			case "evade": case "plant":
-				color = "meek";
-				break;
-
+}
+window.actionsreplace = actionsreplace;
+
+const combatActionColours = {
+	Default: {
+		brat: [
+			/* leftaction or rightaction */
+			"steal", "penwhack", "freeface", "leftcovervagina", "leftcoverpenis", "leftcoveranus", "rightcovervagina", "rightcoverpenis", "rightcoveranus", "leftunderpull", "leftskirtpull", "leftlowerpull", "leftupperpull", "rightunderpull", "rightskirtpull", "rightlowerpull", "rightupperpull", "rightUndressOther", "leftUndressOther", "stopchoke", "clench", "shacklewhack", "leftfold", "rightfold", "dildowhack", "hypnosiswhack", "leftstruggleweak", "rightstruggleweak", "leftresistW", "rightresistW", "leftstillW", "rightstillW",
+			/* feetaction */
+			"run", "hide", "confront", "feetresistW",
+			/* mouthaction */
+			"pullaway", "pullawayvagina", "finish", "novaginal", "nopenile", "noanal", "scream", "mock", "breastclosed", "breastpull", "pullawaykiss", "noupper", "up", "stifleorgasm", "stifle", "mouthresistW", "handcloseW",
+			/* penisaction */
+			"othermouthescape", "escape", "otheranusescape", "fencingescape",
+			/* vaginaaction */
+			"tribescape",
+			/* anusaction */
+			"doubleescape",
+		],
+		def: [
+			/* leftaction or rightaction */
+			"spray", "lefthit", "righthit", "leftstruggle", "rightstruggle", "stopchokenoncon", "pursuit_grab",
+			/* feetaction */
+			"kick",
+			/* mouthaction */
+			"bite", "demand", "breastbite", "handbite", "headbutt", "bitepussy",
+		],
+		meek: [
+			/* leftaction or rightaction */
+			"behind", "fold", "leftcovervaginameek", "leftcoverpenismeek", "leftcoveranusmeek", "rightcovervaginameek", "rightcoverpenismeek", "rightcoveranusmeek", "leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl", "pickupSexToy", "leftcamerapose", "rightcamerapose",
+			/* mouthaction */
+			"grasp", "plead", "forgive", "down", "letout", "letoutorgasm", "noises", "pay",
+			/* penisaction */
+			"thighbay", "bay", "otheranusbay",
+			/* vaginaaction */
+			"penisthighs",
+			/* anusaction */
+			"bottombay", "penischeeks", "penispussy", "penispussydap", "penisanus", "bottomhandbay",
+		],
+		sub: [
+			/* leftaction or rightaction */
+			"leftplay", "leftgrab", "leftstroke", "leftchest", "rightplay", "rightgrab", "rightstroke", "rightchest", "leftchest", "rightchest", "leftwork", "rightwork", "leftclit", "rightclit", "keepchoke", "leftmasturbatepussy", "rightmasturbatepussy", "leftmasturbatepenis", "rightmasturbatepenis", "lefthandholdkeep", "righthandholdkeep", "lefthandholdnew", "righthandholdnew", "lubeanus", "lubepussy", "lubepenis", "removebuttplug", "dildoOtherPussyTease", "dildoOtherPussyFuck", "dildoOtherAnusTease", "dildoOtherAnusFuck", "strokerOtherPenisTease", "strokerOtherPenisFuck", "dildoSelfPussyEntrance", "dildoSelfAnusEntrance", "dildoSelfPussy", "dildoSelfAnus", "strokerSelfPenisEntrance", "strokerSelfPenis",
+			/* feetaction */
+			"grab", "vaginagrab", "grabrub", "vaginagrabrub", "rub",
+			/* mouthaction */
+			"peniskiss", "kisslips", "kissskin", "suck", "lick", "moan", "breastsuck", "breastlick", "swallow", "movetochest", "othervagina", "mouth", "kissback", "vaginalick", "askchoke", "anallick", "analkiss", "askrough",
+			/* penisaction */
+			"penistovagina", "penistoanus", "penisvaginafuck", "penisanusfuck", "othermouthtease", "othermouthrub", "othermouthcooperate", "tease", "cooperate", "otheranustease", "otheranusrub", "otheranuscooperate", "clitrub", "vaginaEdging", "otheranusEdging", "handtease", "handAnusRub", "handcooperate", "strokerCooperate",
+			/* fencing */
+			"otherpenisrub", "penistopenis", "penistopenisfuck", "fencingcooperate",
+			/* vaginaaction */
+			"vaginatopenis", "vaginapenisfuck", "othervaginarub", "vaginatovagina", "vaginatovaginafuck", "tribcooperate", "penisEdging", "vaginatopenisdouble", "vaginapenisdoublefuck", "penispussydouble", "penisanusdvp",
+			/* anusaction */
+			"anustopenis", "anuspenisfuck", "penistease", "otherMouthAnusRub", "otherAnusRub", "penisEdging",
+			/* doubleanusaction */
+			"anustopenisdouble", "anuspenisdoublefuck", "penisdoubletease", "penisDoubleEdging", "doublecooperate", "penisanusdouble",
+		],
+		wraith: [
+			/* leftaction or rightaction */
+			"leftacceptW", "rightacceptW", "leftstruggleW", "rightstruggleW",
+			/* feetaction */
+			"feetacceptW",
+			/* mouthaction */
+			"mouthacceptW", "handbiteW",
+		],
+	},
+	Tentacle: {
+		def: [
+			/* leftaction or rightaction */
+			"lefthittentacle", "righthittentacle", "lefthit", "righthit", "leftbanish", "rightbanish",
+			/* feetaction */
+			"feethit",
+			/* mouthaction */
+			"mouthbitetentacle",
+		],
+		brat: [
+			/* leftaction or rightaction */
+			"leftfold", "rightfold", "leftstruggleweak", "rightstruggleweak",
+			/* mouthaction */
+			"mouthpullawaytentacle", "stifleorgasm", "stifle",
+			/* penisaction */
+			"penispullawaytentacle",
+			/* vaginaaction */
+			"vaginapullawaytentacle",
+			/* anusaction */
+			"anuspullawaytentacle",
+		],
+		sub: [
+			/* leftaction or rightaction */
+			"leftgrabtentacle", "rightgrabtentacle", "leftrubtentacle", "rightrubtentacle", "showbottomtentacle", "showthighstentacle", "showmouthtentacle", "showpenistentacle", "showvaginatentacle", "leftgrab", "rightgrab", "leftrub", "rightrub", "showbottom", "showthighs", "showmouth",
+			/* feetaction */
+			"feetgrab", "feetrubtentacle",
+			/* mouthaction */
+			"mouthlicktentacle", "mouthkisstentacle", "mouthcooperatetentacle",
+			/* penisaction */
+			"penisrubtentacle", "peniscooperatetentacle",
+			/* vaginaaction */
+			"vaginarubtentacle", "vaginacooperatetentacle",
+			/* anusaction */
+			"anusrubtentacle", "anuscooperatetentacle",
+			/* bottomuse */
+			"bottomrubtentacle",
+			/* breastuse */
+			"chestrubtentacle",
+		],
+		meek: [
+			/* leftaction or rightaction */
+			"leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl",
+			/* mouthaction */
+			"letout", "letoutorgasm", "noises",
+		],
+	},
+	Vore: {
+		brat: [
+			"leftescape", "rightescape", "lefthold", "righthold", "leftvorefree", "rightvorefree", "leftfold", "rightfold", "leftstruggleweak", "rightstruggleweak",
+		],
+		meek: [
+			"leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl",
+		],
+	},
+	Swarm: {
+		brat: [
+			"leftfree", "rightfree", "frontpurgeleft", "frontpurgeright", "frontclearleft", "frontclearright", "backpurgeleft", "backpurgeright", "backclearleft", "backclearright", "chestclearleft", "chestclearright", "leftfold", "rightfold", "leftstruggleweak", "rightstruggleweak",
+		],
+		meek: [
+			"leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl",
+		],
+		teal: ["swim"],
+	},
+	Struggle: {
+		brat: [
+			/* leftaction or rightaction */
+			"mouth_strengthen", "mouth_grasp", "vagina_strengthen", "vagina_grasp", "penis_strengthen", "penis_grasp", "anus_strengthen", "anus_grasp", "chest_strengthen", "chest_grasp", "leftfold", "rightfold", "leftstruggleweak", "rightstruggleweak",
+		],
+		meek: [
+			/* leftaction or rightaction */
+			"leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl", "rest",
+			/* feetaction */
+			"evade", "plant",
+		],
+		def: [
+			/* leftaction or rightaction */
+			"capture", "mouth_pull", "mouth_spray", "vagina_pull", "vagina_spray", "guard", "penis_pull", "penis_spray", "anus_pull", "anus_spray", "chest_pull", "chest_spray",
+			/* mouthaction */
+			"bite",
+		],
+		sub: [
+			/* leftaction or rightaction */
+			"mouth_stroke", "vagina_stroke", "penis_stroke", "anus_stroke", "chest_stroke",
+			/* mouthaction */
+			"open", "suck",
+		],
+	},
+	Machine: {
+		brat: ["leftfold", "rightfold", "leftstruggleweak", "rightstruggleweak", "vaginal_push", "anal_push"],
+		def: ["chain_struggle", "whack", "vaginal_whack", "anal_whack"],
+		meek: ["leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl"],
+	},
+	Self: {
+		brat: [
+			/* leftaction or rightaction */
+			"leftfree", "rightfree", "leftcovervagina", "leftcoverpenis", "leftcoveranus", "rightcovervagina", "rightcoverpenis", "rightcoveranus", "leftunderpull", "leftskirtpull", "leftlowerpull", "leftupperpull", "rightunderpull", "rightskirtpull", "rightlowerpull", "rightupperpull", "leftfold", "rightfold", "leftstruggleweak", "rightstruggleweak",
+		],
+		meek: [
+			/* leftaction or rightaction */
+			"leftprotect", "rightprotect", "leftgrip", "rightgrip", "leftcurl", "rightcurl", "behind", "pickupSexToy",
+			/* feetaction */
+			"evade", "plant",
+		],
+		sub: [
 			/* Masturbate */
-			case "leftmasturbatepenis" : case "rightmasturbatepenis" : case "leftmasturbatepussy" : case "rightmasturbatepussy" :
-			case "dildoSelfPussyEntrance": case "dildoSelfAnusEntrance": case "strokerSelfPenisEntrance": case "strokerSelfPenis":
-			case "lubepussy": case "lubepenis": case "lubeanus": case "removebuttplug":
-				color = "sub";
-				break;
-
-			case "swim":
-				color = "teal";
-				break;
-
-			default:
-				color = "white";
-				break;
-		}
+			"leftmasturbatepenis", "rightmasturbatepenis", "leftmasturbatepussy", "rightmasturbatepussy", "dildoSelfPussyEntrance", "dildoSelfAnusEntrance", "strokerSelfPenisEntrance", "strokerSelfPenis", "lubepussy", "lubepenis", "lubeanus", "removebuttplug",
+		],
+		teal: ["swim"],
+	},
+};
+window.combatActionColours = combatActionColours;
 
+function combatListColor(name, value, type) {
+	const action = (value || V[name]).replace(/\d+/g, "");
+	const encounterType = type || "Default";
+	for (const color in combatActionColours[encounterType]) {
+		if (combatActionColours[encounterType][color].includes(action)) return color;
 	}
-	return color;
+	return "white";
 }
-
+window.combatListColor = combatListColor;
 DefineMacroS("combatListColor", combatListColor);
 
 function combatButtonAdjustments(name, extra) {
-	jQuery(document).on('change', '#listbox-' + name, { "name": name, "extra": extra }, function (e) {
-		/*console.log(e.data);*/
-		new Wikifier(null, '<<replace #' + e.data.name + 'Difficulty>><<' + e.data.name + 'Difficulty' + e.data.extra + '>><</replace>>');
-		$('#' + e.data.name + 'Select').removeClass('whiteList bratList meekList defList subList');
-		$('#' + e.data.name + 'Select').addClass(combatListColor(e.data.name, undefined, e.data.extra) + "List");
+	jQuery(document).on("change", "#listbox-" + name, { name: name, extra: extra }, function (e) {
+		/* console.log(e.data); */
+		Wikifier.wikifyEval("<<replace #" + e.data.name + "Difficulty>><<" + e.data.name + "Difficulty" + e.data.extra + ">><</replace>>");
+		$("#" + e.data.name + "Select").removeClass("whiteList bratList meekList defList subList");
+		$("#" + e.data.name + "Select").addClass(combatListColor(e.data.name, undefined, e.data.extra) + "List");
 	});
 	return "";
 }
-
 DefineMacroS("combatButtonAdjustments", combatButtonAdjustments);
 
 function combatDefaults() {
-	jQuery(document).on('change', '#listbox--defaultoption', function (e) {
-		new Wikifier(null, '<<replace #othersFeelings>><<othersFeelings ' + this.value + '>><</replace>>');
+	jQuery(document).on("change", "#listbox--defaultoption", function (e) {
+		Wikifier.wikifyEval('<<replace #othersFeelings>><<othersFeelings ' + this.value + '>><</replace>>');
 	});
 	return "";
 }
-
 DefineMacroS("combatDefaults", combatDefaults);
 
 /*
-* Explanation for the actionsSuccessPerSkill() function:
-* The following formula shows the old skill chance calculation.
-* (1000 - ($rng * 10) - ($enemytrust * 10) - $skill + $enemyanger) lte (($enemyarousalmax / ($enemyarousal + 1)) * 100)
-* Rearranged to
-* $skill + ($enemytrust * 10) + (($enemyarousalmax / ($enemyarousal + 1)) * 100) + ($rng * 10) gte 1000 + $enemyanger
-* The first half of the formula must be higher than the second half. So the higher the left values, the easier the action. The higher the right values, the harder the action.
-* $skill is the skill being used. That could be $handskill, $vaginalskill, $seductionskill, etc.
-* ($enemytrust * 10) is simply how much the NPC trust the player. Since $enemytrust can be negative, a bad trust can result in an increase in difficulty.
-* (($enemyarousalmax / ($enemyarousal + 1)) * 100) is the relative NPC arousal. This value can never be 100, except on the last turn.
-* The current arousal being divided by the max arousal means the higher the arousal (and by consequence the arousal percentage) the more difficult the action becomes (since the value will be lower).
-* This also means actions are more likely to succeed during the start of the combat, and get harder as the combat goes on.
-* ($rng * 10) is simply the random part of the equation, so the chance is not always locked into one result. This value varies between 0 and 1000, at a base 10 (so it can't be anything that's not a multiple of 10).
-* 1000 is the base difficulty. This rules how high the skill needs to be if all other values are 0. The higher the base difficulty, the harder the action. This is usually the main factor determining the success of the action.
-* $enemyanger is just like the trust part, but not multiplied. This means anger has 10x less impact in the action than trust, however $enemyanger cannot be negative and could be much higher than trust.
-*
-* Another form of the formula is written as
-* (700 - ($rng * 10) - ($enemytrust * 10) - $handskill + $enemyanger) lte (($enemyarousalmax / ($enemyarousal + 1)) * $_npc.clothes[$_clothesTarget].integrity)
-* This is the difficulty to undress an NPC. The base difficulty is lower, but the arousal multiplier is different. The 100 multiplier is replaced by the NPC's clothes' integrity, which is often higher than 100. The more tattered the clothes, the harder to succeed in the action (the arousal side becomes lower).
-*
-* The function uses the following formula:
-* skill + trust + (arousalfactor * multiplier) + rng >= basedifficulty + anger
-* Which is the same as the previous formula, just renamed.
-* trust will always be $enemytrust * 10
-* arousalfactor will always be $enemyarousalmax / ($enemyarousal + 1)
-* multiplier, if not passed as an argument, will always be 100 (to complement the ($enemyarousalmax / ($enemyarousal + 1) * 100 format).
-* rng will always be $rng * 100
-* basedifficulty, if not passed as an argument, will always be 1000
-* anger is simply $enemyanger, renamed to fit in the format.
-* skill will be the selected skill. The function uses a required string argument which is skillname, being "hand", "vaginal", "seduction", etc. Whichever string is passed will be added to "skill" to make the skill variable.
-* E.g. the function passes "anal" as the only argument (and thus skillname is "anal"). skill will become the value of $analskill used in calculation.
-* So skillname is a string, and skill is an integer. Why not simply pass the skill value as the argument? Because of possible future variants, such as moor luck, affecting some variable and not the other.
-* targetid is an optional value, that doesn't see use currently but can possibly be required in the future in case any of the "enemy" variables (such as $enemyarousal or $enemytrust) become individual values ("per NPC", as health currently is).
-*
-* The output is simply: true if the action is a success, and false if the action fails.
-*/
+ * Explanation for the actionsSuccessPerSkill() function:
+ * The following formula shows the old skill chance calculation.
+ * (1000 - ($rng * 10) - ($enemytrust * 10) - $skill + $enemyanger) lte (($enemyarousalmax / ($enemyarousal + 1)) * 100)
+ * Rearranged to
+ * $skill + ($enemytrust * 10) + (($enemyarousalmax / ($enemyarousal + 1)) * 100) + ($rng * 10) gte 1000 + $enemyanger
+ * The first half of the formula must be higher than the second half. So the higher the left values, the easier the action. The higher the right values, the harder the action.
+ * $skill is the skill being used. That could be $handskill, $vaginalskill, $seductionskill, etc.
+ * ($enemytrust * 10) is simply how much the NPC trust the player. Since $enemytrust can be negative, a bad trust can result in an increase in difficulty.
+ * (($enemyarousalmax / ($enemyarousal + 1)) * 100) is the relative NPC arousal. This value can never be 100, except on the last turn.
+ * The current arousal being divided by the max arousal means the higher the arousal (and by consequence the arousal percentage) the more difficult the action becomes (since the value will be lower).
+ * This also means actions are more likely to succeed during the start of the combat, and get harder as the combat goes on.
+ * ($rng * 10) is simply the random part of the equation, so the chance is not always locked into one result. This value varies between 0 and 1000, at a base 10 (so it can't be anything that's not a multiple of 10).
+ * 1000 is the base difficulty. This rules how high the skill needs to be if all other values are 0. The higher the base difficulty, the harder the action. This is usually the main factor determining the success of the action.
+ * $enemyanger is just like the trust part, but not multiplied. This means anger has 10x less impact in the action than trust, however $enemyanger cannot be negative and could be much higher than trust.
+ *
+ * Another form of the formula is written as
+ * (700 - ($rng * 10) - ($enemytrust * 10) - $handskill + $enemyanger) lte (($enemyarousalmax / ($enemyarousal + 1)) * $_npc.clothes[$_clothesTarget].integrity)
+ * This is the difficulty to undress an NPC. The base difficulty is lower, but the arousal multiplier is different. The 100 multiplier is replaced by the NPC's clothes' integrity, which is often higher than 100. The more tattered the clothes, the harder to succeed in the action (the arousal side becomes lower).
+ *
+ * The function uses the following formula:
+ * skill + trust + (arousalfactor * multiplier) + rng >= basedifficulty + anger
+ * Which is the same as the previous formula, just renamed.
+ * trust will always be $enemytrust * 10
+ * arousalfactor will always be $enemyarousalmax / ($enemyarousal + 1)
+ * multiplier, if not passed as an argument, will always be 100 (to complement the ($enemyarousalmax / ($enemyarousal + 1) * 100 format).
+ * rng will always be $rng * 100
+ * basedifficulty, if not passed as an argument, will always be 1000
+ * anger is simply $enemyanger, renamed to fit in the format.
+ * skill will be the selected skill. The function uses a required string argument which is skillname, being "hand", "vaginal", "seduction", etc. Whichever string is passed will be added to "skill" to make the skill variable.
+ * E.g. the function passes "anal" as the only argument (and thus skillname is "anal"). skill will become the value of $analskill used in calculation.
+ * So skillname is a string, and skill is an integer. Why not simply pass the skill value as the argument? Because of possible future variants, such as moor luck, affecting some variable and not the other.
+ * targetid is an optional value, that doesn't see use currently but can possibly be required in the future in case any of the "enemy" variables (such as $enemyarousal or $enemytrust) become individual values ("per NPC", as health currently is).
+ *
+ * The output is simply: true if the action is a success, and false if the action fails.
+ */
 /**
- * Checks skill value against combat math to determine success of an action
- * @param {string} skillName - Simple skill name, "anus" "hand" "feet" etc
- * @param {number} targetid - The targetted NPC's id
- * @param {number} difficulty - Difficulty of the check, default 1000
- * @param {number} multiplier - Multiplier on enemy arousal, default 100
+ * Checks skill value against combat math to determine success of an action.
+ *
+ * @param {string} skillname Simple skill name, "anus" "hand" "feet" etc.
+ * @param {number} targetid The targetted NPC's id.
+ * @param {number} basedifficulty Difficulty of the check, default 1000.
+ * @param {number} multiplier Multiplier on enemy arousal, default 100.
  * @returns {boolean}
  */
- function combatSkillCheck(skillname, targetid = 0, basedifficulty = 1000, multiplier = 100){
-	let skill = V[skillname + "skill"];
-	let rng = V.rng * 10;
-	let arousalfactor = V.enemyarousalmax / (V.enemyarousal + 1);
-	let trust = V.enemytrust * 10;
-	let anger = V.enemyanger;
-
-	if (skill + trust + (arousalfactor * multiplier) + rng >= basedifficulty + anger){
+function combatSkillCheck(skillname, targetid = 0, basedifficulty = 1000, multiplier = 100) {
+	const skill = V[skillname + "skill"];
+	const rng = V.rng * 10;
+	const arousalfactor = V.enemyarousalmax / (V.enemyarousal + 1);
+	const trust = V.enemytrust * 10;
+	const anger = V.enemyanger;
+
+	if (arousalfactor * multiplier + skill + trust + rng >= basedifficulty + anger) {
 		return true;
-	}else{
+	} else {
 		return false;
 	}
 }
 window.combatSkillCheck = combatSkillCheck;
 
 function hairdressersReset() {
-	jQuery(document).on('change', '.macro-listbox', function (e) {
-		new Wikifier(null, '<<replace #hairDressers>><<hairDressersOptions>><</replace>>');
-		new Wikifier(null, '<<replace #currentCost>>To pay: £<<print _currentCost / 100>><</replace>>');
+	jQuery(document).on("change", ".macro-listbox", function (e) {
+		Wikifier.wikifyEval("<<replace #hairDressers>><<hairDressersOptions>><</replace>>");
+		Wikifier.wikifyEval("<<replace #currentCost>>To pay: £<<print _currentCost / 100>><</replace>>");
 	});
 	return "";
 }
-
 DefineMacroS("hairdressersReset", hairdressersReset);
 
 function hairdressersResetAlt() {
-	jQuery(document).on('click', '.macro-cycle', function (e) {
-		new Wikifier(null, '<<replace #hairDressersSydney>><<hairDressersOptionsSydney>><</replace>>');
-		new Wikifier(null, '<<replace #currentCost>>To pay: £<<print _currentCost / 100>><</replace>>');
+	jQuery(document).on("click", ".macro-cycle", function (e) {
+		Wikifier.wikifyEval("<<replace #hairDressersSydney>><<hairDressersOptionsSydney>><</replace>>");
+		Wikifier.wikifyEval("<<replace #currentCost>>To pay: £<<print _currentCost / 100>><</replace>>");
 	});
 	return "";
 }
-
 DefineMacroS("hairdressersResetAlt", hairdressersResetAlt);
 
 function browsDyeReset() {
-	jQuery(document).on('change', '#listbox-browsdyeoption', function (e) {
-		new Wikifier(null, '<<replace #browsColourPreview>><<browsColourPreview>><</replace>>');
+	jQuery(document).on("change", "#listbox-browsdyeoption", function (e) {
+		Wikifier.wikifyEval("<<replace #browsColourPreview>><<browsColourPreview>><</replace>>");
 	});
 	return "";
 }
-
 DefineMacroS("browsDyeReset", browsDyeReset);
 
 function NPCSettingsReset() {
-	jQuery(document).on('change', '#listbox--npcid', function (e) {
-		new Wikifier(null, '<<replace #npcSettingsMenu>><<npcSettingsMenu>><</replace>>');
+	jQuery(document).on("change", "#listbox--npcid", function (e) {
+		Wikifier.wikifyEval("<<replace #npcSettingsMenu>><<npcSettingsMenu>><</replace>>");
 	});
 	return "";
 }
-
 DefineMacroS("NPCSettingsReset", NPCSettingsReset);
 
 function loveInterestFunction() {
-	jQuery(document).on('change', '#listbox-loveinterestprimary', function (e) {
-		new Wikifier(null, '<<replace #loveInterest>><<loveInterest>><</replace>>');
+	jQuery(document).on("change", "#listbox-loveinterestprimary", function (e) {
+		Wikifier.wikifyEval("<<replace #loveInterest>><<loveInterest>><</replace>>");
 	});
-	jQuery(document).on('change', '#listbox-loveinterestsecondary', function (e) {
-		new Wikifier(null, '<<replace #loveInterest>><<loveInterest>><</replace>>');
+	jQuery(document).on("change", "#listbox-loveinterestsecondary", function (e) {
+		Wikifier.wikifyEval("<<replace #loveInterest>><<loveInterest>><</replace>>");
 	});
 	return "";
 }
-
 DefineMacroS("loveInterestFunction", loveInterestFunction);
 
-window.between = function(x, min, max){
+function between(x, min, max) {
 	return x >= min && x <= max;
 }
+window.between = between;
 
 function featsPointsMenuReset() {
-	jQuery(document).on('change', '#listbox--upgradenameid', function (e) {
-		new Wikifier(null, '<<updateFeatsPointsMenu>>');
+	jQuery(document).on("change", "#listbox--upgradenameid", () => {
+		Wikifier.wikifyEval("<<updateFeatsPointsMenu>>");
 	});
 	return "";
 }
-
 DefineMacroS("featsPointsMenuReset", featsPointsMenuReset);
 
 function startingPlayerImageReset() {
-	jQuery(document).on('change', '#settingsDiv .macro-radiobutton,#settingsDiv .macro-numberslider,#settingsDiv .macro-checkbox', function (e) {
-		new Wikifier(null, '<<startingPlayerImageUpdate>>');
-	});
+	jQuery(document).on(
+		"change",
+		"#settingsDiv .macro-radiobutton,#settingsDiv .macro-numberslider,#settingsDiv .macro-checkbox",
+		() => {
+			Wikifier.wikifyEval("<<startingPlayerImageUpdate>>");
+		}
+	);
 	return "";
 }
-
 DefineMacroS("startingPlayerImageReset", startingPlayerImageReset);
 
-window.deck = function(){
-	var names = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
-	var suits = ['Hearts','Diamonds','Spades','Clubs'];
-	var cards = [];
+function deck() {
+	const names = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
+	const suits = ["Hearts", "Diamonds", "Spades", "Clubs"];
+	const cards = [];
 
-	for( var s = 0; s < suits.length; s++ ) {
-		for( var n = 0; n < names.length; n++ ) {
-			cards.push( {value:n+2, name:names[n], suits:suits[s]} );
+	for (let s = 0; s < suits.length; s++) {
+		for (let n = 0; n < names.length; n++) {
+			cards.push({ value: n + 2, name: names[n], suits: suits[s] });
 		}
 	}
 
 	return cards;
 }
+window.deck = deck;
 
-window.ordinalSuffixOf = function(i) {
-    var j = i % 10,
-        k = i % 100;
-    if (j == 1 && k != 11) {
-        return i + "st";
-    }
-    if (j == 2 && k != 12) {
-        return i + "nd";
-    }
-    if (j == 3 && k != 13) {
-        return i + "rd";
-    }
-    return i + "th";
+function ordinalSuffixOf(i) {
+	const j = i % 10;
+	const k = i % 100;
+	if (j === 1 && k !== 11) {
+		return i + "st";
+	}
+	if (j === 2 && k !== 12) {
+		return i + "nd";
+	}
+	if (j === 3 && k !== 13) {
+		return i + "rd";
+	}
+	return i + "th";
 }
+window.ordinalSuffixOf = ordinalSuffixOf;
 
-window.lerp = function(percent, start, end) {
+function lerp(percent, start, end) {
 	return Math.clamp(start + (end - start) * percent, start, end);
 }
-window.inverseLerp = function(value, start, end) {
+window.lerp = lerp;
+
+function inverseLerp(value, start, end) {
 	return Math.clamp((value - start) / (end - start), 0, 1);
 }
-window.formatDecimals = function(value, decimalPlaces) {
-	return Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces);
+window.inverseLerp = inverseLerp;
+
+function formatDecimals(value, decimalPlaces) {
+	return Number(Math.round(parseFloat(value + "e" + decimalPlaces)) + "e-" + decimalPlaces);
 }
+window.formatDecimals = formatDecimals;
 
-window.nCr = function(n, r) {
+function nCr(n, r) {
 	// https://stackoverflow.com/questions/11809502/which-is-better-way-to-calculate-ncr
-    if (r > n - r) {
-        // because C(n, r) == C(n, n - r)
-        r = n - r
-    }
+	if (r > n - r) {
+		// because C(n, r) == C(n, n - r)
+		r = n - r
+	}
 
-    let ans = 1;
-    for(let i = 1; i <= r; ++i) {
-        ans *= n - r + i;
-        ans /= i;
-    }
+	let ans = 1;
+	for (let i = 1; i <= r; ++i) {
+		ans *= n - r + i;
+		ans /= i;
+	}
 
-    return ans;
+	return ans;
 }
+window.nCr = nCr;
 
 /**
  * Given there are {deckCount} cards in the deck and {markedCount} of them have been marked by the player,
@@ -615,172 +520,182 @@ window.nCr = function(n, r) {
  * @param {Boolean} doLog = false, if true - logs the steps of the solution
  * @returns
  */
-window.calculateMarkedChance = function(deckCount, markedCount, depth, atLeast, doLog=false) {
-    // we calculate how many possible ways we can pull DEPTH amount of cards from the deck (and put them in the front of the deck)
-    let totalEvents = nCr(deckCount, depth);
-    let logMessages = [];
-    let log = (m) => {
-        if (doLog) {
-            logMessages.push(m);
-        }
-    }
-    log(`DEPTH=${depth} cards can be placed in front of the deck from a deck of ${deckCount} cards in ${deckCount}c${depth} = ${totalEvents} ways.`);
-
-    let favorableEvents = 0;
-
-    // as per the algorithm, we go from how many marked cards we need at the very least, to either how many marked cards there are, or to how deep we can go (whichever is the limit)
-    let possibleMarkedCardsVisibleLimit = Math.min(markedCount, depth);
-    for (let nMarkedPicked = atLeast; nMarkedPicked <= possibleMarkedCardsVisibleLimit; ++nMarkedPicked) {
-        // we calculate how many possible ways we can pull a valid number of marked cards from the deck
-        //   by dividing the cards into a pool of
-        //    * marked cards (and calculating how many ways we can pull the valid nMarkedPicked cards from the pool of markedCount marked cards),  nCr(markedCount, nMarkedPicked)
-        //    * unmarked cards (and calculating how many ways we can pull the remaining possibleMarkedCardsVisibleLimit-nMarkedPicked non-marked cards from the pool of deck-markedCount unmarked cards), ncr(deck-markedCount, possibleMarkedCardsVisibleLimit-nMarkedPicked)
-        //   and then we multiply the mutually exclusive combinations to get all possible combinations (cross-joins) of the two (since for each way we can pull (say) 1 marked card, there's the second number of ways we can pull the remaining non marked ones)
-        let markedPoolWays = nCr(markedCount, nMarkedPicked);
-        let unmarkedPoolWays = nCr(deckCount - markedCount, possibleMarkedCardsVisibleLimit - nMarkedPicked);
-        let totalWays = markedPoolWays * unmarkedPoolWays;
-        favorableEvents += totalWays;
-        //log(`One marked card can be picked from MARKED=1 cards in 1c1 = 1 ways, and the remaining three (which are not marked) can be picked from DECK=5-MARKED=1 = 4 cards in 4c3 = 4 ways.
-        log(`${nMarkedPicked} marked cards can be picked from MARKED=${markedCount} cards in ${markedCount}c${nMarkedPicked} = ${markedPoolWays} ways,` +
-            `and the remaining ${deckCount - markedCount} (which are not marked) can be picked from DECK=${deckCount}-MARKED=${markedCount} = ${deckCount - markedCount} cards in ${deckCount - markedCount}c${possibleMarkedCardsVisibleLimit - nMarkedPicked} = ${unmarkedPoolWays} ways.\n` +
-            `${markedPoolWays}*${unmarkedPoolWays} = ${totalWays} ways.`
-        );
-    }
-
-    console.log(logMessages.join("\n"));
-    return favorableEvents / totalEvents;
-}
-
-window.shuffle = function(o) {
-	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
+function calculateMarkedChance(deckCount, markedCount, depth, atLeast, doLog = false) {
+	// we calculate how many possible ways we can pull DEPTH amount of cards from the deck (and put them in the front of the deck)
+	const totalEvents = nCr(deckCount, depth);
+	const logMessages = [];
+	const log = m => {
+		if (doLog) {
+			logMessages.push(m);
+		}
+	};
+	log(
+		`DEPTH=${depth} cards can be placed in front of the deck from a deck of ${deckCount} cards in ${deckCount}c${depth} = ${totalEvents} ways.`
+	);
+
+	let favorableEvents = 0;
+
+	// as per the algorithm, we go from how many marked cards we need at the very least, to either how many marked cards there are, or to how deep we can go (whichever is the limit)
+	const possibleMarkedCardsVisibleLimit = Math.min(markedCount, depth);
+	for (
+		let nMarkedPicked = atLeast;
+		nMarkedPicked <= possibleMarkedCardsVisibleLimit;
+		++nMarkedPicked
+	) {
+		// we calculate how many possible ways we can pull a valid number of marked cards from the deck
+		//   by dividing the cards into a pool of
+		//    * marked cards (and calculating how many ways we can pull the valid nMarkedPicked cards from the pool of markedCount marked cards),  nCr(markedCount, nMarkedPicked)
+		//    * unmarked cards (and calculating how many ways we can pull the remaining possibleMarkedCardsVisibleLimit-nMarkedPicked non-marked cards from the pool of deck-markedCount unmarked cards), ncr(deck-markedCount, possibleMarkedCardsVisibleLimit-nMarkedPicked)
+		//   and then we multiply the mutually exclusive combinations to get all possible combinations (cross-joins) of the two (since for each way we can pull (say) 1 marked card, there's the second number of ways we can pull the remaining non marked ones)
+		const markedPoolWays = nCr(markedCount, nMarkedPicked);
+		const unmarkedPoolWays = nCr(
+			deckCount - markedCount,
+			possibleMarkedCardsVisibleLimit - nMarkedPicked
+		);
+		const totalWays = markedPoolWays * unmarkedPoolWays;
+		favorableEvents += totalWays;
+		// log(`One marked card can be picked from MARKED=1 cards in 1c1 = 1 ways, and the remaining three (which are not marked) can be picked from DECK=5-MARKED=1 = 4 cards in 4c3 = 4 ways.
+		log(
+			`${nMarkedPicked} marked cards can be picked from MARKED=${markedCount} cards in ${markedCount}c${nMarkedPicked} = ${markedPoolWays} ways,` +
+				`and the remaining ${
+					deckCount - markedCount
+				} (which are not marked) can be picked from DECK=${deckCount}-MARKED=${markedCount} = ${
+					deckCount - markedCount
+				} cards in ${deckCount - markedCount}c${
+					possibleMarkedCardsVisibleLimit - nMarkedPicked
+				} = ${unmarkedPoolWays} ways.\n` +
+				`${markedPoolWays}*${unmarkedPoolWays} = ${totalWays} ways.`
+		);
+	}
+
+	console.log(logMessages.join("\n"));
+	return favorableEvents / totalEvents;
+}
+window.calculateMarkedChance = calculateMarkedChance;
+
+function shuffle(o) {
+	for (
+		let j, x, i = o.length;
+		i;
+		j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x
+	);
 	return o;
-};
+}
+window.shuffle = shuffle;
 
 function updateAskColour() {
-	jQuery(document).on('change', '#listbox-askaction', function (e) {
-		new Wikifier(null, '<<replaceAskColour>>');
+	jQuery(document).on("change", "#listbox-askaction", function (e) {
+		Wikifier.wikifyEval("<<replaceAskColour>>");
 	});
 	return "";
 }
-
 DefineMacroS("updateAskColour", updateAskColour);
 
-
-window.generateBabyName = function(name, gender, usedNames) {
-	var result = "";
-	if(name != undefined && name != null && name != ""){
-		var result = name.replace(/[^a-zA-Z ]+/g,"");
-		return result.substring(0,30);
-	}else{
-		var names = [];
-		switch(gender){
+function generateBabyName(name, gender, usedNames) {
+	let result = "";
+	if (name != null && name !== "") {
+		result = name.replace(/[^a-zA-Z ]+/g, "");
+		return result.substring(0, 30);
+	} else {
+		let names = [];
+		switch (gender) {
 			case "m":
+				// eslint-disable-next-line prettier/prettier
 				names = ['Addison','Algernon','Allan','Alpha','Anton','Axel','Bazza','Benton','Bernard','Brand','Brett','Cale','Calvin','Carol','Chuck','Chucky','Clay','Cornelius','Crofton','Darden','Dax','Den','Deven','Digby','Don','Douglas','Driscoll','Duane','Duke','Edmund','Elsdon','Freeman','Gabby','Garland','George','Godfrey','Graeme','Grier','Hammond','Harlan','Hendrix','Herman','Hewie','Hugh','Indiana','Ingram','Jackie','Jasper','Jaxon','Jaycob','Jere','Kamden','Kelcey','Kendall','Kevin','Kian','Kieran','Kirby','Lanny','Lawson','Laz','Leland','Levi','Lindon','Linton','Lionel','Lonny','Lucas','Manley','Maverick','Merlyn','Michael','Monty','Murphy','Nate','Ned','Nowell','Odell','Ollie','Osbert','Otto','Paget','Pip','Quintin','Raymund','Ricky','Robert','Ross','Rudolph','Sammy','Scotty','Stacey','Thad','Theodore','Tommy','Trey','Tyson','Val','Vernon','Willis','Wilmer','Winton','Wisdom'];
 				break;
 			case "f":
+				// eslint-disable-next-line prettier/prettier
 				names = ['Adelyn','Alene','Alexa','Aliah','Alyson','Angelica','Annalise','Annora','Azaria','Bessie','Betsy','Bettie','Biddy','Brianne','Camellia','Camille','Camryn','Caroline','Chastity','Chelsea','Chelsey','Cindy','Clematis','Darla','Deb','Debby','Dortha','Eleanora','Eliana','Elsabeth','Elyse','Emerson','Emmeline','Erica','Ettie','Eustacia','Evelyn','Gabrielle','Georgiana','Harper','Harrietta','Haylie','Haze','Hunter','Hyacinth','Indiana','Indie','Jacquetta','Janie','Jannine','Jonquil','Kaelyn','Kam','Khloe','Kolleen','Korrine','Kourtney','Krystine','Lavena','Leeann','Lela','Lesleigh','Lindsie','Lorena','Lucile','Luvinia','Lyn','Lyssa','Madeleine','Marian','Maudie','Maureen','Maxine','Melody','Milani','Misti','Nat','Noelle','Ottoline','Paige','Pauline','Payton','Pearl','Perlie','Petronel','Phebe','Posie','Praise','Rexana','Serena','Sharalyn','Sharla','Shauna','Sky','Sybella','Tracy','Tresha','Trudi','Wallis','Wilda','Wren','Yvette'];
 				break;
 		}
+		// eslint-disable-next-line prettier/prettier
 		names.pushUnique('Aaren','Addison','Alex','Alpha','Andie','Arden','Ariel','Artie','Ashton','Aston','Aubrey','Beau','Bernie','Bertie','Beverly','Bobbie','Brooklyn','Caelan','Cameron','Carol','Cary','Casey','Channing','Charley','Cherokee','Cheyenne','Coby','Codie','Collyn','Cyan','Dale','Dallas','Dana','Darby','Dee','Derby','Devan','Devin','Emmerson','Emory','Finley','Flannery','Florence','Gabby','Garnet','Garnett','Gray','Hadyn','Harlow','Hollis','Jackie','Jade','Jae','Jaiden','Johnnie','Joyce','Justice','Kam','Kelcey','Kelsey','Leslie','Lindsey','Lorin','Lyric','Maitland','Marley','McKinley','Merlyn','Murphy','Nicky','Oakley','Odell','Pacey','Paget','Peyton','Presley','Rain','Raleigh','Reagan','Regan','Reilly','Remington','Robbie','Rory','Royale','Sage','Sam','Schuyler','Selby','Shae','Shaye','Shelly','Skylar','Sloan','Stacey','Stacy','Tayler','Tommie','Tracey','Tristen','Tristin','Val');
 		names.delete(usedNames);
-		result = names[random(0,names.length - 1)];
+		result = names[random(0, names.length - 1)];
 		return result;
 	}
 }
-
+window.generateBabyName = generateBabyName;
 DefineMacroS("generateBabyName", generateBabyName);
 
-window.bulkProduceValue = function(plant, quantity = 250) {
-	if(plant !== undefined){
-		let baseCost = plant.plant_cost * quantity / 2;
-		let seasonBoost = !plant.season.includes(V.season) ? 1.1 : 1;
+function bulkProduceValue(plant, quantity = 250) {
+	if (plant != null) {
+		const baseCost = (plant.plant_cost * quantity) / 2;
+		const seasonBoost = !plant.season.includes(V.season) ? 1.1 : 1;
 		return Math.floor(baseCost * seasonBoost);
 	}
 }
+window.bulkProduceValue = bulkProduceValue;
 
-
-window.pregnancyBellyVisible = function(){
-	let size = State.variables.sexStats.vagina.pregnancy.bellySize;
-	if(size <= 7) return false;
-	if(size <= 11 && State.variables.worn.upper.name !== "naked" && State.variables.worn.upper.type.includes("bellyShow")) return false;
-	if(size <= 17 && State.variables.worn.upper.type.includes("bellyHide")) return false;
+function pregnancyBellyVisible() {
+	const size = State.variables.sexStats.vagina.pregnancy.bellySize;
+	if (size <= 7) return false;
+	if (size <= 11 && State.variables.worn.upper.name !== "naked" && State.variables.worn.upper.type.includes("bellyShow")) return false;
+	if (size <= 17 && State.variables.worn.upper.type.includes("bellyHide")) return false;
 
 	return true;
 }
+window.pregnancyBellyVisible = pregnancyBellyVisible;
 
-
-window.toTitleCase = function(str) {
-	return str.replace(/\w\S*/g, function(txt){
-		return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
-	});
+function toTitleCase(str) {
+	return str.replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
 }
+window.toTitleCase = toTitleCase;
 
-window.numbersBetween = (start, end, step = 1) => Array.from({ length: (end - start) / step + 1}, (_, i) => start + (i * step));
+function numbersBetween(start, end, step = 1) {
+	return Array.from({ length: (end - start) / step + 1 }, (_, i) => start + i * step);
+}
+window.numbersBetween = numbersBetween;
 
-window.getRobinLocation = function(){
-	if (V.NPCName[V.NPCNameList.indexOf("Robin")].init !== 1){
+function getRobinLocation() {
+	if (V.NPCName[V.NPCNameList.indexOf("Robin")].init !== 1) {
 		return;
-
-	} else if (V.robinlocationoverride && V.robinlocationoverride.during.includes(V.hour)){
-		return T.robin_location = V.robinlocationoverride.location;
-
-	} else if (V.robinmissing === "docks"){
-		return T.robin_location = "docks";
-
-	} else if (V.robinmissing === "landfill"){
-		return T.robin_location = "landfill";
-
-	} else if (V.robinmissing === "dinner"){
-		return T.robin_location = "dinner";
-
-	} else if (V.robinmissing === "pillory"){
-		return T.robin_location = "pillory";
-
-	} else if (!between(V.hour, 7, 20)){ //if hour is 6 or lower, or 21 or higher
-		return T.robin_location = "sleep";
-
-	} else if (V.schoolday === 1 && between(V.hour, 8, 15)){
-		return T.robin_location = "school";
-
-	} else if ((V.weekday === 7 || V.weekday === 1) && between(V.hour, 9, 16) && V.NPCName[V.NPCNameList.indexOf("Robin")].trauma < 80){
-		if (V.season === "winter"){
-			return T.robin_location = "park";
+	} else if (V.robinlocationoverride && V.robinlocationoverride.during.includes(V.hour)) {
+		T.robin_location = V.robinlocationoverride.location;
+	} else if (["docks", "landfill", "dinner", "pillory"].includes(V.robinmissing)) {
+		T.robin_location = V.robinmissing;
+	} else if (!between(V.hour, 7, 20)) { // if hour is 6 or lower, or 21 or higher
+		T.robin_location = "sleep";
+	} else if (V.schoolday === 1 && between(V.hour, 8, 15)) {
+		return (T.robin_location = "school");
+	} else if ((V.weekday === 7 || V.weekday === 1) && between(V.hour, 9, 16) && V.NPCName[V.NPCNameList.indexOf("Robin")].trauma < 80) {
+		if (V.season === "winter") {
+			T.robin_location = "park";
 		} else {
-			return T.robin_location = "beach";
+			T.robin_location = "beach";
 		}
-
-	} else if (V.halloween === 1 && between(V.hour, 16, 18) && V.monthday === 31){
-		return T.robin_location = "halloween";
-
+	} else if (V.halloween === 1 && between(V.hour, 16, 18) && V.monthday === 31) {
+		T.robin_location = "halloween";
 	} else {
-		return T.robin_location = "orphanage";
+		T.robin_location = "orphanage";
 	}
+	return T.robin_location;
 }
+window.getRobinLocation = getRobinLocation;
 
-window.setRobinLocationOverride = function(loc, hour){
-	let override = {
-		"location": loc,
-		"during": [],
+function setRobinLocationOverride(loc, hour) {
+	const override = {
+		location: loc,
+		during: [],
 	};
 	if (Array.isArray(hour)) override.during = hour;
 	else override.during = [hour];
-
 	// note: overrides get reset at midnight (in the <<day>> widget)
 	V.robinlocationoverride = override;
-	return;
 }
+window.setRobinLocationOverride = setRobinLocationOverride;
 
-window.getRobinCrossdressingStatus = function(crossdressLevel){
-	//Note returns 2 if Robin is crossdressing or 0 if not comfortable enough at that location
-	//Traumatised Robin will not crossdress.
-	if (V.NPCName[V.NPCNameList.indexOf("Robin")].init !== 1){
+function getRobinCrossdressingStatus(crossdressLevel) {
+	// Note returns 2 if Robin is crossdressing or 0 if not comfortable enough at that location
+	// Traumatised Robin will not crossdress.
+	if (V.NPCName[V.NPCNameList.indexOf("Robin")].init !== 1) {
 		return;
 	}
 	T.robin_cd = 0;
-	if (V.NPCName[V.NPCNameList.indexOf("Robin")].trauma >= 40){
+	if (V.NPCName[V.NPCNameList.indexOf("Robin")].trauma >= 40) {
 		return;
 	}
-	switch (getRobinLocation()){
+	switch (getRobinLocation()) {
 		case "orphanage":
 		case "sleep":
 			if (crossdressLevel >= 2) T.robin_cd = 2;
@@ -800,9 +715,10 @@ window.getRobinCrossdressingStatus = function(crossdressLevel){
 	}
 	return T.robin_cd;
 }
+window.getRobinCrossdressingStatus = getRobinCrossdressingStatus;
 
 window.DefaultActions = {
-	create: function (isMinimal = false, preload = false) {
+	create(isMinimal = false, preload = false) {
 		let storage = {};
 		setup.actionsTypes.combatTypes.forEach(type => {
 			storage[type] = {};
@@ -812,10 +728,10 @@ window.DefaultActions = {
 				setup.actionsTypes.personTypes.forEach(person => {
 					storage[type][person] = {};
 					setup.actionsTypes.actionTypes.forEach(part => {
-						if (person === 'Tentacles' && part === 'askActions') {
+						if (person === "Tentacles" && part === "askActions") {
 							// Do not add askActions to tentacle enemies.
 							return;
-						} else if (person !== 'Tentacles' && part === 'regrab') {
+						} else if (person !== "Tentacles" && part === "regrab") {
 							// Do not add regrab to non-tentacle enemies.
 							return;
 						}
@@ -830,77 +746,77 @@ window.DefaultActions = {
 		}
 		return storage;
 	},
-	check: function (storage) {
+	check(storage) {
 		if (storage === undefined) {
 			return;
 		}
-		if (storage['consensual'] === undefined || storage['rape'] === undefined) {
+		if (storage["consensual"] === undefined || storage["rape"] === undefined) {
 			storage = this.create(true, true);
 		}
 		return storage;
 	},
-	setup: function (recreate = false) {
+	setup(recreate = false) {
 		if (recreate || V.actionDefaults === undefined) {
 			return this.create(true);
 		}
 		return V.actionDefaults;
 	},
-	load: function (from = {}) {
+	load(from = {}) {
 		Object.keys(from).forEach(type => {
 			Object.keys(from[type]).forEach(person => {
 				Object.keys(from[type][person]).forEach(part => {
-					let actions = this.get(type, person, part);
+					const actions = this.get(type, person, part);
 					if (Array.isArray(actions)) {
 						actions.forEach(action => {
 							from[type][person][part].pushUnique(action);
 						});
 					} else {
-						if (part === 'regrab') {
-							let action = actions ? 1 : 0;
+						if (part === "regrab") {
+							const action = actions ? 1 : 0;
 							from[type][person][part].pushUnique(action);
 						}
 					}
-				})
+				});
 			});
 		});
 		return from;
 	},
-	loadOld: function (from, to) {
+	loadOld(from, to) {
 		setup.actionsTypes.personTypes.forEach(person => {
 			setup.actionsTypes.combatTypes.forEach(type => {
 				setup.actionsTypes.actionTypes.forEach(part => {
-					let actions = this.get(person, type, part, from);
+					const actions = this.get(person, type, part, from);
 					if (Array.isArray(actions)) {
 						actions.forEach(action => {
 							this.add(type, person, part, action, { value: to });
 						});
 					} else {
-						if (part === 'regrab') {
-							let action = actions ? 1 : 0;
+						if (part === "regrab") {
+							const action = actions ? 1 : 0;
 							this.add(type, person, part, action, { value: to });
 						}
 					}
-				})
+				});
 			});
 		});
 		return to;
 	},
-	save: function (from, callback = this.add) {
+	save(from, callback = this.add) {
 		if (from === undefined) {
 			return;
 		}
 		V.actionDefaults = this.setup(true);
 		// Assume the structure is valid.
-		let defaultTypes = Object.keys(from);
+		const defaultTypes = Object.keys(from);
 		defaultTypes.forEach(type => {
-			let defaultPeople = Object.keys(from[type]);
+			const defaultPeople = Object.keys(from[type]);
 			defaultPeople.forEach(person => {
-				let defaultParts = Object.keys(from[type][person]);
+				const defaultParts = Object.keys(from[type][person]);
 				defaultParts.forEach(part => {
-					let actionSets = from[type][person][part];
+					const actionSets = from[type][person][part];
 					if (actionSets !== undefined) {
 						actionSets.forEach(action => {
-							if (part === 'regrab') {
+							if (part === "regrab") {
 								action = action ? 1 : 0;
 							}
 							callback(type, person, part, action, { value: V.actionDefaults });
@@ -910,8 +826,8 @@ window.DefaultActions = {
 			});
 		});
 	},
-	add: function (type, person, part, action, to = { value: V.actionDefaults }) {
-		if (action === 'rest') {
+	add(type, person, part, action, to = { value: V.actionDefaults }) {
+		if (action === "rest") {
 			return;
 		}
 		if (to.value[type][person] === undefined) {
@@ -922,12 +838,12 @@ window.DefaultActions = {
 		}
 		to.value[type][person][part].pushUnique(action);
 	},
-	addMany: function (type, person, part, actions, to = { value: V.actionDefaults }) {
-		let filteredActions = actions.map(action => {
-			if (part === 'regrab') {
+	addMany(type, person, part, actions, to = { value: V.actionDefaults }) {
+		const filteredActions = actions.map(action => {
+			if (part === "regrab") {
 				return action ? 1 : 0;
 			}
-			if (action !== 'rest') {
+			if (action !== "rest") {
 				return action;
 			}
 		});
@@ -944,149 +860,182 @@ window.DefaultActions = {
 			to.value[type][person][part].pushUnique(action);
 		});
 	},
-	get: function (type, person, part, from = V.actionDefaults, defaultValue = 'rest') {
-		if (from[type] === undefined
-			|| from[type][person] === undefined
-			|| from[type][person][part] === undefined) {
-			return [ defaultValue ];
+	get(type, person, part, from = V.actionDefaults, defaultValue = "rest") {
+		if (
+			from[type] === undefined ||
+			from[type][person] === undefined ||
+			from[type][person][part] === undefined
+		) {
+			return [defaultValue];
 		}
 		return from[type][person][part];
 	},
-	setDefaults: function () {
+	setDefaults() {
 		V.actionDefaults = this.create(true);
-		let type = 'rape';
-		this.addMany(type, 'Submissive', 'leftaction', ['leftchest']);
-		this.addMany(type, 'Submissive', 'rightaction', ['rightchest']);
-		this.addMany(type, 'Submissive', 'mouthaction', ['plead', 'suck', 'kiss', 'breastsuck']);
-		this.addMany(type, 'Submissive', 'penisaction', ['tease', 'cooperate']);
-		this.addMany(type, 'Submissive', 'vaginaaction', ['penistease', 'cooperate']);
-		this.addMany(type, 'Submissive', 'anusaction', ['penistease', 'cooperate']);
-		this.addMany(type, 'Submissive', 'feetaction', ['grabrub', 'grabrub', 'vaginagrabrub']);
-		this.addMany(type, 'Defiant', 'leftaction', ['lefthit', 'leftstruggle']);
-		this.addMany(type, 'Defiant', 'rightaction', ['penwhack', 'righthit', 'rightstruggle', 'hypnosiswhack']);
-		this.addMany(type, 'Defiant', 'mouthaction', ['pullaway', 'bite', 'breastbite', 'headbutt']);
-		this.addMany(type, 'Defiant', 'penisaction', ['escape', 'otheranusescape', 'othermouthescape']);
-		this.addMany(type, 'Defiant', 'vaginaaction', ['escape', 'othermouthescape']);
-		this.addMany(type, 'Defiant', 'anusaction', ['escape', 'othermouthescape']);
-		this.addMany(type, 'Defiant', 'feetaction', ['kick']);
-		this.addMany(type, 'Tentacles', 'regrab', [0]);
-		type = 'consensual';
-		this.addMany(type, 'Submissive', 'leftaction', ['leftchest']);
-		this.addMany(type, 'Submissive', 'rightaction', ['rightchest']);
-		this.addMany(type, 'Submissive', 'mouthaction', ['kiss', 'suck', 'breastsuck', 'breastlick']);
-		this.addMany(type, 'Submissive', 'penisaction', ['tease', 'cooperate']);
-		this.addMany(type, 'Submissive', 'vaginaaction', ['penistease', 'cooperate']);
-		this.addMany(type, 'Submissive', 'anusaction', ['penistease', 'cooperate']);
-		this.addMany(type, 'Defiant', 'leftaction', [0]);
-		this.addMany(type, 'Defiant', 'rightaction', ['penwhack']);
-		this.addMany(type, 'Defiant', 'mouthaction', ['breastpull', 'breastclosed']);
-		this.addMany(type, 'Defiant', 'penisaction', ['escape', 'otheranusescape', 'othermouthescape']);
-		this.addMany(type, 'Defiant', 'vaginaaction', ['escape', 'othermouthescape']);
-		this.addMany(type, 'Defiant', 'anusaction', ['escape', 'othermouthescape']);
-		this.addMany(type, 'Tentacles', 'regrab', [0]);
+		let type = "rape";
+		this.addMany(type, "Submissive", "leftaction", ["leftchest"]);
+		this.addMany(type, "Submissive", "rightaction", ["rightchest"]);
+		this.addMany(type, "Submissive", "mouthaction", ["plead", "suck", "kiss", "breastsuck"]);
+		this.addMany(type, "Submissive", "penisaction", ["tease", "cooperate"]);
+		this.addMany(type, "Submissive", "vaginaaction", ["penistease", "cooperate"]);
+		this.addMany(type, "Submissive", "anusaction", ["penistease", "cooperate"]);
+		this.addMany(type, "Submissive", "feetaction", ["grabrub", "grabrub", "vaginagrabrub"]);
+		this.addMany(type, "Defiant", "leftaction", ["lefthit", "leftstruggle"]);
+		this.addMany(type, "Defiant", "rightaction", ["penwhack", "righthit", "rightstruggle", "hypnosiswhack"]);
+		this.addMany(type, "Defiant", "mouthaction", ["pullaway", "bite", "breastbite", "headbutt"]);
+		this.addMany(type, "Defiant", "penisaction", ["escape", "otheranusescape", "othermouthescape"]);
+		this.addMany(type, "Defiant", "vaginaaction", ["escape", "othermouthescape"]);
+		this.addMany(type, "Defiant", "anusaction", ["escape", "othermouthescape"]);
+		this.addMany(type, "Defiant", "feetaction", ["kick"]);
+		this.addMany(type, "Tentacles", "regrab", [0]);
+		type = "consensual";
+		this.addMany(type, "Submissive", "leftaction", ["leftchest"]);
+		this.addMany(type, "Submissive", "rightaction", ["rightchest"]);
+		this.addMany(type, "Submissive", "mouthaction", ["kiss", "suck", "breastsuck", "breastlick"]);
+		this.addMany(type, "Submissive", "penisaction", ["tease", "cooperate"]);
+		this.addMany(type, "Submissive", "vaginaaction", ["penistease", "cooperate"]);
+		this.addMany(type, "Submissive", "anusaction", ["penistease", "cooperate"]);
+		this.addMany(type, "Defiant", "leftaction", [0]);
+		this.addMany(type, "Defiant", "rightaction", ["penwhack"]);
+		this.addMany(type, "Defiant", "mouthaction", ["breastpull", "breastclosed"]);
+		this.addMany(type, "Defiant", "penisaction", ["escape", "otheranusescape", "othermouthescape"]);
+		this.addMany(type, "Defiant", "vaginaaction", ["escape", "othermouthescape"]);
+		this.addMany(type, "Defiant", "anusaction", ["escape", "othermouthescape"]);
+		this.addMany(type, "Tentacles", "regrab", [0]);
 		return V.actionDefaults;
-	}
-}
+	},
+};
 
 function selectWardrobe(targetLocation = V.wardrobe_location) {
 	return ((!targetLocation || targetLocation === "wardrobe" || !V.wardrobes[targetLocation]) ? V.wardrobe : V.wardrobes[targetLocation]);
 }
 window.selectWardrobe = selectWardrobe;
 
-window.transferClothing = function(slot, index, newWardrobe){
+function transferClothing(slot, index, newWardrobe) {
 	let oldWardrobeObject;
-	if(V.wardrobe_location === "wardrobe"){
+	if (V.wardrobe_location === "wardrobe") {
 		oldWardrobeObject = V.wardrobe;
 	} else {
 		oldWardrobeObject = V.wardrobes[V.wardrobe_location];
 	}
 	let newWardrobeObject;
-	if(newWardrobe === "wardrobe"){
+	if (newWardrobe === "wardrobe") {
 		newWardrobeObject = V.wardrobe;
 	} else {
 		newWardrobeObject = V.wardrobes[newWardrobe];
 	}
-	if(oldWardrobeObject && newWardrobeObject){
+	if (oldWardrobeObject && newWardrobeObject) {
 		newWardrobeObject[slot].push(oldWardrobeObject[slot][index]);
 		oldWardrobeObject[slot].deleteAt(index);
 	}
-	return;
 }
+window.transferClothing = transferClothing;
 
-window.clothingData = function(slot, item, data){
-	if(item[data] !== undefined) return item[data];
-	return setup.clothes[slot][clothesIndex(slot,item)][data];
+function clothingData(slot, item, data) {
+	if (item[data] !== undefined) return item[data];
+	return setup.clothes[slot][clothesIndex(slot, item)][data];
 }
+window.clothingData = clothingData;
 
-window.clothesDataTrimmerLoop = function(){
-	if(!V.passage || V.passage === "Start") return;
+function clothesDataTrimmerLoop() {
+	if (!V.passage || V.passage === "Start") return;
 	const wardrobeKeys = Object.keys(V.wardrobes);
 	setup.clothes_all_slots.forEach(slot => {
 		clothesDataTrimmer(V.worn[slot]);
 		clothesDataTrimmer(V.carried[slot]);
-		if(Array.isArray(V.wardrobe[slot])){
+		if (Array.isArray(V.wardrobe[slot])) {
 			V.wardrobe[slot].forEach(item => {
 				clothesDataTrimmer(item);
-			})
+			});
 		}
-		if(Array.isArray(V.store[slot])){
+		if (Array.isArray(V.store[slot])) {
 			V.store[slot].forEach(item => {
 				clothesDataTrimmer(item);
-			})
+			});
 		}
 
-		for (let i = 0, l = wardrobeKeys.length; i < l; i++){
-			if(Array.isArray(V.wardrobes[wardrobeKeys[i]][slot])){
+		for (let i = 0, l = wardrobeKeys.length; i < l; i++) {
+			if (Array.isArray(V.wardrobes[wardrobeKeys[i]][slot])) {
 				V.wardrobes[wardrobeKeys[i]][slot].forEach(item => {
 					clothesDataTrimmer(item);
-				})
+				});
 			}
 		}
-		if(V.tryOn !== undefined){
-			if(V.tryOn.ownedStored !== undefined){
-				if(V.tryOn.ownedStored[slot] !== undefined && V.tryOn.ownedStored[slot] !== null){
+		if (V.tryOn !== undefined) {
+			if (V.tryOn.ownedStored !== undefined) {
+				if (V.tryOn.ownedStored[slot] !== undefined && V.tryOn.ownedStored[slot] !== null) {
 					clothesDataTrimmer(V.tryOn.ownedStored[slot]);
 				}
 			}
-			if(V.tryOn.tryingOn !== undefined){
-				if(V.tryOn.tryingOn[slot] !== undefined && V.tryOn.tryingOn[slot] !== null){
+			if (V.tryOn.tryingOn !== undefined) {
+				if (V.tryOn.tryingOn[slot] !== undefined && V.tryOn.tryingOn[slot] !== null) {
 					clothesDataTrimmer(V.tryOn.tryingOn[slot]);
 				}
 			}
 		}
 	});
 }
-
-window.clothesDataTrimmer = function(item){
-	if(!item) return;
-	const toDelete = ["name_cap","iconFile","accIcon","notuck","skirt","description","colour_options","accessory_colour_options","fabric_strength","integrity_max","bustresize","sleeve_img","breast_img","exposed_base","vagina_exposed_base","anus_exposed_base","state_top_base","state_base","word","femininity","strap","cost","shop","short"];
-	//To prevent it from running on variables multiple times, when updating toDelete, the last of the new additions should be added here
-	const trimmerVersion = ["shop","short"];
+window.clothesDataTrimmerLoop = clothesDataTrimmerLoop;
+
+function clothesDataTrimmer(item) {
+	if (!item) return;
+	const toDelete = [
+		"name_cap",
+		"iconFile",
+		"accIcon",
+		"notuck",
+		"skirt",
+		"description",
+		"colour_options",
+		"accessory_colour_options",
+		"fabric_strength",
+		"integrity_max",
+		"bustresize",
+		"sleeve_img",
+		"breast_img",
+		"exposed_base",
+		"vagina_exposed_base",
+		"anus_exposed_base",
+		"state_top_base",
+		"state_base",
+		"word",
+		"femininity",
+		"strap",
+		"cost",
+		"shop",
+		"short",
+	];
+	// To prevent it from running on variables multiple times, when updating toDelete, the last of the new additions should be added here
+	const trimmerVersion = ["shop", "short"];
 	let version = 0;
 	let indexToUpdateVersion = toDelete.indexOf(trimmerVersion[version]);
 	toDelete.forEach((v, index) => {
-		if(indexToUpdateVersion === -1) {
-			//Do Nothing
-		} else if(item[v] !== undefined && item[trimmerVersion[version]] !== undefined) {
+		if (indexToUpdateVersion === -1) {
+			// Do Nothing
+		} else if (item[v] !== undefined && item[trimmerVersion[version]] !== undefined) {
 			delete item[v];
 		}
-		if(indexToUpdateVersion === index) {
+		if (indexToUpdateVersion === index) {
 			version++;
-			indexToUpdateVersion = toDelete.indexOf(trimmerVersion[version])
+			indexToUpdateVersion = toDelete.indexOf(trimmerVersion[version]);
 		}
 	});
 }
+window.clothesDataTrimmer = clothesDataTrimmer;
 
-function clothesReturnLocation(item, type){
-	if(!V.multipleWardrobes) return "wardrobe";
-	let isolated = ["asylum","prison"];
+function clothesReturnLocation(item, type) {
+	if (!V.multipleWardrobes) return "wardrobe";
+	const isolated = ["asylum", "prison"];
 	let lastTaken = item.lastTaken;
-	if (!lastTaken || (V.multipleWardrobes !== "all" && !isolated.includes(lastTaken))
-		|| !V.wardrobes[lastTaken]
-		|| !V.wardrobes[lastTaken].unlocked) {
-		lastTaken = 'wardrobe';
+	if (
+		!lastTaken ||
+		(V.multipleWardrobes !== "all" && !isolated.includes(lastTaken)) ||
+		!V.wardrobes[lastTaken] ||
+		!V.wardrobes[lastTaken].unlocked
+	) {
+		lastTaken = "wardrobe";
 	}
-	switch(type){
+	switch (type) {
 		case "rebuy":
 			if (isolated.includes(V.location) && item.type.includes(V.location)) return V.location;
 			break;
@@ -1100,52 +1049,54 @@ window.clothesReturnLocation = clothesReturnLocation;
 
 function resetClothingState(slot) {
 	if (!slot || slot === "genitals") return;
-	const setupItem = setup.clothes[slot][clothesIndex(slot,V.worn[slot])];
+	const setupItem = setup.clothes[slot][clothesIndex(slot, V.worn[slot])];
 	// Overwrite the following properties of $worn[slot], IF the corresponding properties are defined in the setupItem.
 	// Note that no single item actually has ALL of these properties; It only changes the properties that DO exist on the item.
 	V.worn[slot] = {
 		...V.worn[slot],
-		...Object.fromEntries(Object.entries({
-			state: setupItem.state_base,
-			state_top: setupItem.state_top_base,
-			exposed: setupItem.exposed_base,
-			skirt_down: setupItem.skirt_down,
-			vagina_exposed: setupItem.vagina_exposed_base,
-			anus_exposed: setupItem.anus_exposed_base,
-		}).filter(([_,p]) => p != undefined))
+		...Object.fromEntries(
+			Object.entries({
+				state: setupItem.state_base,
+				state_top: setupItem.state_top_base,
+				exposed: setupItem.exposed_base,
+				skirt_down: setupItem.skirt_down,
+				vagina_exposed: setupItem.vagina_exposed_base,
+				anus_exposed: setupItem.anus_exposed_base,
+			}).filter(([_, p]) => p != null)
+		),
 	};
 }
 window.resetClothingState = resetClothingState;
 
 /* Returns array of clothing items that are stored in [loc] */
-window.clothingInStorage = function(loc) {
-	if(loc == null) return;
-	let clothing = [];
-	for(const slot of setup.clothingLayer.all) {
-		let item = V.store[slot].find(item => item.location === loc);
-		if(item && !item.outfitSecondary) {
+function clothingInStorage(loc) {
+	if (loc == null) return;
+	const clothing = [];
+	for (const slot of setup.clothingLayer.all) {
+		const item = V.store[slot].find(item => item.location === loc);
+		if (item && !item.outfitSecondary) {
 			item["slot"] = slot;
 			clothing.push(item);
 		}
 	}
 	return clothing;
 }
+window.clothingInStorage = clothingInStorage;
 
 /* Returns name of the current worn outfit, or "none" if no matches are found */
-window.currentOutfit = function() {
-	let compareOutfit = (outfit) => {
-		for(const slot of setup.clothingLayer.all) {
-			if(V.worn[slot].name != (outfit[slot] || "naked"))
-				return false;
+function currentOutfit() {
+	const compareOutfit = outfit => {
+		for (const slot of setup.clothingLayer.all) {
+			if (V.worn[slot].name !== (outfit[slot] || "naked")) return false;
 		}
 		return true;
-	}
-	for(const outfit of V.outfit) {
-		if(compareOutfit(outfit))
-			return outfit.name;
+	};
+	for (const outfit of V.outfit) {
+		if (compareOutfit(outfit)) return outfit.name;
 	}
 	return "none";
 }
+window.currentOutfit = currentOutfit;
 
 function isConnectedToHood(slot) {
 	// Note: this function currently only works on hoods in the "head" slot, NOT the "over_head" slot.
@@ -1156,166 +1107,210 @@ function isConnectedToHood(slot) {
 	if (V.worn[slot].hood && V.worn[slot].outfitSecondary[1] !== "broken") return true;
 
 	// Use the primary clothing slot for the next check if this item is connected to an outfit (and is not the primary item)
-	if (V.worn[slot].outfitSecondary && V.worn[slot].outfitSecondary[1] !== "broken"){
+	if (V.worn[slot].outfitSecondary && V.worn[slot].outfitSecondary[1] !== "broken") {
 		slot = V.worn[slot].outfitSecondary[0];
 	}
-	if (V.worn[slot].hoodposition && (V.worn[slot].hoodposition == "down" || (V.worn[slot].hoodposition == "up" && V.worn[slot].outfitPrimary.head !== "broken" && V.worn.head.hood == 1))){
+	if (V.worn[slot].hoodposition && (V.worn[slot].hoodposition === "down" || (V.worn[slot].hoodposition === "up" && V.worn[slot].outfitPrimary.head !== "broken" && V.worn.head.hood === 1))){
 		return true;
 	}
 	return false;
 }
 window.isConnectedToHood = isConnectedToHood;
 
-//the 'modder' variable is specifically for modders name, should be kept as a short string
-window.clothesIndex = function(slot, itemToIndex) {
-	if(!slot || !itemToIndex || !itemToIndex.name || !itemToIndex.variable) {
+// the 'modder' variable is specifically for modders name, should be kept as a short string
+function clothesIndex(slot, itemToIndex) {
+	if (!slot || !itemToIndex || !itemToIndex.name || !itemToIndex.variable) {
 		/* console.log(`clothesIndex - slot or valid object not provided`); */
-		Errors.report(`[clothesIndex]: slot or valid object not provided`, { 'Stacktrace' : Utils.GetStack(), slot, itemToIndex });
+		Errors.report(`[clothesIndex]: slot or valid object not provided`, {
+			Stacktrace: Utils.GetStack(),
+			slot,
+			itemToIndex,
+		});
 		return 0;
 	}
-	let index = setup.clothes[slot].findIndex((item) => item.variable === itemToIndex.variable && item.modder === itemToIndex.modder)
-	if(index === -1){
-		console.log(`clothesIndex - ${slot} clothing item index not found for the '${itemToIndex.name}' with the modder set to '${itemToIndex.modder}'`);
+	let index = setup.clothes[slot].findIndex(
+		item => item.variable === itemToIndex.variable && item.modder === itemToIndex.modder
+	);
+	if (index === -1) {
+		console.log(
+			`clothesIndex - ${slot} clothing item index not found for the '${itemToIndex.name}' with the modder set to '${itemToIndex.modder}'`
+		);
 		/* try and correct .modder mismatches */
-		let matches = setup.clothes[slot].filter((item) => item.variable === itemToIndex.variable);
+		const matches = setup.clothes[slot].filter(item => item.variable === itemToIndex.variable);
 		if (matches.length === 1) {
-			let recovery = setup.clothes[slot].find((item) => item.variable === itemToIndex.variable);
+			const recovery = setup.clothes[slot].find(item => item.variable === itemToIndex.variable);
 			itemToIndex.modder = recovery.modder;
 			index = recovery.index;
 			console.log(`attempting to recover the mismatch, new modder is '${recovery.modder}'`);
 			return index;
-		}
-		else {
+		} else {
 			console.log("recovery failed, matches: " + matches);
 			return 0;
 		}
 	}
 	return index;
 }
+window.clothesIndex = clothesIndex;
 
-window.currentSkillValue = function(skill){
+function currentSkillValue(skill) {
 	let result = V[skill];
-	if(!result && result !== 0) {
+	if (!result && result !== 0) {
 		/* console.log(`currentSkillValue - skill '${skill}' unknown`); */
-		Errors.report(`[currentSkillValue]: skill '${skill}' unknown.`, { 'Stacktrace' : Utils.GetStack(), skill });
+		Errors.report(`[currentSkillValue]: skill '${skill}' unknown.`, {
+			Stacktrace: Utils.GetStack(),
+			skill,
+		});
 		return 0;
-	};
-	if(['skulduggery','physique','danceskill','swimmingskill','athletics','willpower','tending','science','maths','english','history'].includes(skill) && V.moorLuck > 0){
-		result = Math.floor(result * (1 + (V.moorLuck / 100)));
 	}
-	if(['physique','danceskill','swimmingskill','athletics'].includes(skill) && V.sexStats.vagina.pregnancy.bellySize >= 10){
-		switch(V.pregnancyStats.mother){
-			case 0: T.pregnancyModifier = 30;
-			break;
-			case 1: T.pregnancyModifier = 40;
-			break;
-			case 2: T.pregnancyModifier = 50;
-			break;
-			case 3: T.pregnancyModifier = 65;
-			break;
-			case 4: T.pregnancyModifier = 100;
-			break;
+	if (
+		[
+			"skulduggery",
+			"physique",
+			"danceskill",
+			"swimmingskill",
+			"athletics",
+			"willpower",
+			"tending",
+			"science",
+			"maths",
+			"english",
+			"history",
+		].includes(skill) &&
+		V.moorLuck > 0
+	) {
+		result = Math.floor(result * (1 + V.moorLuck / 100));
+	}
+	if (
+		["physique", "danceskill", "swimmingskill", "athletics"].includes(skill) &&
+		V.sexStats.vagina.pregnancy.bellySize >= 10
+	) {
+		switch (V.pregnancyStats.mother) {
+			case 0:
+				T.pregnancyModifier = 30;
+				break;
+			case 1:
+				T.pregnancyModifier = 40;
+				break;
+			case 2:
+				T.pregnancyModifier = 50;
+				break;
+			case 3:
+				T.pregnancyModifier = 65;
+				break;
+			case 4:
+				T.pregnancyModifier = 100;
+				break;
 		}
-		result = Math.floor(result * (1 - (V.sexStats.vagina.pregnancy.bellySize / T.pregnancyModifier)));
+		result = Math.floor(
+			result * (1 - V.sexStats.vagina.pregnancy.bellySize / T.pregnancyModifier)
+		);
 	}
-	switch(skill){
-		case 'skulduggery':
-			if(V.worn.hands.type.includes("sticky_fingers")){
-				result = Math.floor(result * 1.05);
-			}
-			if(V.harpy >= 2 || V.cat >= 2){
-				result = Math.floor(result * 1.05);
-			}
-		break;
-		case 'physique':
-			if(["forest", "moor", "farm"].includes(V.location)){
-				if(V.worn.feet.type.includes("heels")){
-					result = Math.floor(result * (1 - (V.worn.feet.reveal / 5000)));
+	let modifier = 1;
+	switch (skill) {
+		case "skulduggery":
+			if (V.worn.hands.type.includes("sticky_fingers")) modifier += 0.05;
+			if (V.harpy >= 2 || V.cat >= 2) modifier += 0.05;
+			result = Math.floor(result * modifier);
+			break;
+		case "physique":
+			if (["forest", "moor", "farm"].includes(V.location)) {
+				if (V.worn.feet.type.includes("heels")) {
+					result = Math.floor(result * (1 - V.worn.feet.reveal / 5000));
 				}
-				if(V.worn.feet.type.includes("rugged")){
-					result = Math.floor(result * (1 + (V.feetskill / 10000)));
+				if (V.worn.feet.type.includes("rugged")) {
+					result = Math.floor(result * (1 + V.feetskill / 10000));
 				}
 			}
-		break;
-		case 'danceskill':
-			if(V.worn.under_upper.type.includesAny("dance", "naked") && V.worn.under_lower.type.includesAny("dance", "naked") && V.worn.upper.type.includesAny("dance", "naked") && V.worn.lower.type.includesAny("dance", "naked")){
+			break;
+		case "danceskill":
+			if (
+				V.worn.under_upper.type.includesAny("dance", "naked") &&
+				V.worn.under_lower.type.includesAny("dance", "naked") &&
+				V.worn.upper.type.includesAny("dance", "naked") &&
+				V.worn.lower.type.includesAny("dance", "naked")
+			) {
 				result = Math.floor(result * 1.05);
 			}
-			if(V.worn.feet.type.includes("shackle")){
+			if (V.worn.feet.type.includes("shackle")) {
 				result = Math.floor(result * 0.5);
 			}
-		break;
-		case 'swimmingskill':
-			let heels = 0;
-			if(V.worn.under_upper.type.includesAny("swim", "naked") && V.worn.under_lower.type.includesAny("swim", "naked") && V.worn.upper.type.includesAny("swim", "naked") && V.worn.lower.type.includesAny("swim", "naked")){
+			break;
+		case "swimmingskill":
+			if (
+				V.worn.under_upper.type.includesAny("swim", "naked") &&
+				V.worn.under_lower.type.includesAny("swim", "naked") &&
+				V.worn.upper.type.includesAny("swim", "naked") &&
+				V.worn.lower.type.includesAny("swim", "naked")
+			) {
 				result = Math.floor(result * 1.05);
 			}
-			if(V.worn.feet.type.includes("swim")){
-				result = Math.floor(result * (1 + (V.feetskill / 10000)));
-			} else if(!V.worn.feet.type.includes("naked")){
-				if(V.worn.feet.type.includes("heels")){
-					heels = 0.1;
-				} else {
-					heels = 0;
-				}
-				result = Math.floor(result * (0.9 + (V.feetskill / 10000) - heels));
+			if (V.worn.feet.type.includes("swim")) {
+				result = Math.floor(result * (1 + V.feetskill / 10000));
+			} else if (!V.worn.feet.type.includes("heels")) {
+				result = Math.floor(result * (0.8 + V.feetskill / 10000));
+			} else if (!V.worn.feet.type.includes("naked")) {
+				result = Math.floor(result * (0.9 + V.feetskill / 10000));
 			}
-			if(V.worn.feet.type.includes("shackle")){
+			if (V.worn.feet.type.includes("shackle")) {
 				result = Math.floor(result * 0.5);
 			}
-		break;
-		case 'athletics':
-			if(["forest", "moor", "farm"].includes(V.location)){
-				if(V.worn.feet.type.includes("heels")){
-					result = Math.floor(result * (1 - (V.worn.feet.reveal / 5000)));
+			break;
+		case "athletics":
+			if (["forest", "moor", "farm"].includes(V.location)) {
+				if (V.worn.feet.type.includes("heels")) {
+					result = Math.floor(result * (1 - V.worn.feet.reveal / 5000));
 				}
-				if(V.worn.feet.type.includes("rugged")){
-					result = Math.floor(result * (1 + (V.feetskill / 10000)));
+				if (V.worn.feet.type.includes("rugged")) {
+					result = Math.floor(result * (1 + V.feetskill / 10000));
 				}
 			}
-			if(V.worn.feet.type.includes("shackle")){
-				result = 0;
-			}
-		break;
-		case 'willpower':
-			if(V.parasite.left_ear.name == "slime" && V.parasite.right_ear.name == "slime"){
+			if (V.worn.feet.type.includes("shackle")) result /= 10;
+			break;
+		case "willpower":
+			if (V.parasite.left_ear.name === V.parasite.right_ear.name === "slime") {
 				result = Math.floor(result * 0.9);
 			}
-		break;
-		case 'tending':
-			if(V.backgroundTraits.includes("plantlover")){
-				result = Math.floor(result * (1 + (V.trauma / (V.traumamax * 2))));
+			break;
+		case "tending":
+			if (V.backgroundTraits.includes("plantlover")) {
+				result = Math.floor(result * (1 + V.trauma / (V.traumamax * 2)));
 			}
-		break;
+			break;
 	}
 	return result;
 }
+window.currentSkillValue = currentSkillValue;
 
-window.playerIsPenetrated = function(){
-	return [V.mouthstate, V.vaginastate, V.anusstate].some(s => ["penetrated","doublepenetrated","tentacle","tentacledeep"].includes(s))
+function playerIsPenetrated() {
+	return [V.mouthstate, V.vaginastate, V.anusstate].some(s =>
+		["penetrated", "doublepenetrated", "tentacle", "tentacledeep"].includes(s)
+	);
 }
+window.playerIsPenetrated = playerIsPenetrated;
 
-window.getTimeString = function(minutes = 0){
-	if (minutes < 0){
+function getTimeString(minutes = 0) {
+	if (minutes < 0) {
 		// come on don't try negative numbers, that's silly
 		return "0:00";
 	}
-	if (minutes < 10){
+	if (minutes < 10) {
 		return "0:0" + minutes;
-	} else if (minutes < 60){
+	} else if (minutes < 60) {
 		return "0:" + minutes;
 	} else {
 		const hours = Math.trunc(minutes / 60);
-		minutes = ("" + minutes % 60).padStart(2, '0');
+		minutes = ("" + (minutes % 60)).padStart(2, "0");
 		return hours + ":" + minutes;
 	}
 }
+window.getTimeString = getTimeString;
 
-window.npcAssignClothesToSet = function(upper, lower){
-	return {"upper":T.npcClothesItems.upper[upper], "lower":T.npcClothesItems.lower[lower]}
+function npcAssignClothesToSet(upper, lower) {
+	return { upper: T.npcClothesItems.upper[upper], lower: T.npcClothesItems.lower[lower] };
 }
+window.npcAssignClothesToSet = npcAssignClothesToSet;
 
-window.npcMakeNaked = function (npc, slot){
+function npcMakeNaked(npc, slot) {
 	if (slot === "upper") {
 		npc.chest = 0;
 	} else if (slot === "lower") {
@@ -1323,15 +1318,16 @@ window.npcMakeNaked = function (npc, slot){
 		if (npc.vagina !== "none") npc.vagina = 0;
 	}
 }
+window.npcMakeNaked = npcMakeNaked;
 
-window.npcEquipSet = function(npc, set) {
-	npc.clothes = {set: set.name};
-	Object.entries(set.clothes).forEach((item) => {
-		if (item[1].name === "naked"){
+function npcEquipSet(npc, set) {
+	npc.clothes = { set: set.name };
+	Object.entries(set.clothes).forEach(item => {
+		if (item[1].name === "naked") {
 			npcMakeNaked(npc, item[0]);
 		}
-		let itemData = setup.clothes[item[0]].find(c => c.name === item[1].name);
-		if(!itemData){
+		const itemData = setup.clothes[item[0]].find(c => c.name === item[1].name);
+		if (!itemData) {
 			npc.clothes[item[0]] = {
 				name: item[1].name,
 				integrity: item[1].integrity_max,
@@ -1344,60 +1340,72 @@ window.npcEquipSet = function(npc, set) {
 		}
 	});
 }
+window.npcEquipSet = npcEquipSet;
 
-window.npcSpecifiedClothes = function (npc, name){
-	let clothingItem = setup.npcClothesSets.filter((set) => set.name === name);
-	if(clothingItem.length > 0){
+function npcSpecifiedClothes(npc, name) {
+	const clothingItem = setup.npcClothesSets.filter(set => set.name === name);
+	if (clothingItem.length > 0) {
 		npcEquipSet(npc, clothingItem[0]);
 	} else {
-		console.log(`npcSpecifiedClothes - unable to find a clothing item with the name '${name}' for '${npc.fullDescription}'`)
+		console.log(
+			`npcSpecifiedClothes - unable to find a clothing item with the name '${name}' for '${npc.fullDescription}'`
+		);
 	}
 }
+window.npcSpecifiedClothes = npcSpecifiedClothes;
 
-/*npc.crossdressing: 0 - doesn't at all, 1 - sometimes, 2 - always*/
-window.npcClothes = function (npc, type){
-	let crossdressing = npc.crossdressing || 0;
-	let gender = ['n'];
+/* npc.crossdressing: 0 - doesn't at all, 1 - sometimes, 2 - always */
+function npcClothes(npc, type) {
+	const crossdressing = npc.crossdressing || 0;
+	const gender = ["n"];
 	/* if you don't want those always crossdressing to wear neutral clothes
 	let gender = [];
 	if(crossdressing !== 2) gender.push('n');
 	*/
 
-	if(crossdressing < 2) gender.push(npc.pronoun);
-	if(crossdressing > 0) gender.push(npc.pronoun === "m" ? "f" : "m");
-	let clothingOptions = setup.npcClothesSets.filter((set) => (set.type === type || !type) && gender.includes(set.gender));
+	if (crossdressing < 2) gender.push(npc.pronoun);
+	if (crossdressing > 0) gender.push(npc.pronoun === "m" ? "f" : "m");
+	let clothingOptions = setup.npcClothesSets.filter(
+		set => (set.type === type || !type) && gender.includes(set.gender)
+	);
 
-	if(npc.outfits){
-		let namedNpcClothing = clothingOptions.filter((set) => npc.outfits.includes(set.name));
-		if(namedNpcClothing.length > 0){
+	if (npc.outfits) {
+		const namedNpcClothing = clothingOptions.filter(set => npc.outfits.includes(set.name));
+		if (namedNpcClothing.length > 0) {
 			clothingOptions = namedNpcClothing;
 		}
 	}
-	if(clothingOptions.length > 0){
-		let clothesSet = clothingOptions.pluck();
+	if (clothingOptions.length > 0) {
+		const clothesSet = clothingOptions.pluck();
 		npcEquipSet(npc, clothesSet);
-		//Allows you to record the clothing set selected
+		// Allows you to record the clothing set selected
 		return clothesSet.name;
 	} else {
-		console.log(`npcClothes - unable to find a clothing set with the options for '${npc.fullDescription}' with type '${type}'`)
+		console.log(
+			`npcClothes - unable to find a clothing set with the options for '${npc.fullDescription}' with type '${type}'`
+		);
 	}
 }
+window.npcClothes = npcClothes;
 
-window.getWeekDay = function(day){
+function getWeekDay(day) {
 	// NOTE: This function takes an argument from 1 to 7. Avoid off-by-1 errors! It is NOT 0-6.
-	if (day && day >= 1 && day <= 7){
-		return ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][day-1];
+	if (day && day >= 1 && day <= 7) {
+		return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][day - 1];
 	} else {
-		throw new Error("INVALID DAY, day index: ["+day+"]");
+		throw new Error("INVALID DAY, day index: [" + day + "]");
 	}
 }
+window.getWeekDay = getWeekDay;
 
-window.waterproofCheck = function(clothing){
+function waterproofCheck(clothing) {
 	return clothing.type.includes("swim") || clothing.type.includes("stealthy");
 }
+window.waterproofCheck = waterproofCheck;
 
 function isLoveInterest(name) {
-	return V.loveInterest.primary === name || V.loveInterest.secondary === name || V.loveInterest.tertiary === name;
+	for (const l in V.loveInterest) if (V.loveInterest[l] === name) return true;
+	return false;
 }
 window.isLoveInterest = isLoveInterest;
 
@@ -1406,26 +1414,29 @@ function isBloodmoon() {
 }
 window.isBloodmoon = isBloodmoon;
 
-window.wraithSleepEventCheck = function(){
+function wraithSleepEventCheck() {
 	return V.wraith && V.wraith.state !== "" && V.wraith.nightmare === 1 && (V.moonstate === "evening" && V.hour >= 21 || V.moonstate === "morning" && V.hour < 5);
 }
+window.wraithSleepEventCheck = wraithSleepEventCheck;
 
-window.fameTotal = function() {
+function fameTotal() {
 	let result = 0;
 	for (const key in V.fame) {
 		result += V.fame[key];
 	}
 	return result;
 }
+window.fameTotal = fameTotal;
 
-window.fameSum = function(...fameTypes) {
+function fameSum(...fameTypes) {
 	let result = 0;
-	fameTypes.forEach(fameType => result += V.fame[fameType]);
+	fameTypes.forEach(fameType => (result += V.fame[fameType]));
 	return result;
 }
+window.fameSum = fameSum;
 
 function checkTFparts() {
-	const tfParts = {}
+	const tfParts = {};
 	Object.entries(V.transformationParts).forEach(([tfName,tf]) => /* Iterate over each transformation */
 		Object.entries(tf).forEach(([pName, pStatus]) => { /* Iterate over each part of each transformation */
 			if (pStatus !== "disabled" && pStatus !== "hidden"){ /* Filter out the parts that the player doesn't have or is suppressing */
@@ -1455,8 +1466,8 @@ window.getSexesFromRandomGroup = getSexesFromRandomGroup;
 function getColourClassFromPercentage(percentage) {
 	/* This function is for picking the right color to use when coloring various things, primarily the sidebar stats. */
 	/* When using this function, try to keep in mind what value of your input variable you want "red" to be at. 
-	 * Example: $drugged goes higher than 500, but we want the bar to become red at 500, so we call this function as getColourClassFromPercentage($drugged / 5).   
-	*/
+	 * Example: $drugged goes higher than 500, but we want the bar to become red at 500, so we call this function as getColourClassFromPercentage($drugged / 5).
+	 */
 	if (percentage <= 0) return "green";
 	if (percentage < 20) return "teal";
 	if (percentage < 40) return "lblue";
@@ -1468,22 +1479,22 @@ function getColourClassFromPercentage(percentage) {
 window.getColourClassFromPercentage = getColourClassFromPercentage;
 
 function playerCanBreedWith(npc) {
-	/* This function can accept either a named NPC's name, or an NPC object from either NPCList or NPCName. 
+	/* This function can accept either a named NPC's name, or an NPC object from either NPCList or NPCName.
 	 * Examples: playerCanBreedWith("Kylar"), or playerCanBreedWith($NPCList[0]) or playerCanBreedWith($NPCName[$NPCNameList.indexOf("Kylar")])
 	 * Returns true or false. If you give it garbage, like a totally wrong name, it'll return false, so be careful about silent failures like that.
-	*/
+	 */
 	if (typeof npc === "string") npc = V.NPCName[V.NPCNameList.indexOf(npc)];
-	
+
 	return (V.player.vaginaExist && npc.penis !== "none") || (V.player.penisExist && npc.vagina !== "none");
 }
 window.playerCanBreedWith = playerCanBreedWith;
 
 function outfitHoodPosition(outfit) {
-	/*This function is used to determine whether a hoodie in a given outfit set should have its hood up or down.
+	/* This function is used to determine whether a hoodie in a given outfit set should have its hood up or down.
 	 * It does this by comparing the upper and head slots to determine whether they're part of the same clothing item
-	*/
+	 */
 
-	let hoodie = setup.clothes.upper.find(item => item.name === outfit.upper);
+	const hoodie = setup.clothes.upper.find(item => item.name === outfit.upper);
 	if (hoodie.hoodposition === undefined) return "none";
 	if (outfit.head !== hoodie.outfitPrimary.head) return "down";
 	if (!outfit.colors) return "up";
@@ -1493,26 +1504,29 @@ function outfitHoodPosition(outfit) {
 }
 window.outfitHoodPosition = outfitHoodPosition;
 
-window.combatCharacterShadow = function() {
-	if(!V.options.characterLightEnabled || !V.options.images || !V.options.combatImages) return;
+function combatCharacterShadow() {
+	if (!V.options.characterLightEnabled || !V.options.images || !V.options.combatImages) return;
 	const targetClass = "char-shadow-combat";
 	const mainDiv = ".char_combat";
 
-	$(document).ready(() => {
+	$(() => {
 		$(mainDiv).find('img').filter((i, n) => n.className.match(new RegExp("layer-(" + setup.shadowImage[V.position === "doggy" ? "doggy" : "missionary"].join("|") + ")( |$)", 'i')))
 		.clone(true).removeClass((i, n) => (n.match(/(^|\s)(colour|layer)-\S+/g) || []).join(' '))
 		.addClass(targetClass).removeAttr('style').appendTo($(mainDiv).last());
 	});
 }
+window.combatCharacterShadow = combatCharacterShadow;
 
-window.painToTearsLvl = function(pain) {
+function painToTearsLvl(pain) {
 	/**
 	 * For usage with tears calculation, converts pain stat [0..200] to 0..4 range (maxes out at pain = 80)
 	 */
 	pain ??= V.pain;
 	return Math.floor(Math.clamp(pain, 0, 99) / 20);
 }
+window.painToTearsLvl = painToTearsLvl;
 
-window.mascaraNameToCSS = function(name) {
-	return setup.colours.mascara.find(x => x.variable == name)?.csstext;
+function mascaraNameToCSS(name) {
+	return setup.colours.mascara.find(x => x.variable === name)?.csstext;
 }
+window.mascaraNameToCSS = mascaraNameToCSS;
diff --git a/game/03-JavaScript/save.js b/game/03-JavaScript/save.js
index 325e6c63bc..43c3566a28 100644
--- a/game/03-JavaScript/save.js
+++ b/game/03-JavaScript/save.js
@@ -35,9 +35,7 @@ const DoLSave = ((Story, Save) => {
 
 	function parseVersion(version) {
 		version = marshalVersion(version);
-		return version
-			? version[0] * 1000000 + version[1] * 10000 + version[2] * 100 + version[3] * 1
-			: 0;
+		return version ? version[0] * 1000000 + version[1] * 10000 + version[2] * 100 + version[3] * 1 : 0;
 	}
 
 	/**
@@ -81,15 +79,9 @@ const DoLSave = ((Story, Save) => {
 	 * @returns {void}
 	 */
 	function load(slot, saveObj, overrides) {
-		const save =
-			saveObj == null
-				? slot === "auto"
-					? Save.autosave.get()
-					: Save.slots.get(slot)
-				: saveObj;
+		const save = saveObj == null ? (slot === "auto" ? Save.autosave.get() : Save.slots.get(slot)) : saveObj;
 		const saveDetails = JSON.parse(localStorage.getItem(KEY_DETAILS));
-		const metadata =
-			slot === "auto" ? saveDetails.autosave.metadata : saveDetails.slots[slot].metadata;
+		const metadata = slot === "auto" ? saveDetails.autosave.metadata : saveDetails.slots[slot].metadata;
 		/* Check if metadata for save matches the save's computed md5 hash. If it matches, the ironman save was not tampered with.
 			Bypass this check if on a mobile, because they are notoriously difficult to grab saves from in the event of issues. */
 		if (metadata.ironman && !Browser.isMobile.any()) {
@@ -122,10 +114,7 @@ const DoLSave = ((Story, Save) => {
 	function save(saveSlot, confirm, saveId, saveName) {
 		if (saveId == null) {
 			Wikifier.wikifyEval(`<<saveConfirm ${saveSlot}>>`);
-		} else if (
-			(V.confirmSave === true && confirm !== true) ||
-			(V.saveId !== saveId && saveId != null)
-		) {
+		} else if ((V.confirmSave === true && confirm !== true) || (V.saveId !== saveId && saveId != null)) {
 			Wikifier.wikifyEval(`<<saveConfirm ${saveSlot}>>`);
 		} else {
 			if (saveSlot != null) {
@@ -144,6 +133,7 @@ const DoLSave = ((Story, Save) => {
 						signature: V.ironmanmode ? IronMan.getSignature(save) : false,
 					});
 					V.currentOverlay = null;
+					// todo: find a better solution
 					closeOverlay();
 					if (V.ironmanmode === true) Engine.restart();
 				}
@@ -406,9 +396,7 @@ window.copySavedata = function (id) {
 window.updateExportDay = function () {
 	if (V.saveDetails != null && State.history[0].variables.saveDetails != null) {
 		V.saveDetails.exported.days = clone(V.days);
-		State.history[0].variables.saveDetails.exported.days = clone(
-			State.history[0].variables.days
-		);
+		State.history[0].variables.saveDetails.exported.days = clone(State.history[0].variables.days);
 		V.saveDetails.exported.count++;
 		State.history[0].variables.saveDetails.exported.count++;
 		V.saveDetails.exported.dayCount++;
@@ -481,16 +469,8 @@ const importSettingsData = function (data) {
 				if (namedObjects.includes(listKey[i]) && S.starting[listKey[i]] != null) {
 					const itemKey = Object.keys(listObject[listKey[i]]);
 					for (let j = 0; j < itemKey.length; j++) {
-						if (
-							V[listKey[i]][itemKey[j]] != null &&
-							S.starting[listKey[i]][itemKey[j]] != null
-						) {
-							if (
-								validateValue(
-									listObject[listKey[i]][itemKey[j]],
-									S.starting[listKey[i]][itemKey[j]]
-								)
-							) {
+						if (V[listKey[i]][itemKey[j]] != null && S.starting[listKey[i]][itemKey[j]] != null) {
+							if (validateValue(listObject[listKey[i]][itemKey[j]], S.starting[listKey[i]][itemKey[j]])) {
 								V[listKey[i]][itemKey[j]] = S.starting[listKey[i]][itemKey[j]];
 							}
 						}
@@ -525,16 +505,8 @@ const importSettingsData = function (data) {
 				if (namedObjects.includes(listKey[i]) && S.general[listKey[i]] != null) {
 					const itemKey = Object.keys(listObject[listKey[i]]);
 					for (let j = 0; j < itemKey.length; j++) {
-						if (
-							V[listKey[i]][itemKey[j]] != null &&
-							S.general[listKey[i]][itemKey[j]] != null
-						) {
-							if (
-								validateValue(
-									listObject[listKey[i]][itemKey[j]],
-									S.general[listKey[i]][itemKey[j]]
-								)
-							) {
+						if (V[listKey[i]][itemKey[j]] != null && S.general[listKey[i]][itemKey[j]] != null) {
+							if (validateValue(listObject[listKey[i]][itemKey[j]], S.general[listKey[i]][itemKey[j]])) {
 								V[listKey[i]][itemKey[j]] = S.general[listKey[i]][itemKey[j]];
 							}
 						}
@@ -565,12 +537,7 @@ const importSettingsData = function (data) {
 							S.npc[V.NPCNameList[i]][listKey[j]] === "none"
 						) {
 							V.NPCName[i][listKey[j]] = S.npc[V.NPCNameList[i]][listKey[j]];
-						} else if (
-							validateValue(
-								listObject[listKey[j]],
-								S.npc[V.NPCNameList[i]][listKey[j]]
-							)
-						) {
+						} else if (validateValue(listObject[listKey[j]], S.npc[V.NPCNameList[i]][listKey[j]])) {
 							V.NPCName[i][listKey[j]] = S.npc[V.NPCNameList[i]][listKey[j]];
 						}
 					}
@@ -643,12 +610,7 @@ function exportSettings(data, type) {
 				const itemKey = Object.keys(listObject[listKey[i]]);
 				for (let j = 0; j < itemKey.length; j++) {
 					if (V[listKey[i]][itemKey[j]] != null) {
-						if (
-							validateValue(
-								listObject[listKey[i]][itemKey[j]],
-								V[listKey[i]][itemKey[j]]
-							)
-						) {
+						if (validateValue(listObject[listKey[i]][itemKey[j]], V[listKey[i]][itemKey[j]])) {
 							S.starting[listKey[i]][itemKey[j]] = V[listKey[i]][itemKey[j]];
 						}
 					}
@@ -672,9 +634,7 @@ function exportSettings(data, type) {
 			const itemKey = Object.keys(listObject[listKey[i]]);
 			for (let j = 0; j < itemKey.length; j++) {
 				if (V[listKey[i]][itemKey[j]] != null) {
-					if (
-						validateValue(listObject[listKey[i]][itemKey[j]], V[listKey[i]][itemKey[j]])
-					) {
+					if (validateValue(listObject[listKey[i]][itemKey[j]], V[listKey[i]][itemKey[j]])) {
 						S.general[listKey[i]][itemKey[j]] = V[listKey[i]][itemKey[j]];
 					}
 				}
@@ -693,11 +653,7 @@ function exportSettings(data, type) {
 		S.npc[V.NPCNameList[i]] = {};
 		for (let j = 0; j < listKey.length; j++) {
 			// Overwrite to allow for "none" default value in the start passage to allow for rng to decide
-			if (
-				V.passage === "Start" &&
-				["pronoun", "gender"].includes(listKey[i]) &&
-				V.NPCName[i][listKey[j]] === "none"
-			) {
+			if (V.passage === "Start" && ["pronoun", "gender"].includes(listKey[i]) && V.NPCName[i][listKey[j]] === "none") {
 				S.npc[V.NPCNameList[i]][listKey[j]] = V.NPCName[i][listKey[j]];
 			} else if (validateValue(listObject[listKey[j]], V.NPCName[i][listKey[j]])) {
 				S.npc[V.NPCNameList[i]][listKey[j]] = V.NPCName[i][listKey[j]];
@@ -802,16 +758,7 @@ function settingsObjects(type) {
 				},
 				skinColor: {
 					natural: {
-						strings: [
-							"light",
-							"medium",
-							"dark",
-							"gyaru",
-							"ylight",
-							"ymedium",
-							"ydark",
-							"ygyaru",
-						],
+						strings: ["light", "medium", "dark", "gyaru", "ylight", "ymedium", "ydark", "ygyaru"],
 						randomize: "characterAppearance",
 					},
 					range: { min: 0, max: 100, decimals: 0, randomize: "characterAppearance" },
@@ -906,7 +853,7 @@ function settingsObjects(type) {
 				reducedLineHeight: { bool: true },
 				multipleWardrobes: { strings: [false, "isolated"] }, //, "all"
 				outfitEditorPerPage: { min: 5, max: 20, decimals: 0 }, //, "all"
-				options:{
+				options: {
 					neverNudeMenus: { bool: true },
 					showCaptionText: { bool: true },
 					sidebarStats: { strings: ["disabled", "limited", "all"] },
@@ -935,7 +882,7 @@ function settingsObjects(type) {
 					maxStates: { min: 1, max: 20, decimals: 0 },
 					newWardrobeStyle: { bool: true },
 					useNarrowMarket: { bool: true },
-					skipStatisticsConfirmation:{ bool: true },
+					skipStatisticsConfirmation: { bool: true },
 				},
 				shopDefaults: {
 					alwaysBackToShopButton: { bool: true },
@@ -1078,14 +1025,9 @@ window.randomizeSettings = function (filter) {
 		Object.entries(settingsObject).forEach(setting => {
 			if (settingContainers.includes(setting[0])) {
 				randomizeSettingLoop(setting[1], mainObject, setting[0]);
-			} else if (
-				(!filter && setting[1].randomize) ||
-				(filter && filter === setting[1].randomize)
-			) {
+			} else if ((!filter && setting[1].randomize) || (filter && filter === setting[1].randomize)) {
 				if (subObject) {
-					settingsResult[mainObject][subObject][setting[0]] = randomizeSettingSet(
-						setting[1]
-					);
+					settingsResult[mainObject][subObject][setting[0]] = randomizeSettingSet(setting[1]);
 				} else {
 					settingsResult[mainObject][setting[0]] = randomizeSettingSet(setting[1]);
 				}
diff --git a/game/04-Variables/variables-passageHeader.twee b/game/04-Variables/variables-passageHeader.twee
index 9f8daf1298..3ddfc4d408 100644
--- a/game/04-Variables/variables-passageHeader.twee
+++ b/game/04-Variables/variables-passageHeader.twee
@@ -33,7 +33,6 @@
 		<<updatehistorycontrols>>
 		<<set _preventUpdate to true>> /*prevent rewriting autosaves */
 		<<if $reducedLineHeight is true>><<addclass "#passages" "reducedLineHeight">><</if>>
-		<<run zoom($zoom, true)>> <!-- Pass the save's $zoom into the set zoom func, with second arg true, to either correct it to 100, or between 50 and 200. (Sanitisation) -->
 		<<run syncFavourites()>>
 		<<run initCustomLenses()>>	/* push custom eyelenses inside setup.colours.eyes; on every load/refresh it needs to be done. */
 		<<run syncDebugAddedEvents()>>
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index 2905f2c015..3080e1c906 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -1520,10 +1520,6 @@
 
 <<setupDefaults>>
 
-<<if $zoom is undefined>>
-	<<set $zoom to 100>>
-<</if>>
-
 <<if $bodywritingImages is undefined>>
 	<<set $bodywritingImages to true>>
 <</if>>
diff --git a/game/base-system/caption.twee b/game/base-system/caption.twee
index 69ba6ef0d8..8c965cb872 100644
--- a/game/base-system/caption.twee
+++ b/game/base-system/caption.twee
@@ -32,24 +32,39 @@
 	<div id="storyCaptionContent">
 		<<if $options.numpad is true>>
 			<style>
+				.mob-btn-group{
+					position: fixed;
+					top: 100px;
+					right: 0;
+					display: flex;
+					align-items: end;
+					flex-direction: column;
+					cursor: pointer;
+					color: #fff;
+				}
 				.mob-btn-group>div{
-				padding: 10px;background-color: rgb(34, 34, 34);color: #fff;border: 1px solid rgb(68, 68, 68);border-radius: 5px 0 0;
+					padding: 10px;
+					background-color: var(--850);
+					border: 1px solid var(--750);
+					border-radius: 5px 0 0 5px;
+				}
+				.mob-btn-group>div:hover{
+					background-color: var(--800);
 				}
-				.mob-btn-group>div:hover{background-color: rgb(51, 51, 51);}
 			</style>
-			<div class="mob-btn-group unstowable" style="position: fixed;top: 100px;right: 0;display: flex; align-items: center;flex-direction: column;cursor:pointer;">
+			<div class="mob-btn-group unstowable">
 				<div class="mob-btn-h" onclick="mobBtnShow()" style="display:none;"></div>
 				<div class="mob-btn" onclick="mobBtnHide()"></div>
-				<div class="mob-btn" onclick="mobclick(1)">1</div>
-				<div class="mob-btn" onclick="mobclick(2)">2</div>
-				<div class="mob-btn" onclick="mobclick(3)">3</div>
-				<div class="mob-btn" onclick="mobclick(4)">4</div>
-				<div class="mob-btn" onclick="mobclick(5)">5</div>
-				<div class="mob-btn" onclick="mobclick(6)">6</div>
-				<div class="mob-btn" onclick="mobclick(7)">7</div>
-				<div class="mob-btn" onclick="mobclick(8)">8</div>
-				<div class="mob-btn" onclick="mobclick(9)">9</div>
-				<div class="mob-btn" onclick="mobclick(10)">0</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 1 ? ' red' : '')" onclick="mobClick(1)">1</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 2 ? ' link-disabled' : '')" onclick="mobClick(2)">2</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 3 ? ' link-disabled' : '')" onclick="mobClick(3)">3</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 4 ? ' link-disabled' : '')" onclick="mobClick(4)">4</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 5 ? ' link-disabled' : '')" onclick="mobClick(5)">5</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 6 ? ' link-disabled' : '')" onclick="mobClick(6)">6</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 7 ? ' link-disabled' : '')" onclick="mobClick(7)">7</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 8 ? ' link-disabled' : '')" onclick="mobClick(8)">8</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 9 ? ' link-disabled' : '')" onclick="mobClick(9)">9</div>
+				<div @class="'mob-btn' + (Links.currentLinks.length < 10 ? ' link-disabled' : '')" onclick="mobClick(10)">0</div>
 			</div>
 		<</if>>
 		<<if $endeventerror isnot undefined>>
diff --git a/game/base-system/overlays/featsUI.twee b/game/base-system/overlays/featsUI.twee
index 0d014d7419..d085ea2049 100644
--- a/game/base-system/overlays/featsUI.twee
+++ b/game/base-system/overlays/featsUI.twee
@@ -31,7 +31,7 @@ You currently have <<if $feats.allSaves.point is undefined>><<print $feats.allSa
 <br><br>
 <<set $feats.filter to "General">>
 Filter by:
-<select id="featTypes" name="featTypes" onchange="V.feats.filter = this.value; filterFeats()">
+<select id="featTypes" name="featTypes" onchange="V.feats.filter = this.value; Wikifier.wikifyEval('<<replace #featsList>><<featsList>><</replace>>')">
 	<option value="General" selected>General</option>
 	<option value="Stats">Stats</option>
 	<option value="Social">Social</option>
diff --git a/game/base-system/settings.twee b/game/base-system/settings.twee
index 4703533691..a45a0e82b1 100644
--- a/game/base-system/settings.twee
+++ b/game/base-system/settings.twee
@@ -68,7 +68,6 @@
 <<set $facesitdisable to "f">>
 <<set $timestyle to "military">>
 <<set $saveName to "">>
-<<set $zoom to 100>>
 <<set $checkstyle to "words">>
 <<set $blackwolfmonster to 1>>
 <<set $greathawkmonster to 1>>
@@ -289,11 +288,13 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<<if $player.freckles is "random">>
 		<<set $player.freckles to (random(1, 5) is 1)>>
 	<</if>>
+	/* this never worked as intended
 	<!-- check if specified face style is installed -->
 	<img id="testImage" class="hidden" @scr="'img/face/' + $facestyle + '/base.png'">
 	<<if $facestyle is "" or isImageOk("#testImage")>>
 		<<set $facestyle = "default">>
 	<</if>>
+	*/
 	<!-- Init shop mannequin gender -->
 	<<if $mannequinHasPenis is undefined>>
 		<<set $mannequinHasPenis to $player.penisExist>>
@@ -1245,20 +1246,6 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<<textbox "$saveName" $saveName>>
 	<div class="description">Shows in the save menu in place of the save id.</div>
 	<div class="description"><span class="red">Only 10 characters at most will show in the save menu, leave empty to show the save ID.</span></div>
-	<br>
-	<span class="gold">Game Zoom</span> <mouse class="tooltip linkBlue">(?)<span>Will allow you to adjust the size of game elements and text. 100 is the default value.
-	A value of 50 will zoom the page out to half of its original size, while a value of 200 will zoom the page in to double its size.
-	The test button will not save the zoom value into the current save.
-	<span class="red">
-		Please be careful with this setting! Only save if you are happy with the changes made, as reloading the game will reset it to the last value used in that save.
-		Depending on the device and browser, the setting may break entirely, and may cause unexpected effects. Please report these issues as necessary.
-	</span></span></mouse>
-	<br><br>
-	<<numberslider "$zoom" $zoom 50 200 1>>
-	<input type="button" value="Set Zoom Test" onclick="zoom()"/>
-	<br><br>
-	<input type="button" value="Reset Zoom" onclick="zoom(100, true)"/>
-	<input type="button" value="Set Zoom" onclick="zoom(undefined, true)"/>
 	<br><br>
 
 	<span class="gold">Cheats menu</span>
diff --git a/game/base-system/widgets.js b/game/base-system/widgets.js
index 51ef0e2a54..80e1b34e5d 100644
--- a/game/base-system/widgets.js
+++ b/game/base-system/widgets.js
@@ -1,3 +1,4 @@
+/* eslint-disable jsdoc/require-description-complete-sentence */
 function setfemininitymultiplierfromgender(gender) {
 	if (gender === "f") {
 		T.femininity_multiplier = 1;
@@ -9,60 +10,64 @@ function setfemininitymultiplierfromgender(gender) {
 }
 DefineMacro("setfemininitymultiplierfromgender", setfemininitymultiplierfromgender);
 
-function addfemininityfromfactor(femininity_boost, factor_description, no_overwear_check) {
-	if (no_overwear_check) {
+function addfemininityfromfactor(femininityBoost, factorDescription, noOverwearCheck) {
+	if (noOverwearCheck) {
 		T.gender_appearance_factors_noow.push({
-			femininity: femininity_boost,
-			factor: factor_description
+			femininity: femininityBoost,
+			factor: factorDescription,
 		});
-		T.apparent_femininity_noow += femininity_boost;
+		T.apparent_femininity_noow += femininityBoost;
 	} else {
-		T.apparent_femininity += femininity_boost;
+		T.apparent_femininity += femininityBoost;
 		T.gender_appearance_factors.push({
-			femininity: femininity_boost,
-			factor: factor_description
+			femininity: femininityBoost,
+			factor: factorDescription,
 		});
 	}
 }
 DefineMacro("addfemininityfromfactor", addfemininityfromfactor);
 
-function addfemininityofclothingarticle(slot, clothing_article, no_overwear_check) {
-	if (setup.clothes[slot][clothesIndex(slot,clothing_article)].femininity) {
-		addfemininityfromfactor(setup.clothes[slot][clothesIndex(slot,clothing_article)].femininity, setup.clothes[slot][clothesIndex(slot,clothing_article)].name_cap, no_overwear_check);
+function addfemininityofclothingarticle(slot, clothingArticle, noOverwearCheck) {
+	if (setup.clothes[slot][clothesIndex(slot, clothingArticle)].femininity) {
+		addfemininityfromfactor(
+			setup.clothes[slot][clothesIndex(slot, clothingArticle)].femininity,
+			setup.clothes[slot][clothesIndex(slot, clothingArticle)].name_cap,
+			noOverwearCheck
+		);
 	}
 }
 DefineMacro("addfemininityofclothingarticle", addfemininityofclothingarticle);
 
 const hairStyleCap = {
-	hairtype:{
-		"flat ponytail":300,
-		"messy":200,
-		"pigtails":300,
-		"ponytail":300,
-		"short":100,
+	hairtype: {
+		"flat ponytail": 300,
+		messy: 200,
+		pigtails: 300,
+		ponytail: 300,
+		short: 100,
 	},
-	fringetype:{
-		"default":100,
-		"thin flaps":300,
-		"wide flaps":300,
-		"hime":300,
-		"loose":300,
-		"messy":200,
-		"overgrown":200,
-		"ringlets":300,
-		"split":300,
-		"straight":300,
-		"swept left":200,
-		"back":100,
-		"parted":100,
-		"flat":100,
-		"quiff":100,
-		"straight curl":200,
-		"ringlet curl":300,
-		"curtain":200,
-		"trident":200,
-	}
-}
+	fringetype: {
+		default: 100,
+		"thin flaps": 300,
+		"wide flaps": 300,
+		hime: 300,
+		loose: 300,
+		messy: 200,
+		overgrown: 200,
+		ringlets: 300,
+		split: 300,
+		straight: 300,
+		"swept left": 200,
+		back: 100,
+		parted: 100,
+		flat: 100,
+		quiff: 100,
+		"straight curl": 200,
+		"ringlet curl": 300,
+		curtain: 200,
+		trident: 200,
+	},
+};
 
 /** Calculate the player's gender appearance */
 function genderappearancecheck() {
@@ -85,8 +90,14 @@ function genderappearancecheck() {
 		T.bulge_size = Math.clamp(V.player.penissize * T.erection_state, 0, Infinity);
 	}
 	/* Determine how visible the player's bottom is */
-	if ((setup.clothes.lower[clothesIndex('lower',V.worn.lower)].skirt === 1 && V.worn.lower.skirt_down === 1 && V.worn.lower.state === "waist") ||
-		(setup.clothes.over_lower[clothesIndex('over_lower',V.worn.over_lower)].skirt === 1 && V.worn.over_lower.skirt_down === 1 && V.worn.over_lower.state === "waist")) {
+	if (
+		(setup.clothes.lower[clothesIndex("lower", V.worn.lower)].skirt === 1 &&
+			V.worn.lower.skirt_down === 1 &&
+			V.worn.lower.state === "waist") ||
+		(setup.clothes.over_lower[clothesIndex("over_lower", V.worn.over_lower)].skirt === 1 &&
+			V.worn.over_lower.skirt_down === 1 &&
+			V.worn.over_lower.state === "waist")
+	) {
 		T.bottom_visibility = 0;
 	} else {
 		T.bottom_visibility = 1;
@@ -96,36 +107,36 @@ function genderappearancecheck() {
 	T.apparent_femininity = 0;
 	T.breast_indicator = 0;
 	/* Head clothing */
-	addfemininityofclothingarticle('over_head',V.worn.over_head);
-	addfemininityofclothingarticle('head',V.worn.head);
+	addfemininityofclothingarticle("over_head", V.worn.over_head);
+	addfemininityofclothingarticle("head", V.worn.head);
 	/* Always visible clothing */
-	addfemininityofclothingarticle('face',V.worn.face);
-	addfemininityofclothingarticle('neck',V.worn.neck);
-	addfemininityofclothingarticle('legs',V.worn.legs);
-	addfemininityofclothingarticle('feet',V.worn.feet);
+	addfemininityofclothingarticle("face", V.worn.face);
+	addfemininityofclothingarticle("neck", V.worn.neck);
+	addfemininityofclothingarticle("legs", V.worn.legs);
+	addfemininityofclothingarticle("feet", V.worn.feet);
 	/* Hair length */
 	if (V.worn.over_head.hood !== 1 && V.worn.head.hood !== 1) {
 		let lengthCap;
 		/* Set Hair Style cap */
-		if(hairStyleCap.hairtype[V.hairtype] && hairStyleCap.fringetype[V.fringetype]){
-			lengthCap = Math.max(hairStyleCap.hairtype[V.hairtype],hairStyleCap.fringetype[V.fringetype]);
+		if (hairStyleCap.hairtype[V.hairtype] && hairStyleCap.fringetype[V.fringetype]) {
+			lengthCap = Math.max(hairStyleCap.hairtype[V.hairtype], hairStyleCap.fringetype[V.fringetype]);
 		}
-		let femininityfactor = Math.trunc((V.hairlength - 200) / 2);
-		if(lengthCap && femininityfactor >= lengthCap){
+		const femininityfactor = Math.trunc((V.hairlength - 200) / 2);
+		if (lengthCap && femininityfactor >= lengthCap) {
 			addfemininityfromfactor(lengthCap, "Hair length (capped due to hair style)");
 		} else {
 			addfemininityfromfactor(femininityfactor, "Hair length");
 		}
 	}
 	/* Makeup */
-	addfemininityfromfactor(V.makeup.lipstick == 0 ? 0 : 50, "Lipstick");
-	addfemininityfromfactor(V.makeup.eyeshadow == 0 ? 0 : 50, "Eye shadow");
-	addfemininityfromfactor(V.makeup.mascara == 0 ? 0 : 50, "Mascara");
+	addfemininityfromfactor(V.makeup.lipstick ? 50 : 0, "Lipstick");
+	addfemininityfromfactor(V.makeup.eyeshadow ? 50 : 0, "Eye shadow");
+	addfemininityfromfactor(V.makeup.mascara ? 50 : 0, "Mascara");
 	/* Body structure */
-	addfemininityfromfactor(Math.trunc(V.player.bottomsize * T.bottom_visibility * 50), "Bottom size (" + Math.trunc(T.bottom_visibility * 100) + "% visible)");
+	addfemininityfromfactor(Math.trunc(V.player.bottomsize * T.bottom_visibility * 50),	"Bottom size (" + Math.trunc(T.bottom_visibility * 100) + "% visible)");
 	setfemininitymultiplierfromgender(V.player.gender_body);
 	addfemininityfromfactor(T.femininity_multiplier * 200, "Natural features");
-	addfemininityfromfactor(Math.trunc((-1 * (V.physique + V.physiquesize / 2) / V.physiquesize) * 100), "Toned muscles");
+	addfemininityfromfactor(Math.trunc((V.physique + V.physiquesize / 2) / V.physiquesize * -100), "Toned muscles");
 	/* Behaviour */
 	setfemininitymultiplierfromgender(V.player.gender_posture);
 	T.acting_multiplier = V.englishtrait + 1;
@@ -136,49 +147,49 @@ function genderappearancecheck() {
 	T.under_lower_protected = !V.worn.under_lower.exposed;
 	T.apparent_femininity_noow = T.apparent_femininity;
 	T.gender_appearance_factors_noow = clone(T.gender_appearance_factors);
-	T.over_lower_femininity = (setup.clothes.over_lower[clothesIndex('over_lower',V.worn.over_lower)].femininity ? setup.clothes.over_lower[clothesIndex('over_lower',V.worn.over_lower)].femininity : 0);
-	T.lower_femininity = (setup.clothes.lower[clothesIndex('lower',V.worn.lower)].femininity ? setup.clothes.lower[clothesIndex('lower',V.worn.lower)].femininity : 0);
-	T.under_lower_femininity = (setup.clothes.under_lower[clothesIndex('under_lower',V.worn.under_lower)].femininity ? setup.clothes.under_lower[clothesIndex('under_lower',V.worn.under_lower)].femininity : 0);;
+	T.over_lower_femininity = setup.clothes.over_lower[clothesIndex("over_lower", V.worn.over_lower)].femininity ? setup.clothes.over_lower[clothesIndex("over_lower", V.worn.over_lower)].femininity : 0; 
+	T.lower_femininity = setup.clothes.lower[clothesIndex("lower", V.worn.lower)].femininity ? setup.clothes.lower[clothesIndex("lower", V.worn.lower)].femininity : 0;
+	T.under_lower_femininity = setup.clothes.under_lower[clothesIndex("under_lower", V.worn.under_lower)].femininity ? setup.clothes.under_lower[clothesIndex("under_lower", V.worn.under_lower)].femininity : 0;
 	/* find maximum possible femininity of the last lower piece you can strip down to, and add it to the counter */
 	addfemininityfromfactor(Math.max(T.over_lower_femininity, T.lower_femininity, T.under_lower_femininity), "Lower clothes", "noow");
 	/* bulge and genitals checks for topless gender */
 	if (T.under_lower_protected && V.NudeGenderDC > 0) {
-		addfemininityfromfactor(-T.bulge_size * 100, "Bulge visible through underwear", "noow");
+		addfemininityfromfactor(T.bulge_size * -100, "Bulge visible through underwear", "noow");
 	} else if ((T.over_lower_protected || T.lower_protected) && V.NudeGenderDC > 0) {
-		addfemininityfromfactor(-Math.clamp((T.bulge_size - 3) * 100, 0, Infinity), "Bulge visible through clothing", "noow");
-	} else if (V.worn.genitals.exposed && V.NudeGenderDC == 1) {
+		addfemininityfromfactor(Math.clamp((T.bulge_size - 3) * -100, 0, Infinity), "Bulge visible through clothing", "noow");
+	} else if (V.worn.genitals.exposed && V.NudeGenderDC === 1) {
 		if (V.player.penisExist) {
-			addfemininityfromfactor((-V.player.penissize-2.5) * 150, "Penis exposed", "noow");
+			addfemininityfromfactor((V.player.penissize + 2.5) * -150, "Penis exposed", "noow");
 		}
 		if (V.player.vaginaExist) {
 			addfemininityfromfactor(450, "Vagina exposed", "noow");
 		}
-	} else if (V.worn.genitals.exposed && V.NudeGenderDC == 2) {
+	} else if (V.worn.genitals.exposed && V.NudeGenderDC === 2) {
 		addfemininityfromfactor(V.player.vaginaExist * 100000 - V.player.penisExist * 100000, "Genitals exposed", "noow");
 	}
 	/* plain breasts factor */
 	addfemininityfromfactor((V.player.breastsize - 0.5) * 100, "Exposed breasts", "noow");
 	/* Lower clothing, bulge, and genitals */
-	addfemininityofclothingarticle('over_lower',V.worn.over_lower);
+	addfemininityofclothingarticle("over_lower", V.worn.over_lower);
 	if (!T.over_lower_protected) {
-		addfemininityofclothingarticle('lower',V.worn.lower);
+		addfemininityofclothingarticle("lower", V.worn.lower);
 	}
 	if (!T.over_lower_protected && !T.lower_protected) {
 		/* Lower underwear is visible */
-		addfemininityofclothingarticle('under_lower',V.worn.under_lower);
+		addfemininityofclothingarticle("under_lower", V.worn.under_lower);
 		if (!T.under_lower_protected) {
 			/* Genitals slot is visible */
-			addfemininityofclothingarticle('genitals',V.worn.genitals);
+			addfemininityofclothingarticle("genitals", V.worn.genitals);
 			if (V.worn.genitals.exposed) {
 				/* Bare genitals are visible */
-				if (V.NudeGenderDC == 1) {
+				if (V.NudeGenderDC === 1) {
 					if (V.player.penisExist) {
-						addfemininityfromfactor((-V.player.penissize-2.5) * 150, "Penis visible");
+						addfemininityfromfactor((-V.player.penissize - 2.5) * 150, "Penis visible");
 					}
 					if (V.player.vaginaExist) {
 						addfemininityfromfactor(450, "Vagina visible");
 					}
-				} else if (V.NudeGenderDC == 2) {
+				} else if (V.NudeGenderDC === 2) {
 					if (V.player.penisExist) {
 						addfemininityfromfactor(-100000, "Penis visible");
 					}
@@ -204,57 +215,50 @@ function genderappearancecheck() {
 		}
 	}
 	/* Upper clothing and breasts */
-	addfemininityofclothingarticle('over_upper',V.worn.over_upper);
+	addfemininityofclothingarticle("over_upper", V.worn.over_upper);
 	if (V.worn.over_upper.exposed >= 2) {
-		addfemininityofclothingarticle('upper',V.worn.upper);
+		addfemininityofclothingarticle("upper", V.worn.upper);
 	}
 	if (V.worn.over_upper.exposed >= 2 && V.worn.upper.exposed >= 2) {
 		/* Upper underwear is visible */
-		addfemininityofclothingarticle('under_upper',V.worn.under_upper);
+		addfemininityofclothingarticle("under_upper", V.worn.under_upper);
 		if (V.worn.under_upper.exposed >= 1) {
 			/* Exposed breasts */
 			T.breast_indicator = 1;
 			addfemininityfromfactor((V.player.breastsize - 0.5) * 100, "Exposed breasts");
 		} else if (!V.worn.under_upper.type.includes("chest_bind")) {
 			/* Breasts covered by only underwear */
-			addfemininityfromfactor(Math.clamp(
-				(V.player.breastsize - 2) * 100, 0, Infinity
-			), "Breast size visible through underwear");
+			addfemininityfromfactor(Math.clamp((V.player.breastsize - 2) * 100, 0, Infinity), "Breast size visible through underwear");
 		}
 	} else if (!V.worn.under_upper.type.includes("chest_bind")) {
 		/* Breast fully covered */
-		addfemininityfromfactor(Math.clamp(
-			(V.player.breastsize - 4) * 100, 0, Infinity
-		), "Breast size visible through clothing");
+		addfemininityfromfactor(Math.clamp((V.player.breastsize - 4) * 100, 0, Infinity), "Breast size visible through clothing");
 	}
 	/* Pregnant Belly */
 	if (V.sexStats === undefined) {
-	}else if (V.sexStats.vagina.pregnancy.bellySize >= 8) {
-		addfemininityfromfactor(Math.clamp(
-			100000, 0, Infinity
-		), "Pregnant Belly");
-	}else if (V.sexStats.vagina.pregnancy.bellySize >= 5) {
-		addfemininityfromfactor(Math.clamp(
-			(V.sexStats.vagina.pregnancy.bellySize - 4) * 500, 0, Infinity
-		), "Pregnant Belly");
+		// do glorious nothing
+	} else if (V.sexStats.vagina.pregnancy.bellySize >= 8) {
+		addfemininityfromfactor(Math.clamp(100000, 0, Infinity), "Pregnant Belly");
+	} else if (V.sexStats.vagina.pregnancy.bellySize >= 5) {
+		addfemininityfromfactor(Math.clamp((V.sexStats.vagina.pregnancy.bellySize - 4) * 500, 0, Infinity), "Pregnant Belly");
 	}
 	/* Body writing */
 	Wikifier.wikifyEval("<<bodywriting_exposure_check>>"); // TODO convert to JS when possible
 	T.skinValue = 0;
 	T.skinValue_noow = 0;
-	Object.keys(V.skin).forEach(label=>{
-		let value = V.skin[label];
+	Object.keys(V.skin).forEach(label => {
+		const value = V.skin[label];
 		if (T.skin_array.includes(label)) {
 			if (value.gender === "m") {
-				T.skinValue -= 50 * (value.pen !== "pen"?2:1);
+				T.skinValue -= 50 * (value.pen !== "pen" ? 2 : 1);
 			} else if (value.gender === "f") {
-				T.skinValue += 50 * (value.pen !== "pen"?2:1);
+				T.skinValue += 50 * (value.pen !== "pen" ? 2 : 1);
 			}
 		} else {
 			if (value.gender === "m") {
-				T.skinValue_noow -= 50 * (value.pen !== "pen"?2:1);
+				T.skinValue_noow -= 50 * (value.pen !== "pen" ? 2 : 1);
 			} else if (V.skin.breasts.gender === "f") {
-				T.skinValue_noow += 50 * (value.pen !== "pen"?2:1);
+				T.skinValue_noow += 50 * (value.pen !== "pen" ? 2 : 1);
 			}
 		}
 	});
@@ -264,7 +268,8 @@ function genderappearancecheck() {
 		T.gender_appearance = "f";
 	} else if (T.apparent_femininity < 0) {
 		T.gender_appearance = "m";
-	} else if (V.player.gender == "h") { // if herm pc and perfect 0 apparent_femininity
+	} else if (V.player.gender === "h") {
+		// if herm pc and perfect 0 apparent_femininity
 		T.gender_appearance = genderAppearanceHermTiebreak();
 	} else {
 		T.gender_appearance = V.player.gender;
@@ -273,7 +278,7 @@ function genderappearancecheck() {
 		T.gender_appearance_noow = "f";
 	} else if (T.apparent_femininity_noow < 0) {
 		T.gender_appearance_noow = "m";
-	} else if (V.player.gender == "h") {
+	} else if (V.player.gender === "h") {
 		T.gender_appearance_noow = genderAppearanceHermTiebreak();
 	} else {
 		T.gender_appearance_noow = V.player.gender;
@@ -295,24 +300,24 @@ function genderAppearanceHermTiebreak() {
 	}
 }
 
-function apparentbreastsizecheck(){
+function apparentbreastsizecheck() {
 	T.tempbreast = V.player.breastsize;
-	if ( clothingData('upper',V.worn.upper,'bustresize') != undefined ){ T.tempbreast += clothingData('upper',V.worn.upper,'bustresize') };
-	if ( clothingData('under_upper',V.worn.under_upper,'bustresize') != undefined ){ T.tempbreast += clothingData('under_upper',V.worn.under_upper,'bustresize') };
-	if ( clothingData('over_upper',V.worn.over_upper,'bustresize') != undefined){ T.tempbreast += clothingData('over_upper',V.worn.over_upper,'bustresize')  };
-	V.player.perceived_breastsize = Math.clamp( V.breastsizemin, T.tempbreast, V.breastsizemax );
+	if (clothingData("upper", V.worn.upper, "bustresize") != null) { T.tempbreast += clothingData("upper", V.worn.upper, "bustresize"); }
+	if (clothingData("under_upper", V.worn.under_upper, "bustresize") != null) { T.tempbreast += clothingData("under_upper", V.worn.under_upper, "bustresize"); }
+	if (clothingData("over_upper", V.worn.over_upper, "bustresize") != null) { T.tempbreast += clothingData("over_upper", V.worn.over_upper, "bustresize"); }
+	V.player.perceived_breastsize = Math.clamp(V.breastsizemin, T.tempbreast, V.breastsizemax);
 }
 
-function apparentbottomsizecheck(){
+function apparentbottomsizecheck() {
 	T.tempbutt = V.player.bottomsize;
-	if ( V.worn.lower.rearresize != undefined ){ T.tempbutt += V.worn.lower.rearresize };
-	if ( V.worn.under_lower.rearresize != undefined ){ T.tempbutt += V.worn.under_lower.rearresize };
-	if ( V.worn.lower.rearresize != undefined ){ T.tempbutt += V.worn.over_lower.rearresize };
-	V.player.perceived_bottomsize = Math.clamp( V.bottomsizemin, T.tempbutt, V.bottomsizemax );
+	if (V.worn.lower.rearresize != null) { T.tempbutt += V.worn.lower.rearresize }
+	if (V.worn.under_lower.rearresize != null) { T.tempbutt += V.worn.under_lower.rearresize }
+	if (V.worn.lower.rearresize != null) { T.tempbutt += V.worn.over_lower.rearresize }
+	V.player.perceived_bottomsize = Math.clamp(V.bottomsizemin, T.tempbutt, V.bottomsizemax);
 }
 
 function exposedcheck() {
-	if ( !V.combat || V.args[0] === true ){
+	if (!V.combat || V.args[0] === true) {
 		genderappearancecheck();
 		V.player.gender_appearance = T.gender_appearance;
 		T.gender_appearance_factors.sort((a, b) => a.femininity > b.femininity);
@@ -332,54 +337,13 @@ function exposedcheck() {
 }
 DefineMacro("exposedcheck", exposedcheck);
 
-function updatehistorycontrols(){
-	if (V.options.maxStates === undefined || V.options.maxStates > 20) {
-		/* initiate new variable based on engine config and limit it to 20 */
-		V.options.maxStates = Math.clamp(1, 20, Config.history.maxStates);
-	}
-	if (V.options.maxStates == 1) {
-		/* when disabled, irreversibly delete history controls the way sugarcube intended */
-		Config.history.maxStates = 1;
-		jQuery('#ui-bar-history').remove();
-	} else {
-		/* set actual maxStates in accordance with our new variable */
-		Config.history.maxStates = V.options.maxStates;
-		/* ensure that controls are enabled so sugarcube won't destroy them on reload */
-		Config.history.controls = true;
-		/* if irreversibly deleted, restore #ui-bar-history from oblivion and pop it after #ui-bar-toggle */
-		if (jQuery("#ui-bar-history").length == 0){
-			jQuery("#ui-bar-toggle").after(`
-				<div id="ui-bar-history">
-					<button id="history-backward" tabindex="0" title="'+t+'" aria-label="'+t+'">\uE821</button>
-					<button id="history-forward" tabindex="0" title="'+n+'" aria-label="'+n+'">\uE822</button>
-				</div>`);
-			/* make buttons active/inactive based on the available history states */
-			jQuery(document).on(':historyupdate.ui-bar', (($backward, $forward) => () => {
-					$backward.ariaDisabled(State.length < 2);
-					$forward.ariaDisabled(State.length === State.size);
-				})(jQuery('#history-backward'), jQuery('#history-forward')));
-			jQuery('#history-backward')
-				.ariaDisabled(State.length < 2)
-				.ariaClick({
-					label : L10n.get('uiBarBackward')
-				}, () => Engine.backward());
-			jQuery('#history-forward')
-				.ariaDisabled(State.length === State.size)
-				.ariaClick({
-					label : L10n.get('uiBarForward')
-				}, () => Engine.forward());
-		}
-		jQuery("#ui-bar-history").show();
-	}
-}
-DefineMacro("updatehistorycontrols", updatehistorycontrols);
-
-
-/** Jimmy: A potential improvement is to not wikify the hints that are appended to the ends of the links,
+/**
+ * Jimmy: A potential improvement is to not wikify the hints that are appended to the ends of the links,
  *         I chose to keep this format for now to keep <<promiscuous>>, <<exhibitionist>> and <<deviant>> centralised.
- * 		   If someone wants to change those widgets, this won't need updating. */
-Macro.add('reqSkill', {
-	tags: ['reqE', 'reqElse'],
+ * 		   If someone wants to change those widgets, this won't need updating.
+ */
+Macro.add("reqSkill", {
+	tags: ["reqE", "reqElse"],
 	reqs: [0, 1, 15, 35, 55, 75, 95],
 	handler() {
 		/* The function below (some) will immediately end and not iterate further if TRUE is returned, it will continue to iterate if FALSE is returned. */
@@ -387,7 +351,7 @@ Macro.add('reqSkill', {
 			if (section.args.length === 0) {
 				/* If <<reqSkill>> has no arguments, report an error.
 				   However, if <<reqElse>> had none, print out the section as normal, no need to add skill hints to the links. */
-				if (section.name === 'reqSkill') {
+				if (section.name === "reqSkill") {
 					Errors.inlineReport(`Missing arguments for <<${section.name}>>`, `${this.source}`).appendTo(this.output);
 				} else {
 					new Wikifier(this.output, section.contents);
@@ -407,18 +371,18 @@ Macro.add('reqSkill', {
 					return true;
 				}
 				switch (type) {
-					case 'promiscuity':
-					case 'p':
+					case "promiscuity":
+					case "p":
 						if (V.promiscuity < this.self.reqs[tier]) return true;
 						output += `<<promiscuous${tier}>>`;
 						return false;
-					case 'exhibitionism':
-					case 'e':
+					case "exhibitionism":
+					case "e":
 						if (V.exhibitionism < this.self.reqs[tier]) return true;
 						output += `<<exhibitionist${tier}>>`;
 						return false;
-					case 'deviancy':
-					case 'd':
+					case "deviancy":
+					case "d":
 						if (V.deviancy < this.self.reqs[tier]) return true;
 						output += `<<deviant${tier}>>`;
 						return false;
@@ -430,33 +394,30 @@ Macro.add('reqSkill', {
 			/* If cancel signals true, exit but continue next payloads. */
 			if (cancel) return false;
 			/* Final render, and insertion of elements.
-			   Renders the section defined within the block that was successful.*/
+			   Renders the section defined within the block that was successful. */
 			new Wikifier(this.output, section.contents);
 			/* Renders the HTML elements that are inserted after every link. */
 			const wikiOutput = new Wikifier(null, output);
 			/* Scan through macro outfit for valid links to append hints to. */
-			jQuery(this.output).children().filter('a.link-internal, a.link-external')
-				.after(wikiOutput.output);
+			jQuery(this.output).children().filter("a.link-internal, a.link-external").after(wikiOutput.output);
 			/* Successful render, no need to process anymore segments. */
 			return true;
 		});
-	}
+	},
 });
 
 /**
  * Turns an array into a formatted list for printing.
- * @param {any[]} arr - An Array, ie ["a","b","c","d"]
- * @param {String} conjunction ("and") - A conjunction for the formatted list
- * @param {Boolean} useOxfordComma (false) - A boolean deciding whether to prepend a separator before conjunction
- * @param {String} separator (", ") - A separator between elements of the formatted list
- * @returns {String} A formatted list, ie "a, b, c and d"
+ *
+ * @param {any[]} arr An Array, ie ["a","b","c","d"]
+ * @param {string} conjunction ("and") - A conjunction for the formatted list
+ * @param {boolean} useOxfordComma (false) - A boolean deciding whether to prepend a separator before conjunction
+ * @param {string} separator (", ") - A separator between elements of the formatted list
+ * @returns {string} A formatted list, ie "a, b, c and d"
  */
-function formatList(arr, conjunction = "and", useOxfordComma = false, separator=", ") {
+function formatList(arr, conjunction = "and", useOxfordComma = false, separator = ", ") {
 	if (!(Array.isArray(arr) && arr.length > 0)) {
-		Errors.report(
-			"Error in formatList: Missing or invalid array argument",
-			{"Stacktrace" : Utils.GetStack(), arguments}
-		);
+		Errors.report("Error in formatList: Missing or invalid array argument", { Stacktrace: Utils.GetStack(), arguments });
 		return "";
 	}
 	/*
@@ -465,7 +426,7 @@ function formatList(arr, conjunction = "and", useOxfordComma = false, separator=
 	const oxConj = (useOxfordComma ? separator : " ") + conjunction;
 	return arr.slice(0,-1).join(separator) + oxConj + arr.at(-1);
 	*/
-	return arr.formatList({conjunction, useOxfordComma, separator});
+	return arr.formatList({ conjunction, useOxfordComma, separator });
 }
 window.formatList = formatList;
 DefineMacroS("formatList", formatList);
diff --git a/game/overworld-town/loc-shop/clothing-v2.twee b/game/overworld-town/loc-shop/clothing-v2.twee
index f65f75762f..fc643a0849 100644
--- a/game/overworld-town/loc-shop/clothing-v2.twee
+++ b/game/overworld-town/loc-shop/clothing-v2.twee
@@ -774,7 +774,7 @@
 					<<capture _buttonName _args[0] _acc $clothingShopSlot>>
 						<<link "">>
 							<<if _buttonName == "random">>
-								<<set $customColors.color[_acc] to getRandomIntInclusive(0,360)>> /* 0,360 are min/max hue values, representing colours */
+								<<set $customColors.color[_acc] to random(0, 360)>> /* 0,360 are min/max hue values, representing colours */
 								<<run updateHueSlider($customColors.color[_acc], _acc)>>
 								<<set _colour = "custom">>
 							<<else>>
-- 
GitLab


From 9b128a36e0a2d3fd16a66767e915cf717cc463f9 Mon Sep 17 00:00:00 2001
From: oyea <23656-oyea@users.noreply.gitgud.io>
Date: Tue, 13 Sep 2022 20:37:28 +0000
Subject: [PATCH 34/50] Contributed scene and other things

---
 game/03-JavaScript/ingame.js                  |   6 +-
 game/base-combat/actions-hands.twee           | 232 ++++-
 game/base-combat/actions-mouth.twee           |   3 +
 game/base-combat/actionsGeneration.twee       |  19 +
 game/base-combat/effects.twee                 |  96 +-
 game/base-combat/end.twee                     |   2 +
 game/base-combat/man-combat.twee              |  39 +-
 game/base-system/bodywriting.twee             |  78 +-
 game/base-system/overlays/cheats.twee         |   4 +-
 game/base-system/promiscuity.twee             |   4 +-
 game/base-system/text.twee                    |   8 +-
 game/base-system/time.twee                    |   1 +
 game/overworld-forest/loc-asylum/widgets.twee |  10 +-
 game/overworld-town/loc-adultshop/events.twee |   5 +-
 game/overworld-town/loc-docks/main.twee       |   2 +-
 game/overworld-town/loc-docks/widgets.twee    |  22 +-
 game/overworld-town/loc-home/main.twee        |   2 +-
 game/overworld-town/loc-prison/wren.twee      |  35 +-
 game/overworld-town/loc-pub/main.twee         | 327 +++++--
 game/overworld-town/loc-shop/main.twee        |  16 +-
 game/overworld-town/special-avery/main.twee   |  15 +
 game/overworld-town/special-robin/main.twee   |   2 +-
 game/overworld-town/special-sydney/walk.twee  |   4 +-
 game/overworld-town/special-whitney/main.twee | 917 ++++++++++++++++--
 .../special-whitney/widgets.twee              |  54 ++
 25 files changed, 1667 insertions(+), 236 deletions(-)

diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index aee93ad674..21f47dbc1a 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -101,11 +101,11 @@ const combatActionColours = {
 	Default: {
 		brat: [
 			/* leftaction or rightaction */
-			"steal", "penwhack", "freeface", "leftcovervagina", "leftcoverpenis", "leftcoveranus", "rightcovervagina", "rightcoverpenis", "rightcoveranus", "leftunderpull", "leftskirtpull", "leftlowerpull", "leftupperpull", "rightunderpull", "rightskirtpull", "rightlowerpull", "rightupperpull", "rightUndressOther", "leftUndressOther", "stopchoke", "clench", "shacklewhack", "leftfold", "rightfold", "dildowhack", "hypnosiswhack", "leftstruggleweak", "rightstruggleweak", "leftresistW", "rightresistW", "leftstillW", "rightstillW",
+			"steal", "penwhack", "freeface", "leftcovervagina", "leftcoverpenis", "leftcoveranus", "rightcovervagina", "rightcoverpenis", "rightcoveranus", "leftunderpull", "leftskirtpull", "leftlowerpull", "leftupperpull", "rightunderpull", "rightskirtpull", "rightlowerpull", "rightupperpull", "rightUndressOther", "leftUndressOther", "stopchoke", "clench", "shacklewhack", "leftfold", "rightfold", "dildowhack", "hypnosiswhack", "leftstruggleweak", "rightstruggleweak", "handpullpenis", "handpullvagina", "handpullanus", "leftresistW", "rightresistW", "leftstillW", "rightstillW",
 			/* feetaction */
 			"run", "hide", "confront", "feetresistW",
 			/* mouthaction */
-			"pullaway", "pullawayvagina", "finish", "novaginal", "nopenile", "noanal", "scream", "mock", "breastclosed", "breastpull", "pullawaykiss", "noupper", "up", "stifleorgasm", "stifle", "mouthresistW", "handcloseW",
+			"pullaway", "pullawayvagina", "finish", "novaginal", "nopenile", "noanal", "scream", "mock", "breastclosed", "breastpull", "pullawaykiss", "noupper", "analpull", "up", "stifleorgasm", "stifle", "mouthresistW", "handcloseW",
 			/* penisaction */
 			"othermouthescape", "escape", "otheranusescape", "fencingescape",
 			/* vaginaaction */
@@ -135,7 +135,7 @@ const combatActionColours = {
 		],
 		sub: [
 			/* leftaction or rightaction */
-			"leftplay", "leftgrab", "leftstroke", "leftchest", "rightplay", "rightgrab", "rightstroke", "rightchest", "leftchest", "rightchest", "leftwork", "rightwork", "leftclit", "rightclit", "keepchoke", "leftmasturbatepussy", "rightmasturbatepussy", "leftmasturbatepenis", "rightmasturbatepenis", "lefthandholdkeep", "righthandholdkeep", "lefthandholdnew", "righthandholdnew", "lubeanus", "lubepussy", "lubepenis", "removebuttplug", "dildoOtherPussyTease", "dildoOtherPussyFuck", "dildoOtherAnusTease", "dildoOtherAnusFuck", "strokerOtherPenisTease", "strokerOtherPenisFuck", "dildoSelfPussyEntrance", "dildoSelfAnusEntrance", "dildoSelfPussy", "dildoSelfAnus", "strokerSelfPenisEntrance", "strokerSelfPenis",
+			"leftplay", "leftgrab", "leftstroke", "leftchest", "rightplay", "rightgrab", "rightstroke", "rightchest", "leftchest", "rightchest", "leftwork", "rightwork", "leftclit", "rightclit", "keepchoke", "leftmasturbatepussy", "rightmasturbatepussy", "leftmasturbatepenis", "rightmasturbatepenis", "lefthandholdkeep", "righthandholdkeep", "lefthandholdnew", "righthandholdnew", "handguide", "lubeanus", "lubepussy", "lubepenis", "removebuttplug", "dildoOtherPussyTease", "dildoOtherPussyFuck", "dildoOtherAnusTease", "dildoOtherAnusFuck", "strokerOtherPenisTease", "strokerOtherPenisFuck", "dildoSelfPussyEntrance", "dildoSelfAnusEntrance", "dildoSelfPussy", "dildoSelfAnus", "strokerSelfPenisEntrance", "strokerSelfPenis",
 			/* feetaction */
 			"grab", "vaginagrab", "grabrub", "vaginagrabrub", "rub",
 			/* mouthaction */
diff --git a/game/base-combat/actions-hands.twee b/game/base-combat/actions-hands.twee
index 9fd20eface..cbfe71e4bb 100644
--- a/game/base-combat/actions-hands.twee
+++ b/game/base-combat/actions-hands.twee
@@ -22,6 +22,23 @@
 	<</if>>
 <</widget>>
 
+<<widget "lefthandpull">>
+	<<if ($NPCList[$lefttarget].lefthand and $NPCList[$lefttarget].lefthand.startsWith("penis"))
+	or ($NPCList[$lefttarget].righthand and $NPCList[$lefttarget].righthand.startsWith("penis"))>>
+		<<set _leftaction["Take " + $NPCList[$lefttarget].pronouns.his + " hand off your penis"] to "handpullpenis">>
+	<</if>>
+
+	<<if ($NPCList[$lefttarget].lefthand and $NPCList[$lefttarget].lefthand.startsWith("vagina"))
+	or ($NPCList[$lefttarget].righthand and $NPCList[$lefttarget].righthand.startsWith("vagina"))>>
+		<<set _leftaction["Take " + $NPCList[$lefttarget].pronouns.his + " hand off your pussy"] to "handpullvagina">>
+	<</if>>
+
+	<<if ($NPCList[$lefttarget].lefthand and $NPCList[$lefttarget].lefthand.startsWith("anus"))
+	or ($NPCList[$lefttarget].righthand and $NPCList[$lefttarget].righthand.startsWith("anus"))>>
+		<<set _leftaction["Take " + $NPCList[$lefttarget].pronouns.his + " hand off your ass"] to "handpullanus">>
+	<</if>>
+<</widget>>
+
 <!-- Deprecated, not in use. See "leftgrabnew"-->
 <<widget "leftgrab">>
 
@@ -486,6 +503,23 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 <</if>>
 <</widget>>
 
+<<widget "righthandpull">>
+	<<if ($NPCList[$righttarget].lefthand and $NPCList[$righttarget].lefthand.startsWith("penis"))
+	or ($NPCList[$righttarget].righthand and $NPCList[$righttarget].righthand.startsWith("penis"))>>
+		<<set _rightaction["Take " + $NPCList[$righttarget].pronouns.his + " hand off your penis"] to "handpullpenis">>
+	<</if>>
+
+	<<if ($NPCList[$righttarget].lefthand and $NPCList[$righttarget].lefthand.startsWith("vagina"))
+	or ($NPCList[$righttarget].righthand and $NPCList[$righttarget].righthand.startsWith("vagina"))>>
+		<<set _rightaction["Take " + $NPCList[$righttarget].pronouns.his + " hand off your pussy"] to "handpullvagina">>
+	<</if>>
+
+	<<if ($NPCList[$righttarget].lefthand and $NPCList[$righttarget].lefthand.startsWith("anus"))
+	or ($NPCList[$righttarget].righthand and $NPCList[$righttarget].righthand.startsWith("anus"))>>
+		<<set _rightaction["Take " + $NPCList[$righttarget].pronouns.his + " hand off your ass"] to "handpullanus">>
+	<</if>>
+<</widget>>
+
 <!-- Deprecated, not in use. See "rightgrabnew"-->
 <<widget "rightgrab">>
 <<for _j = $enemyno-1; _j gte _end; _j-->>
@@ -964,6 +998,39 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 	<</if>>
 <</widget>>
 
+<<widget "combathandguide">>
+	<<if $consensual is 1 and ($enemytype is "man" ? $promiscuity : $deviancy) lt 15 and !$promiscuityIgnore>>
+		<!-- Do Nothing -->
+	<<else>>
+		<<set _handGuideOptions to {}>>
+
+		<<set $_genitals_exposed to $worn.over_lower.vagina_exposed gte 1 and ($worn.lower.vagina_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.vagina_exposed gte 1 and $worn.genitals.vagina_exposed gte 1>>
+		<<set $_anus_exposed to $worn.over_lower.anus_exposed gte 1 and ($worn.lower.anus_exposed gte 1 or $worn.lower.skirt gte 1) and $worn.under_lower.anus_exposed gte 1 and $worn.genitals.anus_exposed gte 1>>
+
+		<<if $_genitals_exposed>>
+			<<if $penisuse is 0>>
+				<<set _handGuideOptions["your penis"] to "penis">>
+			<</if>>
+
+			<<if $vaginause is 0>>
+				<<set _handGuideOptions["your pussy"] to "pussy">>
+			<</if>>
+		<</if>>
+
+		<<if $anususe is 0 and $_anus_exposed>>
+			<<set _handGuideOptions["your ass"] to "ass">>
+		<</if>>
+
+		<<if Object.keys(_handGuideOptions).length gt 0>>
+			<<if _args[0] is "left">>
+				<<set _leftaction["Guide " + $NPCList[$lefttarget].pronouns.him + " to"] to "handguide">>
+			<<else>>
+				<<set _rightaction["Guide " + $NPCList[$righttarget].pronouns.him + " to"] to "handguide">>
+			<</if>>
+		<</if>>
+	<</if>>
+<</widget>>
+
 <<widget "removeButtplug">>
 	<<if _args[0]>>
 		<<if _args[0] is "left">>
@@ -1784,43 +1851,29 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 			<<set $leftaction to 0>><<set $leftactiondefault to "freeface">>
 			<<set $rightaction to 0>><<set $rightactiondefault to "freeface">>
 			<<set _freestrength to 2.5>>
+			<<set $_t to $lefttarget>>
 			You try to use both hands to free your face,
 		<<elseif $leftaction is "freeface">>
 			<<set $leftaction to 0>><<set $leftactiondefault to "freeface">>
 			<<set _freestrength to 1>>
+			<<set $_t to $lefttarget>>
 			You try to use your hand to free your face,
 		<<elseif $rightaction is "freeface">>
 			<<set $rightaction to 0>><<set $rightactiondefault to "freeface">>
 			<<set _freestrength to 1>>
+			<<set $_t to $rightarget>>
 			You try to use your hand to free your face,
 		<</if>>
 
-		<<if $mouthuse is "facesit">>
-			<<if $mouthstate is "vagina">>
-				<<selectNpcWithPartInPosition "vagina" "facesit">>
-			<<elseif $mouthstate is "anal">>
-				<<selectNpcWithPartInPosition "vagina" "facesitanal">>
-			<</if>>
-		<<elseif $mouthstate is "nipple">>
-			<<selectNpcWithPartInPosition "chest" "mouth">>
-		<<elseif $mouthstate is "breasts">>
-			<<selectNpcWithPartInPosition "chest" "mouthentrance">>
-		<<elseif $mouthuse is "lefthand">>
-			<<selectNpcWithPartInPosition "lefthand" "mouth">>
-		<<elseif $mouthuse is "righthand">>
-			<<selectNpcWithPartInPosition "righthand" "mouth">>
-		<<elseif $mouthstate is "otheranus">>
-			<<selectNpcWithPartInPosition "penis" "mouthotheranus">>
-		<</if>>
-
+		<<set _npc to $NPCList[$_t]>><<personselect $_t>>
 		<<set _nectarDifficulty to Math.clamp($drugged, 0, 500) + Math.clamp($nectar_addiction, 0, 500)>>
 		<<willpowerdifficulty _nectarDifficulty $willpowermax "silent">>
-		<<if (($mouthuse is "facesit" and $mouthstate is "vagina") or ["nipple","breasts"].includes($mouthstate)) and ($NPCList[$lefttarget].type is "plant" or $NPCList[$righttarget].type is "plant") and !$willpowerSuccess>>
+		<<if (($mouthuse is "facesit" and $mouthstate is "vagina") or ["nipple","breasts"].includes($mouthstate)) and (_npc.type is "plant") and !$willpowerSuccess>>
 			<span class="red">but you can't tear yourself from the sweet nectar.</span>
 			<<if $mouthstate is "nipple">>
-				You desperately suck their $NPCList[0].breastdesc.
+				You desperately suck <<his>> _npc.breastdesc.
 			<<elseif $mouthstate is "breasts">>
-				You push your face back into their $NPCList[0].breastdesc.
+				You push your face back into <<his>> _npc.breastdesc.
 			<<else>>
 				You desperately lick the pussy pressing into your face.
 			<</if>>
@@ -1880,7 +1933,13 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 							"and manage to shove <<his>> ass from off of your face.",
 							"and wrestle <<him>> and <<his>> ass away from your mouth."
 						)>>
-						<<set _npc.penis to 0>><<set _npc.location.genitals to 0>>
+						<<if _npc.penis is "mouthotheranus">>
+							<<set _npc.penis to 0>>
+						<</if>>
+						<<if _npc.vagina is "mouthotheranus">>
+							<<set _npc.vagina to 0>>
+						<</if>>
+						<<set _npc.location.genitals to 0>>
 					<</if>>
 				</span>
 				<<set $mouthuse to 0>><<set $mouthstate to 0>><<set $mouthaction to 0>><<set $head to 0>>
@@ -1973,6 +2032,135 @@ $NPCList[5].lefthand is "pen" or $NPCList[5].righthand is "pen">>
 	<</if>>
 <</widget>>
 
+<<widget "effectshandpull">>
+	<<if $leftaction is "handpullpenis" or $rightaction is "handpullpenis">>
+		<<if $leftaction is "handpullpenis" and $rightaction is "handpullpenis">>
+			<<set $leftaction to 0>><<set $leftactiondefault to "handpullpenis">>
+			<<set $rightaction to 0>><<set $rightactiondefault to "handpullpenis">>
+			<<personselect $lefttarget>><<set $_handPullDifficulty to 500>>
+		<<elseif $leftaction is "handpullpenis">>
+			<<set $leftaction to 0>><<set $leftactiondefault to "handpullpenis">>
+			<<personselect $lefttarget>><<set $_handPullDifficulty to 1000>>
+		<<else>>
+			<<set $rightaction to 0>><<set $rightactiondefault to "handpullpenis">>
+			<<personselect $righttarget>><<set $_handPullDifficulty to 1000>>
+		<</if>>
+		<<brat 1>>
+
+		
+		<<if combatSkillCheck("hand", _n, $_handPullDifficulty)>>
+			You grasp <<combatpersons>> wrist,
+			<<if $penisstate is "otherhand">>
+				<span class="green">and pry <<his>> fingers off your <<penis>>.</span>
+			<<else>>
+				<span class="green">and pull it off your crotch.</span>
+			<</if>>
+
+			<<if $NPCList[_n].lefthand and $NPCList[_n].lefthand.startsWith("penis")>>
+				<<combat-reset-hand "left">>
+			<<else>>
+				<<combat-reset-hand "right">>
+			<</if>>
+			<<set $penisuse to 0>><<set $penisstate to 0>>
+		<<else>>
+			You try to grab <<combatpersons>> wrist,
+			<<if $penisstate is "otherhand">>
+				<span class="red">but <<he>> tightens <<his>> grip in retaliation.</span>
+			<<else>>
+				<span class="red">but <<he>> swats your hand away and resumes <<his>> stroking.</span>
+			<</if>>
+			<<if $consensual is 1>>
+				<<set $consensual to 0>><<molested>><<controlloss>>
+			<</if>>
+			<<violence 1>>
+		<</if>>
+	<</if>>
+
+	<<if $leftaction is "handpullvagina" or $rightaction is "handpullvagina">>
+		<<if $leftaction is "handpullvagina" and $rightaction is "handpullvagina">>
+			<<set $leftaction to 0>><<set $leftactiondefault to "handpullvagina">>
+			<<set $rightaction to 0>><<set $rightactiondefault to "handpullvagina">>
+			<<personselect $lefttarget>><<set $_handPullDifficulty to 500>>
+		<<elseif $leftaction is "handpullvagina">>
+			<<set $leftaction to 0>><<set $leftactiondefault to "handpullvagina">>
+			<<personselect $lefttarget>><<set $_handPullDifficulty to 1000>>
+		<<else>>
+			<<set $rightaction to 0>><<set $rightactiondefault to "handpullvagina">>
+			<<personselect $righttarget>><<set $_handPullDifficulty to 1000>>
+		<</if>>
+		<<brat 1>>
+
+		<<if combatSkillCheck("hand", _n, $_handPullDifficulty)>>
+			You grasp <<combatpersons>> wrist,
+			<<if $vaginastate is "otherhand">>
+				<span class="green">and pry <<his>> fingers out of your <<pussy>>.</span>
+			<<else>>
+				<span class="green">and pull it off your crotch.</span>
+			<</if>>
+
+			<<if $NPCList[_n].lefthand and $NPCList[_n].lefthand.startsWith("vagina")>>
+				<<combat-reset-hand "left">>
+			<<else>>
+				<<combat-reset-hand "right">>
+			<</if>>
+			<<set $vaginause to 0>><<set $vaginastate to 0>>
+		<<else>>
+			You try to grab <<combatpersons>> wrist,
+			<<if $vaginastate is "otherhand">>
+				<span class="red">but <<he>> jams <<his>> fingers deeper in retaliation.</span>
+			<<else>>
+				<span class="red">but <<he>> swats your hand away and resumes <<his>> stroking.</span>
+			<</if>>
+			<<if $consensual is 1>>
+				<<set $consensual to 0>><<molested>><<controlloss>>
+			<</if>>
+			<<violence 1>>
+		<</if>>
+	<</if>>
+
+	<<if $leftaction is "handpullanus" or $rightaction is "handpullanus">>
+		<<if $leftaction is "handpullanus" and $rightaction is "handpullanus">>
+			<<set $leftaction to 0>><<set $leftactiondefault to "handpullanus">>
+			<<set $rightaction to 0>><<set $rightactiondefault to "handpullanus">>
+			<<personselect $lefttarget>><<set $_handPullDifficulty to 500>>
+		<<elseif $leftaction is "handpullanus">>
+			<<set $leftaction to 0>><<set $leftactiondefault to "handpullanus">>
+			<<personselect $lefttarget>><<set $_handPullDifficulty to 1000>>
+		<<else>>
+			<<set $rightaction to 0>><<set $rightactiondefault to "handpullanus">>
+			<<personselect $righttarget>><<set $_handPullDifficulty to 1000>>
+		<</if>>
+		<<brat 1>>
+
+		<<if combatSkillCheck("hand", _n, $_handPullDifficulty)>>
+			You grasp <<combatpersons>> wrist,
+			<<if $anusstate is "otherhand">>
+				<span class="green">and pry <<his>> fingers out of your asshole.</span>
+			<<else>>
+				<span class="green">and pull it off your <<bottom>>.</span>
+			<</if>>
+
+			<<if $NPCList[_n].lefthand and $NPCList[_n].lefthand.startsWith("anus")>>
+				<<combat-reset-hand "left">>
+			<<else>>
+				<<combat-reset-hand "right">>
+			<</if>>
+			<<set $anususe to 0>><<set $anusstate to 0>>
+		<<else>>
+			You try to grab <<combatpersons>> wrist,
+			<<if $anusstate is "otherhand">>
+				<span class="red">but <<he>> jams <<his>> fingers deeper in retaliation.</span>
+			<<else>>
+				<span class="red">but <<he>> swats your hand away and resumes <<his>> stroking.</span>
+			<</if>>
+			<<if $consensual is 1>>
+				<<set $consensual to 0>><<molested>><<controlloss>>
+			<</if>>
+			<<violence 1>>
+		<</if>>
+	<</if>>
+<</widget>>
+
 <<widget "hand_section">>
 	<!-- This widget is for NPC hands. -->
 
diff --git a/game/base-combat/actions-mouth.twee b/game/base-combat/actions-mouth.twee
index 45eb24e2e8..a17f9f0c42 100644
--- a/game/base-combat/actions-mouth.twee
+++ b/game/base-combat/actions-mouth.twee
@@ -233,6 +233,9 @@
 		<<set _mouthaction["Kiss ass"] to "analkiss">>
 	<</if>>
 <</if>>
+<<if $consensual is 1 and $head isnot "grappled" and $head isnot "bound" and $mouthuse isnot "facesit">>
+	<<set _mouthaction["Pull away"] to "analpull">>
+<</if>>
 <</widget>>
 
 <<widget "combatBreast">>
diff --git a/game/base-combat/actionsGeneration.twee b/game/base-combat/actionsGeneration.twee
index 6dcd3b11fc..be8daab528 100644
--- a/game/base-combat/actionsGeneration.twee
+++ b/game/base-combat/actionsGeneration.twee
@@ -449,6 +449,13 @@
 			<</listbox>>
 		<</if>>
 		<<combatpromiscuous3>>
+	<<case "handguide">>
+		<<if Object.keys(_handGuideOptions).length gt 0>>
+			<<listbox "$handGuideLeft" autoselect>>
+				<<optionsfrom _handGuideOptions>>
+			<</listbox>>
+		<</if>>
+		<<handdifficulty>> <<combatpromiscuous2>>
 <</switch>>
 <</widget>>
 
@@ -486,10 +493,12 @@
 			<<leftdildowhack>>
 			<<pickupSexToy "left">>
 			<<leftcamerapose>>
+			<<lefthandpull>>
 		<<case "handheld">>
 			<<if $consensual is 1>>
 			<<set _leftaction["Keep holding"] to "lefthandholdkeep">>
 			<</if>>
+			<<combathandguide "left">>
 			<<set _leftaction["Stop"] to "lefthandholdstop">>
 		<<case "penis">>
 			<<if $NPCList[$lefttarget].chastity.penis.includes("chastity")>>
@@ -814,6 +823,13 @@
 			<</listbox>>
 		<</if>>
 		<<combatpromiscuous3>>
+	<<case "handguide">>
+		<<if Object.keys(_handGuideOptions).length gt 0>>
+			<<listbox "$handGuideRight" autoselect>>
+				<<optionsfrom _handGuideOptions>>
+			<</listbox>>
+		<</if>>
+		<<handdifficulty>> <<combatpromiscuous2>>
 <</switch>>
 <</widget>>
 
@@ -851,10 +867,12 @@
 			<<rightdildowhack>>
 			<<pickupSexToy "right">>
 			<<rightcamerapose>>
+			<<righthandpull>>
 		<<case "handheld">>
 			<<if $consensual is 1>>
 				<<set _rightaction["Keep holding"] to "righthandholdkeep">>
 			<</if>>
+			<<combathandguide "right">>
 			<<set _rightaction["Stop"] to "righthandholdstop">>
 		<<case "penis">>
 			<<if $NPCList[$righttarget].chastity.penis.includes("chastity")>>
@@ -1304,6 +1322,7 @@
 	<<case "movetochest">><<oraldifficulty>> <<combatpromiscuous3>>
 	<<case "swallow">><<oralvirginitywarning>> <<combatpromiscuous5>>
 	<<case "grasp">><<chestdifficulty>> <<combatpromiscuous3>>
+	<<case "kisslips">><<oraldifficulty>> <<combatpromiscuous1>>
 	<<case "pullaway" "pullawaykiss">><<oraldifficulty>>
 	<<case "finish">><<if !$gloryhole and $gamemode isnot "soft">><<seductiondifficulty>><</if>>
 	<<case "novaginal">><<if !$gloryhole and $gamemode isnot "soft">><<seductiondifficulty>><</if>>
diff --git a/game/base-combat/effects.twee b/game/base-combat/effects.twee
index 41c2a0df9a..5a4382e1d8 100644
--- a/game/base-combat/effects.twee
+++ b/game/base-combat/effects.twee
@@ -97,6 +97,7 @@
 <<effectsshacklewhack>>
 <<effectshypnosiswhack>>
 <<effectshandsfreeface>>
+<<effectshandpull>>
 <<effectsdildowhack>>
 
 <<if $bodyaction is "doggy">>
@@ -198,6 +199,80 @@
 	<</if>>
 <</if>>
 
+<<if $leftaction is "handguide">>
+	<<set $leftaction to 0>><<set $leftactiondefault to "handguide">><<combatpromiscuity2>>
+
+	<<if combatSkillCheck("hand", $lefttarget)>>
+		<<if $rightaction is "handguide" and $handGuideLeft is $handGuideRight>>
+			<<set $rightaction to 0>><<set $rightactiondefault to "rest">>
+		<</if>>
+
+		<<switch $handGuideLeft>>
+			<<case "penis">>
+				You lower <<someones $lefttarget>> hand to your <<penis>>.
+				<<set $NPCList[$lefttarget].righthand to "penisentrance">><<set $penisuse to 1>><<set $penisstate to "otherhandentrance">>
+			<<case "pussy">>
+				You lower <<someones $lefttarget>> hand to your <<pussy>>.
+				<<set $NPCList[$lefttarget].righthand to "vaginaentrance">><<set $vaginause to 1>><<set $vaginastate to "otherhandentrance">>
+			<<case "ass">>
+				You press <<someones $lefttarget>> hand against your <<bottom>>.
+				<<set $NPCList[$lefttarget].righthand to "anusentrance">><<set $anususe to "handentrance">><<set $anusstate to "handentrance">>
+			<<default>>
+		<</switch>>
+		<<set $leftactiondefault to "rest">><<set $leftarm to 0>><<submission 1 $lefttarget>>
+	<<else>>
+		You try to guide <<someones $lefttarget>> hand to
+		<<switch $handGuideRight>>
+			<<case "penis">>your <<penis>>,
+			<<case "pussy">>your <<pussy>>,
+			<<case "ass">>your <<bottom>>,
+			<<default>>
+		<</switch>>
+
+		<<if $enemyanger gte random(30, 100)>>
+			<span class="purple">but <<he>> wrenches it out of your grasp.</span>
+			<<set $leftactiondefault to "rest">><<set $leftarm to 0>>
+			<<set $NPCList[$lefttarget].righthand to 0>><<violence 2>>
+		<<else>>
+			but <<his>> grip is too tight.
+		<</if>>
+	<</if>>
+<</if>>
+
+<<if $rightaction is "handguide">>
+	<<set $rightaction to 0>><<set $rightactiondefault to "handguide">><<combatpromiscuity2>>
+
+	<<if combatSkillCheck("hand", $righttarget)>>
+		<<switch $handGuideRight>>
+			<<case "penis">>
+				You lower <<someones $lefttarget>> hand to your <<penis>>.
+				<<set $NPCList[$righttarget].lefthand to "penisentrance">><<set $penisuse to 1>><<set $penisstate to "otherhandentrance">>
+			<<case "pussy">>
+				Your lower <<someones $lefttarget>> hand to your <<pussy>>.
+				<<set $NPCList[$righttarget].lefthand to "vaginaentrance">><<set $vaginause to 1>><<set $vaginastate to "otherhandentrance">>
+			<<case "ass">>
+				You press <<someones $lefttarget>> hand against your <<bottom>>.
+				<<set $NPCList[$righttarget].lefthand to "anusentrance">><<set $anususe to "handentrance">><<set $anusstate to "handentrance">>
+		<</switch>>
+		<<set $rightactiondefault to "rest">><<set $rightarm to 0>><<submission 1 $righttarget>>
+	<<else>>
+		You try to guide <<someones $lefttarget>> hand to
+		<<switch $handGuideRight>>
+			<<case "penis">>your <<penis>>,
+			<<case "pussy">>your <<pussy>>,
+			<<case "ass">>your <<bottom>>,
+		<</switch>>
+
+		<<if $enemyanger gte random(30, 100)>>
+			<span class="purple">but <<he>> wrenches it out of your grasp.</span>
+			<<set $rightactiondefault to "rest">><<set $rightarm to 0>>
+			<<set $NPCList[$righttarget].lefthand to 0>><<violence 2>>
+		<<else>>
+			but <<his>> grip is too tight.
+		<</if>>
+	<</if>>
+<</if>>
+
 <<if $leftaction is "leftgrab">>
 	<<set $leftaction to 0>><<set $leftactiondefault to "leftgrab">><<handskilluse>><<combatpromiscuity3>>
 	<<if combatSkillCheck("hand", $lefttarget)>>
@@ -2960,7 +3035,7 @@
 <</if>>
 
 <<if $mouthaction is "kisslips">>
-	<<set $mouthaction to 0>><<set $mouthactiondefault to "kisslips">><<personselect $mouthtarget>>
+	<<set $mouthaction to 0>><<set $mouthactiondefault to "kisslips">><<personselect $mouthtarget>><<combatpromiscuity1>>
 	<<if combatSkillCheck("oral", $mouthtarget)>>
 		You move your lips close to <<hers>>.
 		<<set $mouthuse to "kiss">><<set $mouthstate to "kissentrance">>
@@ -3494,6 +3569,25 @@
 	<<set $mouthaction to 0>><<set $mouthactiondefault to "analkiss">><<actionsAnalKiss $mouthtarget>><<submission 12 $mouthtarget>>
 <</if>>
 
+<<if $mouthaction is "analpull" and ($NPCList[$mouthtarget].penis is "mouthotheranus" or $NPCList[$mouthtarget].vagina is "mouthotheranus")>>
+	<<set $mouthaction to 0>><<set $mouthactiondefault to "analpull">><<personselect $mouthtarget>>
+	You try to pull away from the anus menacing your mouth.
+	<<oralskilluse>><<brat 1 $mouthtarget>>
+	<<if combatSkillCheck("oral", $mouthtarget)>>
+		<span class="green"><<He>> doesn't stop you.</span>
+		<<set $mouthstate to 0>><<set $mouthuse to 0>>
+		<<if $NPCList[$mouthtarget].penis is "mouthotheranus">><<set $NPCList[$mouthtarget].penis to 0>><</if>>
+		<<if $NPCList[$mouthtarget].vagina is "mouthotheranus">><<set $NPCList[$mouthtarget].vagina to 0>><</if>>
+		<<set $NPCList[$mouthtarget].location.genitals to 0>>
+	<<else>>
+		<span class="red">However, <<combatperson>> refuses to allow it,</span> forcing your face into <<his>> ass.
+		<<violence 1>>
+		<<if $consensual is 1>>
+			<<set $consensual to 0>><<molested>><<controlloss>>
+		<</if>>
+	<</if>>
+<</if>>
+
 <<rng>>
 
 <<if $mouthaction is "handbite">>
diff --git a/game/base-combat/end.twee b/game/base-combat/end.twee
index 792a01d6a9..a95850a201 100644
--- a/game/base-combat/end.twee
+++ b/game/base-combat/end.twee
@@ -238,6 +238,8 @@
 <<unset $stealstateleft>>
 <<unset $stealstateright>>
 <<unset $position_lock>>
+<<unset $handGuideLeft>>
+<<unset $handGuideRight>>
 
 
 <<set $leftactiondefault to $leftaction>>
diff --git a/game/base-combat/man-combat.twee b/game/base-combat/man-combat.twee
index 791f77bd5a..25ecae1dd2 100644
--- a/game/base-combat/man-combat.twee
+++ b/game/base-combat/man-combat.twee
@@ -279,7 +279,23 @@ Hands are 'inverted': NPC holds PC's left hand with their right one, and vice ve
 <<widget "combat-hand-on-hand">>
 	<<rng>>
 	<<set $_hand to _args[0]>>
-	<<if $rng gte 95>>
+	<<if $enemyanger + $rng gte 196>>
+		In anger, <span class="pink"><<he>> wrenches <<his>> hand from your grasp.</span>
+		<<combat-reset-hand _args[0]>>
+		<<if $_hand is "left">>
+			<<set $rightarm to 0>>
+		<<else>>
+			<<set $leftarm to 0>>
+		<</if>>
+		<<violence 5>>
+	<<elseif $enemyanger + $rng gte 160>>
+		<<print either(
+			"<<He>> digs <<his>> nails into your wrist.",
+			"<<He>> crushes your hand in <<his>> grip.",
+			"<<He>> bends your fingers back."
+		)>>
+		<<violence 10>><<hitstat>><<set $speechbeat to 1>>
+	<<elseif $rng gte 95>>
 		<span class="purple"><<He>> releases your <<print ($_hand is "left" ? "right" : "left")>> hand.</span>
 		<<combat-reset-hand _args[0]>>
 		<<if $_hand is "left">>
@@ -4493,6 +4509,27 @@ Hands are 'inverted': NPC holds PC's left hand with their right one, and vice ve
 		<</if>>
 	<</if>>
 
+	<<rng>>
+	<<if $NPCList[_n].vagina is "mouthotheranus">>
+		<<if $rng gte 1>>
+			<<if $enemyarousal gte (($enemyarousalmax / 5) * 3)>>
+				<<He>> grinds <<his>> ass against your mouth.
+			<<else>>
+				<<He>> slowly moves <<his>> ass against your lips.
+			<</if>>
+			<<sex 3 _n>><<set $speechmouthotheranus to 1>>
+			<<if $mouthactiondefault is "anallick">>
+				<<set $speechanallick to 1>>
+			<<elseif $mouthactiondefault is "analkiss">>
+				<<set $speechanalkiss to 1>>
+			<</if>>
+		<<else>>
+			<span class="purple"><<He>> moves <<his>> ass away from your face.</span>
+			<<set $mouthuse to 0>><<set $mouthstate to 0>><<set $NPCList[_n].penis to 0>>
+			<<set $NPCList[_n].location.genitals = 0>>
+		<</if>>
+	<</if>>
+
 	<<if $NPCList[_n].vagina is 0 and $NPCList[_n].penis is 0>>
 		<<if random(0,1) is 0>>
 			<<vaginainit>>
diff --git a/game/base-system/bodywriting.twee b/game/base-system/bodywriting.twee
index c718553e66..14112c8766 100755
--- a/game/base-system/bodywriting.twee
+++ b/game/base-system/bodywriting.twee
@@ -915,13 +915,22 @@ Second arg: tool */
 <<if $skin[_args[0]].special is "prostitution" and $NPCList[_n].type isnot "plant">>
 	<<bodypart_admire_prostitution _args[0]>>
 <</if>>
-<<if _args[0] is "left_cheek" or _args[0] is "right_cheek" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "head" and ($position isnot "wall" or $walltype is "front")>>
-	<<if $NPCList[_n].penis is 0 and $mouthuse is 0>>
+<<if (_args[0] is "left_cheek" or _args[0] is "right_cheek") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "head" and ($position isnot "wall" or $walltype is "front") and $mouthuse is 0>>
+	<<if $analingusdisablegiving is "f" and random(1, 10) is 1 and ($NPCList[_n].penis is 0 or $NPCList[_n].vagina is 0)>>
+		<<He>> follows the arrow's instruction, <span class="blue">and swings <<his>> ass in front of your face.</span>
+		<<neutral 5>><<set $mouthuse to "otheranus">><<set $mouthstate to "otheranus">>
+		<<if $NPCList[_n].penis is 0>>
+			<<set $NPCList[_n].penis to "mouthotheranus">>
+		<</if>>
+		<<if $NPCList[_n].vagina is 0>>
+			<<set $NPCList[_n].vagina to "mouthotheranus">>
+		<</if>>
+		<<set $NPCList[_n].location.genitals = "head">><<set $speechmouthotheranus to 1>><<set $mouthtarget to _n>>
+	<<elseif $NPCList[_n].penis is 0>>
 		<<He>> follows the arrow's instruction, <span class="blue">and positions <<his>> $NPCList[_n].penisdesc in front of your mouth.</span>
 		<<neutral 5>><<set $mouthuse to "penis">><<set $NPCList[_n].penis to "mouthentrance">><<set $mouthstate to "entrance">><<set $speechmouthentrance to 1>><<set $mouthtarget to _n>>
 		<<set $NPCList[_n].location.genitals to "head">>
-
-	<<elseif $NPCList[_n].vagina is 0 and $mouthuse is 0>>
+	<<elseif $NPCList[_n].vagina is 0>>
 		<<He>> follows the arrow's instruction.
 		<<if random(4) is 0 and $facesitdisable is "f">>
 			<<if $position is "doggy">>
@@ -952,23 +961,52 @@ Second arg: tool */
 			<<set $NPCList[_n].location.genitals to "head">>
 		<</if>>
 	<</if>>
-<<elseif _args[0] is "back" or _args[0] is "right_bottom" or _args[0] is "left_bottom" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals">>
-	<<if $worn.lower.anus_exposed gte 1 and $worn.under_lower.anus_exposed gte 1 and $NPCList[_n].penis is 0 and $anususe is 0>>
-		<<He>> follows the arrow's instruction, <span class="blue">and positions <<his>> penis in front of your <<bottom>>.</span>
-		<<if $NPCList[_n].type is "plant" and $NPCList[_n].penissize gte 4>>
-			<span class="green">Something about it scares you.</span>
+<<elseif (_args[0] is "back" or _args[0] is "right_bottom" or _args[0] is "left_bottom") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals">>
+	<<if $worn.lower.anus_exposed gte 1 and $worn.under_lower.anus_exposed gte 1 and $anususe is 0>>
+		<<if $analingusdisablereceiving is "f" and $NPCList[_n].mouth is 0 and ($NPCList[_n].penis is "none" or random(1, 10) is 1)>>
+			<<He>> follows the arrow's instruction and lowers <<his>> head, <span class="blue">until <<hes>> level with your <<bottom>>.</span>
+			<<neutral 5>><<set $NPCList[_n].mouth to "anusentrance">><<set $anususe to "othermouth">><<set $anusstate to "othermouthentrance">>
+			<<set $NPCList[_n].location.head to "genitals">><<set $anustarget to _n>>
+		<<elseif $NPCList[_n].penis is 0>>
+			<<He>> follows the arrow's instruction, <span class="blue">and positions <<his>> penis in front of your <<bottom>>.</span>
+			<<if $NPCList[_n].type is "plant" and $NPCList[_n].penissize gte 4>>
+				<span class="green">Something about it scares you.</span>
+			<</if>>
+			<<neutral 5>><<set $anususe to "penis">><<set $NPCList[_n].penis to "anusentrance">><<set $anusstate to "entrance">><<set $speechanusentrance to 1>>
+			<<set $NPCList[_n].location.genitals to "genitals">><<set $anustarget to _n>>
+		<</if>>
+	<</if>>
+<<elseif (_args[0] is "pubic" or _args[0] is "left_thigh" or _args[0] is "right_thigh") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals">>
+	<<if $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1>>
+		<<if $penisuse is 0 and ($vaginause isnot 0 or random(1))>>
+			<<if random(1, 5) is 1 and $NPCList[_n].mouth is 0>>
+				<<He>> follows the arrow's instruction and lowers <<his>> head, <span class="blue">until <<hes>> level with your <<penis>>.</span>
+				<<neutral 5>><<set $NPCList[_n].mouth to "penisentrance">><<set $penisuse to "othermouth">><<set $penisstate to "othermouthentrance">>
+				<<set $NPCList[_n].location.head to "genitals">><<set $penistarget to _n>>
+			<<elseif $NPCList[_n].penis is 0>>
+				<<He>> follows the arrow's instruction, <span class="blue">and angles <<his>> $NPCList[_n].penisdesc towards yours.</span>
+				<<neutral 5>><<set $NPCList[_n].penis to "penisentrance">><<set $penisuse to "otherpenis">><<set $penisstate to "otherpenisentrance">>
+				<<set $NPCList[_n].location.genitals to "genitals">><<set $penistarget to _n>><<set $speechfencingentrance to 1>>
+			<<elseif $NPCList[_n].vagina is 0>>
+				<<He>> follows the arrow's instruction, <span class="blue">and straddles you, <<his>> pussy hovering close to your <<penis>>.</span>
+				<<neutral 5>><<set $NPCList[_n].vagina to "penisentrance">><<set $penisuse to "othervagina">><<set $penisstate to "entrance">>
+				<<set $NPCList[_n].location.genitals to "genitals">><<set $penistarget to _n>><<set $speechpenisentrance to 1>>
+			<</if>>
+		<<elseif $vaginause is 0>>
+			<<if random(1, 5) is 1 and $NPCList[_n].mouth is 0>>
+				<<He>> follows the arrow's instruction and lowers <<his>> head, <span class="blue">until <<hes>> level with your <<pussy>>.</span>
+				<<neutral 5>><<set $NPCList[_n].mouth to "vaginaentrance">><<set $vaginause to "othermouth">><<set $vaginastate to "othermouthentrance">>
+				<<set $NPCList[_n].location.head to "genitals">><<set $vaginatarget to _n>>
+			<<elseif $NPCList[_n].penis is 0>>
+				<<He>> follows the arrow's instruction, <span class="blue">and moves between your legs, positioning <<his>> $NPCList[_n].penisdesc in front of your <<pussy>>.</span>
+				<<neutral 5>><<set $NPCList[_n].penis to "vaginaentrance">><<set $vaginause to "penis">><<set $vaginastate to "entrance">>
+				<<set $NPCList[_n].location.genitals to "genitals">><<set $vaginatarget to _n>><<set $speechvaginaentrance to 1>>
+			<<elseif $NPCList[_n].vagina is 0>>
+				<<He>> follows the arrow's instruction, <span class="blue">and moves <<his>> pussy closer to yours.</span>
+				<<neutral 5>><<set $NPCList[_n].vagina to "vaginaentrance">><<set $vaginause to "othervagina">><<set $vaginastate to "othervaginaentrance">>
+				<<set $NPCList[_n].location.genitals to "genitals">><<set $vaginatarget to _n>><<set $speechtribentrance to 1>>
+			<</if>>
 		<</if>>
-		<<neutral 5>><<set $anususe to "penis">><<set $NPCList[_n].penis to "anusentrance">><<set $anusstate to "entrance">><<set $speechanusentrance to 1>>
-		<<set $NPCList[_n].location.genitals to "genitals">><<set $anustarget to _n>>
-	<</if>>
-<<elseif _args[0] is "pubic" or _args[0] is "left_thigh" or _args[0] is "right_thigh" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals">>
-	<<if $player.vaginaExist and $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1 and $NPCList[_n].penis is 0 and $vaginause is 0>>
-		<<He>> follows the arrow's instruction, <span class="blue">and moves between your legs, positioning <<his>> $NPCList[_n].penisdesc in front of your <<pussy>>.</span>
-		<<neutral 5>><<set $NPCList[_n].penis to "vaginaentrance">><<set $vaginause to "penis">><<set $vaginastate to "entrance">><<set $NPCList[_n].location.genitals to "genitals">><<set $vaginatarget to _n>>
-	<<elseif $player.penisExist and $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1 and $NPCList[_n].vagina is 0 and $penisuse is 0>>
-		<<set $penisuse to "othervagina">><<set $NPCList[_n].vagina to "penisentrance">><<set $penisstate to "entrance">><<set $penistarget to _n>>
-		<<He>> follows the arrow's instruction, <span class="blue">and straddles you, <<his>> pussy hovering close to your <<penis>>.</span>
-		<<set $NPCList[_n].location.genitals to "genitals">>
 	<</if>>
 <</if>>
 <<set $speechadmired to 1>>
diff --git a/game/base-system/overlays/cheats.twee b/game/base-system/overlays/cheats.twee
index d66604a3ea..63acaae181 100644
--- a/game/base-system/overlays/cheats.twee
+++ b/game/base-system/overlays/cheats.twee
@@ -2263,7 +2263,7 @@ Model: <span id="statsfamemodel"><<print Math.trunc($fame.model)>></span>
 <<widget "cheats-teleport">>
 <<if ["Clothing Shop", "Forest Shop", "School Library Shop", "Adult Shop Store"].includes($passage)>>
 	<span class="red">Teleporting from a clothing store can break your wardrobe.</span> Please leave the shop before teleporting.
-<<else>>
+<<elseif setup.majorAreas.includes($passage) and $event is undefined>>
 	<b>Teleporting from anywhere but the overworld can cause bugs.</b>
 	<br><br>
 
@@ -2373,6 +2373,8 @@ Model: <span id="statsfamemodel"><<print Math.trunc($fame.model)>></span>
 	<br>
 	<<sewericon>>[[Sewers Industrial]]
 	<br>
+<<else>>
+	<span class="red">You are in an area where teleporting can break your save, or an event is in progress.</span> Return to the overworld before teleporting.
 <</if>>
 <</widget>>
 
diff --git a/game/base-system/promiscuity.twee b/game/base-system/promiscuity.twee
index 464af98c90..231d708c07 100644
--- a/game/base-system/promiscuity.twee
+++ b/game/base-system/promiscuity.twee
@@ -112,7 +112,7 @@
 			<<else>>
 				<<set _combat_promiscuity_failure to $_n>>
 				<<if V["promiscuitystress" + $_n] isnot 1 and $statFreeze isnot true>>
-					<<set V["promiscuitystress" + $_n] to 1>><<lstress>><<stress $_n -100>>
+					<<set V["promiscuitystress" + $_n] to 1>><<stress $_n -100>>
 				<</if>>
 			<</if>>
 			<<arousal `$_n * 100`>>
@@ -130,6 +130,6 @@
 		Your promiscuous behaviour <span class="green">soothes and excites you.</span><<ltrauma>><<lstress>><<garousal>>
 	<<elseif _combat_promiscuity_failure>>
 		<br>
-		Your behaviour is promiscuous, <span class="pink">though it's too tame to soothe.</span><<garousal>>
+		Your behaviour is promiscuous, <span class="pink">though it's too tame to soothe.</span><<lstress>><<garousal>>
 	<</if>>
 <</widget>>
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index 801d2db12d..b59f4b2538 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -7433,6 +7433,12 @@ Argument 2, where appropriate, determines whether it's the player undressing the
 	<</if>>
 <</widget>>
 
+<<widget "stockholmTrait">>
+	<<if $statdisable is "f">>
+		| <span class="gold">Stockholm Syndrome<<if _args[0]>>: <<print _args[0]>><</if>></span>
+	<</if>>
+<</widget>>
+
 <<widget "note">>
 	<<if $statdisable is "f">> |
 		<span @class="_args[1]"><<print _args[0]>></span>
@@ -7454,4 +7460,4 @@ Argument 2, where appropriate, determines whether it's the player undressing the
 	<<if $statdisable is "f" and $_furniture>>
 		| <span class="blue">This will replace your <<if _args[0] is "wallpaper" or _args[0] is "poster">>current <<print _args[0]>><<else>><<print $_furniture.name>><</if>></span>
 	<</if>>
-<</widget>>
+<</widget>>
\ No newline at end of file
diff --git a/game/base-system/time.twee b/game/base-system/time.twee
index cf036bc616..01c0fff0ce 100644
--- a/game/base-system/time.twee
+++ b/game/base-system/time.twee
@@ -61,6 +61,7 @@
 	<<unset $whitneyAsk>>
 	<<unset $whitney_text>>
 	<<unset $whitney_text_trigger>>
+	<<unset $whitneyPub>>
 	<<set $whitneyDaily to {}>>
 	<<set $policecollarseduceattempt to 0>>
 	<<set $tenyclusPlayed to 0>>
diff --git a/game/overworld-forest/loc-asylum/widgets.twee b/game/overworld-forest/loc-asylum/widgets.twee
index 6076ef62f3..15d18e9b18 100644
--- a/game/overworld-forest/loc-asylum/widgets.twee
+++ b/game/overworld-forest/loc-asylum/widgets.twee
@@ -245,7 +245,7 @@ Harper stares at you across the desk. "Let's talk about your exposure fetish," <
 <</if>>
 <<if $asylumkeycard isnot 1 and $leftarm isnot "bound" and $rightarm isnot "bound">>
 <<set $skulduggerydifficulty to 900 + (20 * $suspicion)>>
-<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <i>This will be easier with low suspicion.</i>
+<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <<note "This will be easier with low suspicion" "italic">>
 <br>
 <</if>>
 <<link [[Insist that isn't true|Asylum Exhibit Meek]]>><<awareness -1>><<stress 3>><</link>><<lawareness>><<gstress>>
@@ -267,7 +267,7 @@ Harper stares at you across the desk. "In your sleep you talk about being attack
 <</if>>
 <<if $asylumkeycard isnot 1 and $leftarm isnot "bound" and $rightarm isnot "bound">>
 <<set $skulduggerydifficulty to 900 + (20 * $suspicion)>>
-<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <i>This will be easier with low suspicion.</i>
+<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <<note "This will be easier with low suspicion" "italic">>
 <br>
 <</if>>
 <<link [[Insist they are real|Asylum Tentacles Meek]]>><<awareness 1>><<stress 3>><</link>><<gawareness>><<gstress>>
@@ -295,7 +295,7 @@ Harper stares at you across the desk. "In your sleep you talk about being attack
 	<</if>>
 	<<if $asylumkeycard isnot 1 and $leftarm isnot "bound" and $rightarm isnot "bound">>
 		<<set $skulduggerydifficulty to 900 + (20 * $suspicion)>>
-		<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <i>This will be easier with low suspicion.</i>
+		<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <<note "This will be easier with low suspicion" "italic">>
 		<br>
 	<</if>>
 	<<link [[Insist that isn't true|Asylum Beast Meek]]>><<awareness -1>><<stress 3>><</link>><<lawareness>><<gstress>>
@@ -317,7 +317,7 @@ Harper stares at you across the desk. "In your sleep you talk about being attack
 	<</if>>
 	<<if $asylumkeycard isnot 1 and $leftarm isnot "bound" and $rightarm isnot "bound">>
 		<<set $skulduggerydifficulty to 900 + (20 * $suspicion)>>
-		<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <i>This will be easier with low suspicion.</i>
+		<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>> <<note "This will be easier with low suspicion" "italic">>
 		<br>
 	<</if>>
 	<<link [[Insist that isn't true|Asylum Hurt Meek]]>><<awareness -1>><<stress 3>><</link>><<lawareness>><<gstress>>
@@ -339,7 +339,7 @@ Harper stares at you across the desk. "In your sleep you talk about being raped
 <</if>>
 <<if $asylumkeycard isnot 1 and $leftarm isnot "bound" and $rightarm isnot "bound">>
 <<set $skulduggerydifficulty to 900 + (20 * $suspicion)>>
-<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>><i>This will be easier with low suspicion.</i>
+<<link [[Steal keycard|Asylum Keycard]]>><</link>><<skulduggerydifficulty>><<note "This will be easier with low suspicion" "italic">>
 <br>
 <</if>>
 <<link [[Insist that isn't true|Asylum Rape Meek]]>><<awareness -1>><<stress 3>><</link>><<lawareness>><<gstress>>
diff --git a/game/overworld-town/loc-adultshop/events.twee b/game/overworld-town/loc-adultshop/events.twee
index 7f9471c1b7..89e432b7ab 100644
--- a/game/overworld-town/loc-adultshop/events.twee
+++ b/game/overworld-town/loc-adultshop/events.twee
@@ -775,7 +775,7 @@ You flip onto your back, without disturbing Sydney's position. <<He>> jerks away
 <<if $pronoun is "f">>
 	You run your tongue along Sydney's thigh, skimming <<his>> <<sydneyGenitals>>.
 <<else>>
-	You bite down on <<his>> belt and pull, <span class="lewd">revealing <<his>> <<sydneyGenitals>>.</span> You flick your tongue against <<if _sydneyChastity>><<his>> thigh<<else>>the tip<</if>>.
+	You bite down on <<his>> belt and pull, <span class="lewd">revealing <<his>> <<sydneyGenitals>>.</span> You flick your tongue against <<if _sydneyChastity>><<his>> thigh<<elseif $NPCList[0].penis isnot "none">>the tip<<else>><<his>> clit<</if>>.
 <</if>>
 <<He>> shivers in pleasure, nearly toppling off you, but you
 
@@ -2135,7 +2135,8 @@ Sydney tries to explain the situation, but <<his>> stammering fades into the dis
 	Sydney shrugs. "Okay. I'll leave you alone." <<He>> exits the back room without another word, leaving you locked up.<<stress 2>><<gstress>>
 	<br><br>
 
-	You struggle in vain to free yourself. After a while, Sirris comes in to investigate the noise. <<He>> gasps when <<he>> sees you, and soon sets you free.
+	<<npc Sirris 2>><<person2>>
+	You struggle in vain to free yourself. After a while, Sirris comes in to investigate the noise. <<He>> gasps when <<he>> sees you, and soon has you free.
 	<br><br>
 
 	<<tearful>> you dodge Sirris' questions and hasten back to work. You pass by Sydney, who smiles and waves.<<npcincr Sydney lust 1>><<gslust>>
diff --git a/game/overworld-town/loc-docks/main.twee b/game/overworld-town/loc-docks/main.twee
index 95443b7601..1be6311a97 100644
--- a/game/overworld-town/loc-docks/main.twee
+++ b/game/overworld-town/loc-docks/main.twee
@@ -1554,7 +1554,7 @@ The pub owner steps up to a microphone in the corner of the room, preparing to r
 		<br><br>
 		<<if $dockquiz is "money">>
 			They take their money. "Sorry guys," the <<person>> says. "Shoulda known better than to challenge us."
-			<<lcool>><<status -1>>
+			<<lcool>><<dockstatus -1>>
 			<br><br>
 			You and your colleagues leave in a sour mood.
 			<<lstress>><<stress -6>>
diff --git a/game/overworld-town/loc-docks/widgets.twee b/game/overworld-town/loc-docks/widgets.twee
index 8e984a648e..11076c382b 100644
--- a/game/overworld-town/loc-docks/widgets.twee
+++ b/game/overworld-town/loc-docks/widgets.twee
@@ -585,18 +585,20 @@ is lovemaking, which prompts a bawdy cheer. Your colleagues insist this will be
 <</widget>>
 
 <<widget "skul_dock_state">>
-<<if $skul_dock[_args[0]].state is "known">>
-	<<if $skul_dock[_args[0]].contents is "none">>
-		<span class="purple">The containers here contain nothing of value to you.</span>
-	<<elseif $skul_dock[_args[0]].contents is "fertiliser" and $tending lt 400>>
-		<span class="purple">The containers here contain nothing of value to you.</span>
+<<if $statdisable is "f">>
+	<<if $skul_dock[_args[0]].state is "known">>
+		<<if $skul_dock[_args[0]].contents is "none">>
+			<span class="purple">The containers here contain nothing of value to you.</span>
+		<<elseif $skul_dock[_args[0]].contents is "fertiliser" and $tending lt 400>>
+			<span class="purple">The containers here contain nothing of value to you.</span>
+		<<else>>
+			<span class="teal">A container here contains valuable <<print $skul_dock[_args[0]].contents>>.</span>
+		<</if>>
+	<<elseif $skul_dock[_args[0]].state is "empty">>
+		<span class="lblue">You've checked here.</span>
 	<<else>>
-		<span class="teal">A container here contains valuable <<print $skul_dock[_args[0]].contents>>.</span>
+		<span class="blue">Unknown contents.</span>
 	<</if>>
-<<elseif $skul_dock[_args[0]].state is "empty">>
-	<span class="lblue">You've checked here.</span>
-<<else>>
-	<span class="blue">Unknown contents.</span>
 <</if>>
 <</widget>>
 
diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index e5d3dadc42..2425ca75f9 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -864,7 +864,7 @@ You are in the bathroom.
 			<<link [[Berate Kylar|Kylar Orphanage Sleep Berate]]>><<set $kylarbed to 0>><<npcincr Kylar love -3>><</link>><<lllove>>
 			<br>
 			<<if $submissive lte 500 or $syndromekylar gte 1>>
-				<<link [[Slam the door|Kylar Orphanage Slam]]>><<set $kylarbed to 0>><<npcincr Kylar love 1>><<npcincr Kylar lust 1>><</link>><<glove>><<glust>><<if $syndromekylar gte 1>> | <span class="gold">Stockholm Syndrome</span><<else>><<defianttext>><</if>>
+				<<link [[Slam the door|Kylar Orphanage Slam]]>><<set $kylarbed to 0>><<npcincr Kylar love 1>><<npcincr Kylar lust 1>><</link>><<glove>><<glust>><<if $syndromekylar gte 1>><<stockholmTrait "Kylar">><<else>><<defianttext>><</if>>
 			<</if>>
 
 		<<else>>
diff --git a/game/overworld-town/loc-prison/wren.twee b/game/overworld-town/loc-prison/wren.twee
index 62a0f6242c..f5d8205b9c 100644
--- a/game/overworld-town/loc-prison/wren.twee
+++ b/game/overworld-town/loc-prison/wren.twee
@@ -72,7 +72,7 @@ Wren smiles at you. "If you've got teeth," <<he>> says. "I have some goodies fro
 	Poster of a sexy gentleman: 50 teeth
 	<br>
 	<<if $prison.teeth gte 50>>
-		<<link [[Buy|Prison Wren Poster]]>><<prison_teeth -50>><<set $prison.poster to "man">><</link>><<if $prison.poster>> <i>Will replace existing poster.</i><</if>>
+		<<link [[Buy|Prison Wren Poster]]>><<set $poster_choice to "man">><<set $phase to 0>><</link>>
 	<<else>>
 		<span class="blue">You need more teeth.</span>
 	<</if>>
@@ -82,7 +82,7 @@ Wren smiles at you. "If you've got teeth," <<he>> says. "I have some goodies fro
 	Poster of a sexy lady: 50 teeth
 	<br>
 	<<if $prison.teeth gte 50>>
-		<<link [[Buy|Prison Wren Poster]]>><<prison_teeth -50>><<set $prison.poster to "woman">><</link>><<if $prison.poster>> <i>Will replace existing poster.</i><</if>>
+		<<link [[Buy|Prison Wren Poster]]>><<set $poster_choice to "woman">><<set $phase to 0>><</link>>
 	<<else>>
 		<span class="blue">You need more teeth.</span>
 	<</if>>
@@ -92,7 +92,7 @@ Wren smiles at you. "If you've got teeth," <<he>> says. "I have some goodies fro
 	Poster of a cute puppy: 50 teeth
 	<br>
 	<<if $prison.teeth gte 50>>
-		<<link [[Buy|Prison Wren Poster]]>><<prison_teeth -50>><<set $prison.poster to "puppy">><</link>><<if $prison.poster>><i> Will replace existing poster.</i><</if>>
+		<<link [[Buy|Prison Wren Poster]]>><<set $poster_choice to "puppy">><<set $phase to 0>><</link>>
 	<<else>>
 		<span class="blue">You need more teeth.</span>
 	<</if>>
@@ -312,14 +312,31 @@ Wren hands you a small hammer, barely the size of your thumb. "Hope you weren't
 :: Prison Wren Poster
 <<effects>>
 
-"I'll have it put up in your cell," Wren says. "Free of charge."
-<br><br>
+<<if $prison.poster and $phase isnot 1>>
+	"I'll be taking the old one back," <<he>> says. "Consider it a favour. Too much garnish attracts the gawkers."
+	<br><br>
 
-<span class="gold">You now have a poster on your cell wall.</span>
-<br><br>
+	<<He>> rolls the teeth in <<his>> palm. "You still in?"
+	<br><br>
 
-<<link [[Next|Prison Yard]]>><<endevent>><</link>>
-<br>
+	<<link [[Replace your poster|Prison Wren Poster]]>><<set $phase to 1>><</link>>
+	<br>
+	<<link [[Nevermind|Prison Wren]]>><<unset $poster_choice>><</link>>
+	<br>
+<<else>>
+	"I'll have it put up in your cell," Wren says. "Free of charge."
+	<br><br>
+
+	<<if $phase is 1>>
+		<span class="gold">The poster on your cell wall has been replaced.</span>
+	<<else>>
+		<span class="gold">You now have a poster on your cell wall.</span>
+	<</if>>
+	<br><br>
+
+	<<link [[Next|Prison Yard]]>><<prison_teeth -50>><<set $prison.poster to $poster_choice>><<unset $poster_choice>><<endevent>><</link>>
+	<br>
+<</if>>
 
 :: Prison Wren Ask
 <<effects>>
diff --git a/game/overworld-town/loc-pub/main.twee b/game/overworld-town/loc-pub/main.twee
index 2e778283c7..28be3098ab 100644
--- a/game/overworld-town/loc-pub/main.twee
+++ b/game/overworld-town/loc-pub/main.twee
@@ -34,84 +34,112 @@
 <</widget>>
 
 :: Pub
-
 <<set $outside to 0>><<set $location to "pub">><<effects>><<set $bus to "harvest">>
-<<if $pubbooze is "herbal">>
-	<<set $pubbooze to 0>>
-	The bartender pours a glass of a locally produced spirit. The pub seems more colourful after drinking it.
-<<elseif $pubbooze is "booze">>
-	<<set $pubbooze to 0>>
-	The bartender pours a glass of a cheap and popular beverage.
-<<else>>
-	You enter the pub. It's busy as always.
-<</if>>
-<<if $arousal gte $arousalmax>>
-	<<orgasmLocation "pub">>
-<</if>>
-<br><br>
-<<if $averyPub is 1 and ($daystate is "day" or $daystate is "dusk")>>
-	<<npc Avery>><<person1>>
-	<<loadNPC 1 avery_sidepiece>><<person2>>
-	You try to remain inconspicuous, looking for Avery. You quickly spot the <<person>> and Avery at the bar, having an animated chat.
-	You now recognise that the <span class="red"><<person>> is from the orphanage.</span>
-	<br><br>
-	Avery leans in and places a hand on <<his>> thigh, causing <<him>> to tense up. The <<person>> stands up suddenly, and excuses <<himself>> to the restrooms.
+
+<<if $exposed gte 1>>
+	You are hiding in a trolley to conceal your <<lewdness>>. Everyone's too busy or intoxicated to notice you.
 	<br><br>
-	<<link [[Go to the restrooms|Avery Dismissal Restroom]]>><</link>>
-	<br>
-	<<link [[Go to the bar|Avery Dismissal Bar]]>><</link>>
+
+	<<link [[Look for something to cover with|Pub Exposed]]>><</link>>
 	<br>
-<<elseif $pubwhore gte 10 and $pubattack isnot 1>>
-	<<set $pubattack to 1>>
-	<span class="red">A black sack is thrown over your head</span> and two pairs of arms grab you from behind. They drag you out of the pub and into a waiting van.
-	<br><br>
-	<<link [[Next|Brothel Punishment]]>><</link>>
+	<<link [[Sneak out the back|Industrial alleyways]]>><</link>>
 	<br>
-<<elseif $pubwhore gte 20>>
-	<<set $pubwhore to 10>>
-	<<generate1>><<generate2>><<person1>> A <<person>> shoves you against the wall. A <<person2>><<person>> stands beside <<person1>><<him>>. The pub staff and clientele look away. "<span class="red">Boss sent us,</span>" the <<person1>><<person>> says. "Says you've been naughty. We're gonna bring you in." <<He>> glances at the bar. "And don't try nothing. No one's gonna help you."
+<<else>>
+	<<if $pubbooze is "herbal">>
+		<<set $pubbooze to 0>>
+		The bartender pours a glass of a locally produced spirit. The pub seems more colourful after drinking it.
+	<<elseif $pubbooze is "booze">>
+		<<set $pubbooze to 0>>
+		The bartender pours a glass of a cheap and popular beverage.
+	<<else>>
+		You enter the pub. It's busy as always.
+	<</if>>
+	<<if $arousal gte $arousalmax>>
+		<<orgasmLocation "pub">>
+	<</if>>
 	<br><br>
-	<<if $money gte 50000>>
-		<<link [[Bribe (£500)|Pub Accost]]>><<set $phase to 0>><</link>>
+	<<if $averyPub is 1 and ($daystate is "day" or $daystate is "dusk")>>
+		<<npc Avery>><<person1>>
+		<<loadNPC 1 avery_sidepiece>><<person2>>
+		You try to remain inconspicuous, looking for Avery. You quickly spot the <<person>> and Avery at the bar, having an animated chat.
+		You now recognise that the <span class="red"><<person>> is from the orphanage.</span>
+		<br><br>
+		Avery leans in and places a hand on <<his>> thigh, causing <<him>> to tense up. The <<person>> stands up suddenly, and excuses <<himself>> to the restrooms.
+		<br><br>
+		<<link [[Go to the restrooms|Avery Dismissal Restroom]]>><</link>>
 		<br>
-	<</if>>
-	<<link [[Fight|Pub Accost Fight]]>><<set $fightstart to 1>><</link>>
-	<br>
-	<<link [[Go with them|Pub Accost]]>><<set $phase to 1>><</link>>
-	<br>
-<<else>>
-	<<ind>><<link [[Ask for Landry|Pub Landry]]>><<endevent>><</link>>
-	<br>
-	<<if $sexStats.vagina.pregnancy.awareOf is true>>
-		You can't bring yourself to drink while you know you're with child.
+		<<link [[Go to the bar|Avery Dismissal Bar]]>><</link>>
 		<br>
-	<<else>>
-		<<if $money gte 1000>>
-			<<beericon>><<link [[Drink booze (£10 0:05)|Pub]]>><<endevent>><<set $money -= 1000>><<set $pubbooze to "booze">><<alcohol 120>><<pass 5>><</link>><<ggalcohol>>
+	<<elseif $pubwhore gte 10 and $pubattack isnot 1>>
+		<<set $pubattack to 1>>
+		<span class="red">A black sack is thrown over your head</span> and two pairs of arms grab you from behind. They drag you out of the pub and into a waiting van.
+		<br><br>
+		<<link [[Next|Brothel Punishment]]>><</link>>
+		<br>
+	<<elseif $pubwhore gte 20>>
+		<<set $pubwhore to 10>>
+		<<generate1>><<generate2>><<person1>> A <<person>> shoves you against the wall. A <<person2>><<person>> stands beside <<person1>><<him>>. The pub staff and clientele look away. "<span class="red">Boss sent us,</span>" the <<person1>><<person>> says. "Says you've been naughty. We're gonna bring you in." <<He>> glances at the bar. "And don't try nothing. No one's gonna help you."
+		<br><br>
+		<<if $money gte 50000>>
+			<<link [[Bribe (£500)|Pub Accost]]>><<set $phase to 0>><</link>>
 			<br>
 		<</if>>
-		<<if $money gte 2000>>
-			<<ind>><<link [[Drink herbal booze (£20 0:05)|Pub]]>><<endevent>><<set $money -= 2000>><<set $pubbooze to "herbal">><<pass 5>><<alcohol 60>><<hallucinogen 20>><</link>><<galcohol>><<ghallucinogens>>
+		<<link [[Fight|Pub Accost Fight]]>><<set $fightstart to 1>><</link>>
+		<br>
+		<<link [[Go with them|Pub Accost]]>><<set $phase to 1>><</link>>
+		<br>
+	<<else>>
+		<<ind>><<link [[Ask for Landry|Pub Landry]]>><<endevent>><</link>>
+		<br>
+		<<if $sexStats.vagina.pregnancy.awareOf is true>>
+			You can't bring yourself to drink while you know you're with child.
 			<br>
+		<<else>>
+			<<if $money gte 1000>>
+				<<beericon>><<link [[Drink booze (£10 0:05)|Pub]]>><<endevent>><<set $money -= 1000>><<set $pubbooze to "booze">><<alcohol 120>><<pass 5>><</link>><<ggalcohol>>
+				<br>
+			<</if>>
+			<<if $money gte 2000>>
+				<<ind>><<link [[Drink herbal booze (£20 0:05)|Pub]]>><<endevent>><<set $money -= 2000>><<set $pubbooze to "herbal">><<pass 5>><<alcohol 60>><<hallucinogen 20>><</link>><<galcohol>><<ghallucinogens>>
+				<br>
+			<</if>>
 		<</if>>
-	<</if>>
-	<<if $farm>>
-		<<if $farm.tower gte 1 and !$farm.tower_guard>>
-			<<ind>><<link [[Look for a guard for your farm (0:30)|Pub Guard]]>><<endevent>><<pass 30>><</link>>
+		<<if $farm>>
+			<<if $farm.tower gte 1 and !$farm.tower_guard>>
+				<<ind>><<link [[Look for a guard for your farm (0:30)|Pub Guard]]>><<endevent>><<pass 30>><</link>>
+				<br>
+			<</if>>
+		<</if>>
+		<br>
+		<<generate1>><<person1>>You see a <<person>> sitting alone.
+		<br>
+		<<link [[Flirt (0:05)|Pub Flirt]]>><<pass 5>><<set $pubdrink to 0>><</link>><<promiscuous1>>
+		<br>
+		<<link [[Look for someone else (0:01)|Pub]]>><<endevent>><<pass 1>><</link>>
+		<br>
+
+		<<if $weekday is 1 and $hour gte 21 and ["active", "rescued"].includes($NPCName[$NPCNameList.indexOf("Whitney")].state) and $pillory_tenant.special.name isnot "Whitney">>
+			<br>
+			Some delinquents occupy a table, drowning the room in revelry.
+			<<if $whitneyPub>>
+				<span class="purple">You shouldn't provoke them further.</span>
+			<<else>>
+				You spot Whitney among them.
+				<<if $NPCName[$NPCNameList.indexOf("Whitney")].love gte 10>>
+					<span class="teal"><<nnpc_He "Whitney">> eyes you from <<nnpc_his "Whitney">> seat.</span>
+				<<else>>
+					<span class="blue">If <<nnpc_he "Whitney">> notices you, <<nnpc_he "Whitney">> doesn't show it.</span>
+				<</if>>
+				<br>
+				<<link [[Approach|Whitney Pub Approach]]>><<endevent>><<set $whitneyPub to 1>><<set $phase to 0>><</link>>
+			<</if>>
 			<br>
 		<</if>>
-	<</if>>
-	<br>
-	<<generate1>><<person1>>You see a <<person>> sitting alone.
-	<br>
-	<<link [[Flirt (0:05)|Pub Flirt]]>><<pass 5>><<set $pubdrink to 0>><</link>><<promiscuous1>>
-	<br>
-	<<link [[Look for someone else (0:01)|Pub]]>><<endevent>><<pass 1>><</link>>
-	<br>
 
-	<br><br>
-	<<link [[Leave|Harvest Street]]>><<endevent>><</link>>
-	<br>
+		<br><br>
+		<<link [[Leave|Harvest Street]]>><<endevent>><</link>>
+		<br>
+	<</if>>
 <</if>>
 
 :: Pub Intro
@@ -451,4 +479,173 @@ You ask the landlord if <<he>> knows anyone in need of work. <<He>> nods at a <<
 <<earnFeat "To Watch the Fields">>
 
 <<link [[Next|Pub]]>><<endevent>><</link>>
-<br>
\ No newline at end of file
+<br>
+
+:: Pub Exposed
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+<<generate1>><<person1>>
+
+You scan the room for anything you can cover up with.
+<br><br>
+
+<<switch random(1, 3)>>
+	<<case 3>>
+		Your efforts are cut short by an approaching <<person>>. You pull your head back in as <<he>> loads the trolley with dirty dishes. Miraculously, <<he>> doesn't notice you.
+		<br><br>
+
+		A bundle of cleaning rags land in your lap. They smell of whiskey, but they're better than nothing. You wrap them around your body and sneak to safety.
+		<<towelup>>
+		<br><br>
+
+		<<link [[Next|Pub]]>><<endevent>><</link>>
+		<br>
+	<<case 2>>
+		Before you can make a move, the trolley rattles into motion. You quickly duck back inside.
+		<br><br>
+
+		Cautiously, you poke your head out as you roll past the bar. A sweater sits abandoned on a barstool. You can't tell if the owner's nearby.
+		<br><br>
+
+		<<set $skulduggerydifficulty to 600>>
+		<<link [[Swipe it|Pub Exposed Sweater]]>><</link>><<skulduggerydifficulty>>
+		<br>
+		<<link [[Leave it|Pub Exposed Kitchen]]>><</link>>
+		<br>
+	<<case 1>>
+		By the bar, a <<person>> folds a stack of towels, until <<hes>> called away. The towels are left unguarded.
+		<br><br>
+
+		<<link [[Go for the towels|Pub Exposed Bar]]>><<endevent>><</link>>
+		<br>
+		<<link [[Keeping looking|Pub Exposed No Towels]]>><</link>>
+		<br>
+<</switch>>
+
+:: Pub Exposed Kitchen
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+The pub's din fades as you're pushed along. The squeak of the trolley is joined by shuffling feet and clattering plates. You must be in the kitchen.
+<br><br>
+
+Suddenly, <span class="pink">the cloth covering your trolley lifts up.</span> You come face-to-face with a <<person>>. <<He>> shrieks.<<stress 12>><<ggstress>>
+<br><br>
+
+Panicked, you escape through the back. The <<person>> hurls obscenities after you, but doesn't give chase.
+<br><br>
+
+<<link [[Next|Industrial alleyways]]>><<endevent>><</link>>
+<br>
+
+:: Pub Exposed Sweater
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You wait until you're just inches away, then reach for the sweater.
+<<silently>><<skulduggerycheck>><</silently>>
+<<if $skulduggerysuccess is 1>>
+	<span class="green">Nobody stops you.</span> You whisk it into the trolley, get dressed, and sneak out before anyone notices.
+	<<if $pronoun is "f">>
+		<<upperwear 29>>
+	<<else>>
+		<<upperwear 24>>
+	<</if>>
+	<br><br>
+
+	<<skulduggeryuse>>
+
+	<<link [[Next|Pub]]>><<endevent>><</link>>
+<<else>>
+	Just as your fingers brush the fabric, <span class="red">someone snatches your wrist.</span> You're pulled from your hiding spot by a <<person>>. "You little sneak," <<he>> snarls. "What do you think you-"
+	<br><br>
+
+	Shock replaces <<his>> anger when <<he>> sees your <<lewdness>>. <<His>> grip loosens enough for you to break free. You flee the pub in a panic.<<trauma 6>><<stress 6>><<gtrauma>><<gstress>>
+	<br><br>
+
+	<<skulduggeryuse>>
+
+	<<link [[Next|Harvest Street]]>><<endevent>><</link>>
+	<br>
+<</if>>
+
+:: Pub Exposed Bar
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+<<generate1>><<generate2>>
+
+You keep low and make your way to the bar. Just as the towels are within reach, a mug slams down overhead, startling you.
+<br><br>
+
+"You, <<girl>>," calls a voice. You peek over the bar to find a <<person1>><<person>> and <<person2>><<person>>. They slide their empty glasses to you. "How about a refill?"
+<br><br>
+
+They can't tell you're exposed from behind the bar, but you'll look suspicious if you refuse.
+<br><br>
+
+<<link [[Serve them|Pub Exposed Bar Serve]]>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>>
+<br>
+<<link [[Refuse|Pub Exposed Bar Refuse]]>><</link>><<difficulty 50>>
+<br>
+
+:: Pub Exposed Bar Serve
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $player.gender_appearance is "f" and $worn.upper.exposed gte 2 and $worn.under_upper.exposed gte 1>>
+	You top off a tray of drinks, holding it to your chest as you make your way over. The froth ought to hide your <<breasts>>. You hope.
+<<else>>
+	You top off a tray of drinks and hold it low, just above your <<genitals>>, as you make your way over.
+<</if>>
+<br><br>
+
+They grab a pair of glasses and empty them before you even have a chance to escape. You're forced to stand still and watch them down glass after glass. One clumsy grab could spell disaster.
+<<if $player.gender_appearance is "f" and $worn.upper.exposed gte 2 and $worn.under_upper.exposed gte 1>>
+	Even worse, at the rate they're going, you're losing cover rapidly.
+<</if>>
+<br><br>
+
+Three drinks in, the <<person>> excuses <<himself>> to use the restroom. Seizing the distraction, you snatch the towels and slip away from the bar.
+<<towelup>>
+<br><br>
+
+<<link [[Next|Pub]]>><<endevent>><</link>>
+<br>
+
+:: Pub Exposed Bar Refuse
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You crouch low behind the bar.
+<<if $submissive gte 1150>>
+	"S-sorry," you say. "I'm a bit busy."
+<<elseif $submissive lte 850>>
+	"I'm on break," you lie. "Piss off."
+<<else>>
+	"I can't," you say. "Ask someone else."
+<</if>>
+<br><br>
+
+<<if random(1)>>
+	There's a pause. Then, <span class="green">the <<person>> sighs.</span> "Gonna have a talk with <<pher>> boss," <<he>> mutters.
+	<br><br>
+
+	Up above, you hear chairs creak as the pair depart. You're free to snatch the towels and slip away.
+	<<towelup>>
+	<br><br>
+
+	<<link [[Next|Pub]]>><<endevent>><</link>>
+	<br>
+<<else>>
+	"You what?" the <<person>> scoffs. <span class="red">The bar creaks above you as <<he>> leans over.</span> "Who do you think you're-"
+	<br><br>
+
+	A gasp cuts <<him>> off. "<<pShes>>-" <<he>> stammers. "<<pShes>> naked!" You can't tell if <<hes>> appalled or excited. You don't stick around to find out. Cheers chase after you as you flee onto the street.<<trauma 6>><<stress 6>><<gtrauma>><<gstress>>
+	<br><br>
+
+	<<link [[Next|Harvest Street]]>><<endevent>><</link>>
+	<br>
+<</if>>
+
+:: Pub Exposed No Towels
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You continue your scan over the room. Before you can find anything suitable, <span class="purple">the trolley rattles into motion.</span> You wrench your head back under the cover.
+<br><br>
+
+<<link [[Next|Pub Exposed Kitchen]]>><</link>>
+<br>
diff --git a/game/overworld-town/loc-shop/main.twee b/game/overworld-town/loc-shop/main.twee
index 33515d4875..065368a3c3 100644
--- a/game/overworld-town/loc-shop/main.twee
+++ b/game/overworld-town/loc-shop/main.twee
@@ -473,7 +473,7 @@ Their bodies shudder in unison as they reach orgasm.
 				<br><br>
 			<<else>>
 				<<trauma 9>>
-				Your face aflame with embarrassment, you run into the women's restroom.
+				Your face aflame with embarrassment, you run into the restroom.
 				<br><br>
 			<</if>>
 		<<elseif $exposed gte 1>>
@@ -486,7 +486,7 @@ Their bodies shudder in unison as they reach orgasm.
 				<br><br>
 			<<else>>
 				<<trauma 9>>
-				Your face aflame with embarrassment, you run into the women's restroom.
+				Your face aflame with embarrassment, you run into the restroom.
 				<<gtrauma>><<gstress>><<trauma 6>><<stress 6>>
 				<br><br>
 			<</if>>
@@ -765,9 +765,9 @@ You buy several tubes of wrapping paper. That should cover everything. You can w
 You walk between shops, looking for something Robin would like. You find a few items you think would work.
 <br><br>
 <<if $money gte 1500>>
-	<<link [[Shirt and shorts (Sensible £15)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "shirt_unwrapped">><<set $money -= 1500>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "f">><i>Robin might need some convincing to wear this.</i><</if>>
+	<<link [[Shirt and shorts (Sensible £15)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "shirt_unwrapped">><<set $money -= 1500>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "f">><<note "Robin might need some convincing to wear this." "italic">><</if>>
 	<br>
-	<<link [[Sundress (Sensible £15)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "sundress_unwrapped">><<set $money -= 1500>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "m">><i>Robin might need some convincing to wear this.</i><</if>>
+	<<link [[Sundress (Sensible £15)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "sundress_unwrapped">><<set $money -= 1500>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "m">><<note "Robin might need some convincing to wear this." "italic">><</if>>
 	<br>
 	<<if $money gte 14000>>
 		<<link [[Kimono (Exotic £140)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "kimono_unwrapped">><<set $money -= 14000>><</link>>
@@ -776,13 +776,13 @@ You walk between shops, looking for something Robin would like. You find a few i
 		<<set _moreExotic to true>>
 	<</if>>
 	<<if $money gte 42000>>
-		<<link [[Tuxedo set (Exotic £420)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "tuxedo_set_unwrapped">><<set $money -= 42000>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "f">><i>Robin might need some convincing to wear this.</i><</if>>
+		<<link [[Tuxedo set (Exotic £420)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "tuxedo_set_unwrapped">><<set $money -= 42000>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "f">><<note "Robin might need some convincing to wear this." "italic">><</if>>
 		<br>
 	<<else>>
 		<<set _moreExotic to true>>
 	<</if>>
 	<<if $money gte 42000>>
-		<<link [[Gothic gown (Exotic £420)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "gothic_gown_unwrapped">><<set $money -= 42000>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "m">><i>Robin might need some convincing to wear this.</i><</if>>
+		<<link [[Gothic gown (Exotic £420)|Shop Robin Christmas]]>><<set $christmas_gift_robin to "gothic_gown_unwrapped">><<set $money -= 42000>><</link>> <<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is "m">><<note "Robin might need some convincing to wear this." "italic">><</if>>
 		<br>
 	<<else>>
 		<<set _moreExotic to true>>
@@ -861,10 +861,10 @@ You buy the kimono. You think Robin will like it. <<if $christmas_wrap is undefi
 <br>
 
 :: Shopping Centre Restroom
-You are alone in the women's restroom.
+You are alone in the restroom.
 <br><br>
 <<towelup>>
-You find some towels. They make a poor substitute for actual clothing but it'll keep you covered. You need to find something more solid as soon as you can.
+You find some towels. They make a poor substitute for actual clothing, but they'll keep you covered. You need to find something more solid as soon as you can.
 <br><br>
 
 <<link [[Leave through main door|Shopping Centre]]>><</link>>
diff --git a/game/overworld-town/special-avery/main.twee b/game/overworld-town/special-avery/main.twee
index 69596a6119..43ef5e78ba 100644
--- a/game/overworld-town/special-avery/main.twee
+++ b/game/overworld-town/special-avery/main.twee
@@ -573,6 +573,10 @@ The interior is spacious, just as fancy as the rest of the hotel. It's less a ro
 :: Avery Hotel Strip
 <<effects>><<pass 5>>
 <<strip>>
+<<if !$worn.genitals.type.includes("chastity")>>
+	<<set $genderknown.pushUnique("Avery")>>
+<</if>>
+
 You stand and remove your clothing, making sure to hang it up neat in the suite's wardrobe. There's a set of lingerie folded there already. It looks like your size. <<stress 6>><<gstress>>
 <br><br>
 
@@ -888,6 +892,10 @@ Avery takes a good look at you before stripping nude. You can already see <<his>
 	Avery takes a good look at you before stripping nude <<himself>>. You can already see <<his>> excitement, and <<he>> seems pleased with your enthusiasm.
 <<else>>
 	<<strip>><<water>>
+	<<if !$worn.genitals.type.includes("chastity")>>
+		<<set $genderknown.pushUnique("Avery")>>
+	<</if>>
+
 	You remove all of your clothing, and you shiver feeling the evening air's chill. <<exhibitionism3>>
 	Avery takes a good look at you before stripping nude <<himself>>. You can already see <<his>> excitement.
 <</if>>
@@ -1942,6 +1950,9 @@ The couple finish to uproarious applause. It's your turn. You and Avery take eac
 			<<integritycheck>><<exposure>>
 			With a sickening tearing sound, your clothes rip free from your body, remaining in the <<persons>> grasp.
 				<<if $worn.under_lower.type.includes("naked")>>
+					<<if !$worn.genitals.type.includes("chastity")>>
+						<<set $genderknown.pushUnique("Avery")>>
+					<</if>>
 					You're left naked from the waist down, in the middle of the room, your <<genitals>> and <<bottom>> the centre of attention. <<covered>>
 					<br><br>
 					<<fameexhibitionism 30>>
@@ -2782,6 +2793,10 @@ Holding you down to the seat by the hair, <<he>> drives to a secluded spot near
 <<effects>>
 <<set $money += (($NPCName[$NPCNameList.indexOf("Avery")].love * 10 + $endear * 10 + 10) * 100)>>
 <<strip>>
+<<if !$worn.genitals.type.includes("chastity")>>
+	<<set $genderknown.pushUnique("Avery")>>
+<</if>>
+
 It's awkward in the confines of the car, but you remove your clothing until you're sat naked beside Avery. <<covered>> <<He>> stares at you for a long moment, then hands you the cash. "I'll be in touch, <<pcpetname "Avery">>," <<he>> says.
 <br><br>
 <<He>> watches you dress and exit the car. <<He>> lingers a moment longer before driving away.
diff --git a/game/overworld-town/special-robin/main.twee b/game/overworld-town/special-robin/main.twee
index 7a41b33c26..af7ee840de 100644
--- a/game/overworld-town/special-robin/main.twee
+++ b/game/overworld-town/special-robin/main.twee
@@ -1413,7 +1413,7 @@ You put the cash on the desk. Bailey snatches it, and reclines in <<his>> chair
 The owl peers down at you. It's gotten a bit scruffy, likely due to some rough play with the orphans. Or Bailey.
 <br><br>
 
-<<link [[Take it back|Bailey's Office Owl Take]]>><</link>><<furnitureWarning "decoration">>
+<<link [[Take it back|Bailey's Office Owl Take]]>><<set $kylar_camera to 2>><</link>><<furnitureWarning "decoration">>
 <br>
 <<link [[Leave it|Bailey's Office]]>><</link>>
 <br>
diff --git a/game/overworld-town/special-sydney/walk.twee b/game/overworld-town/special-sydney/walk.twee
index 98dc9a2508..41b8519de2 100644
--- a/game/overworld-town/special-sydney/walk.twee
+++ b/game/overworld-town/special-sydney/walk.twee
@@ -742,7 +742,7 @@ You approach the shelves of folded up swimwear. You can't help but think that so
 		<br>
 	<</if>>
 	<<if $sydney.swim isnot "crossdress" and $money gte 4000>>
-		<<link [[Buy bikini (£40)|Sydney Buy Swim]]>><<set $select to "crossdress">><</link>><<llspurity>> <i>Sydney might need some convincing to wear this.</i>
+		<<link [[Buy bikini (£40)|Sydney Buy Swim]]>><<set $select to "crossdress">><</link>><<llspurity>> <<note "Sydney might need some convincing to wear this." "italic">>
 		<br>
 	<</if>>
 <<else>>
@@ -759,7 +759,7 @@ You approach the shelves of folded up swimwear. You can't help but think that so
 		<br>
 	<</if>>
 	<<if $sydney.swim isnot "crossdress" and $money gte 3500>>
-		<<link [[Buy board shorts (£35)|Sydney Buy Swim]]>><<set $select to "crossdress">><</link>><<llspurity>> <i>Sydney might need some convincing to wear this.</i>
+		<<link [[Buy board shorts (£35)|Sydney Buy Swim]]>><<set $select to "crossdress">><</link>><<llspurity>> <<note "Sydney might need some convincing to wear this." "italic">>
 		<br>
 	<</if>>
 <</if>>
diff --git a/game/overworld-town/special-whitney/main.twee b/game/overworld-town/special-whitney/main.twee
index 4cf00e0fad..bb7a99481b 100644
--- a/game/overworld-town/special-whitney/main.twee
+++ b/game/overworld-town/special-whitney/main.twee
@@ -2009,46 +2009,9 @@ You shake your head. <<He>> reaches forward and grabs your shoulders before pull
 <<ejaculation>><<npcincr Whitney lust -20>>
 
 The audience applauds. Whitney gasps and climbs off you.
+
 <<if $orgasmcurrent is 0 and !$worn.genitals.type.includes("chastity")>>
-	<<if $player.penisExist and $penisuse isnot 0>>
-		<<set $penisuse to 0>>
-	<</if>>
-	<<He>> pulls your head close and whispers. "Couldn't even fake it? You're embarrassing me in front of the crowd."
-	<<if !$genderknown.includes("Whitney") and ($player.gender is "h") or ($player.gender_appearance is "m" and $player.gender isnot "m") or ($player.gender_appearance is "f" and $player.gender isnot "f")>>
-		<<set $genderknown.pushUnique("Whitney")>>
-		<<His>> hand trails down, until it makes contact with your <<genitals>>. For a moment, <<he>> seems surprised by what <<he>> feels, but <<he>> smiles anyway.
-		<br><br>
-	<</if>>
-	<<He>> quickly grabs your <<genitals>> and
-	<<if $player.gender is "h">>
-		starts to jerk you off with one hand, plunging a finger from <<his>> other hand into your <<pussy>>.
-	<<elseif $player.penisExist>>
-		starts to jerk you off, paying extra attention to the tip of your <<penis>>.
-	<<else>>
-		plunges a finger into your <<pussy>>, swirling it around.
-	<</if>>
-	<<arousal 5000>>
-	<<if $arousal gte $arousalmax>>
-		<<orgasm>><<He>> smiles.
-	<<else>>
-		"I'll teach you to appreciate a good fuck."
-		<br><br>
-		<<He>> locks eyes with you, and the speed of <<his>> assault increases.
-		<<if $player.gender is "h">>
-			<<He>> uses <<his>> thumb to rub your tip in circles, while sliding a second finger into your <<pussy>>.
-		<<elseif $player.penisExist>>
-			<<He>> uses <<his>> thumb to rub your tip in circles<<if $NPCName[$NPCNameList.indexOf("Whitney")].dom gte 16 and $analdisable is "f">>, and slowly slides a finger into your <<bottom>>. <<He>> grins as <<he>> reaches your prostate<<else>>, giving your <<bottom>> a slap with <<his>> other hand<</if>>.
-		<<else>>
-			<<He>> plunges a second finger into your <<pussy>>, and uses <<his>> other hand to fondle your <<breasts>>.
-		<</if>>
-		<<He>> kisses you, muffling your involuntary moans.
-		<br><br>
-		<<set $arousal to 10000>>
-		<<if $arousal gte $arousalmax>>
-			<<orgasm>>
-		<</if>>
-	Whitney gives you a wicked smile, and the crowd cheers once again.
-	<</if>>
+	<<whitneyFinish>>
 <</if>>
 
 <<clotheson>>
@@ -4367,42 +4330,7 @@ Whitney brings you to your knees. "All I wanted was some fucking peace and quiet
 	<<ejaculation>><<npcincr Whitney lust -20>>
 
 	<<if $NPCName[$NPCNameList.indexOf("Whitney")].dom gte 10 and $orgasmcurrent is 0 and !$worn.genitals.type.includes("chastity")>>
-		"Don't think I wouldn't return the favour, slut."
-		<<if !$genderknown.includes("Whitney") and ($player.gender is "h") or ($player.gender_appearance is "m" and $player.gender isnot "m") or ($player.gender_appearance is "f" and $player.gender isnot "f")>>
-			<<set $genderknown.pushUnique("Whitney")>>
-			<<His>> hand trails down, until it makes contact with your <<genitals>>. For a moment, <<he>> seems surprised by what <<he>> feels, but <<he>> smiles anyway.
-			<br><br>
-		<</if>>
-		<<He>> quickly grabs your <<genitals>> and
-		<<if $player.gender is "h">>
-			starts to jerk you off with one hand, plunging a finger from <<his>> other hand into your <<pussy>>.
-		<<elseif $player.penisExist>>
-			starts to jerk you off, paying extra attention to the tip of your <<penis>>.
-		<<else>>
-			plunges a finger into your <<pussy>>, swirling it around.
-		<</if>>
-		<<arousal 5000>>
-		<<if $arousal gte $arousalmax>>
-			<<orgasm>><<He>> smiles.
-		<<else>>
-			"Can't have you leaving without a little gift."
-			<br><br>
-			<<He>> locks eyes with you, and the speed of <<his>> assault increases.
-			<<if $player.gender is "h">>
-				<<He>> uses <<his>> thumb to rub your tip in circles, while sliding a second finger into your <<pussy>>.
-			<<elseif $player.penisExist>>
-				<<He>> uses <<his>> thumb to rub your tip in circles<<if $NPCName[$NPCNameList.indexOf("Whitney")].dom gte 16 and $analdisable is "f">>, and slowly slides a finger into your <<bottom>>. <<He>> grins as <<he>> reaches your prostate<<else>>, giving your <<bottom>> a slap with <<his>> other hand<</if>>.
-			<<else>>
-				<<He>> plunges a second finger into your <<pussy>>, and uses <<his>> other hand to fondle your <<breasts>>.
-			<</if>>
-			<<He>> kisses you, muffling your involuntary moans. Someone on the far side of the park seems to notice you two, and they quickly turn away.
-			<br><br>
-			<<set $arousal to 10000>>
-			<<if $arousal gte $arousalmax>>
-				<<orgasm>>
-			<</if>>
-		Whitney gives you a wicked smile.
-		<</if>>
+		<<whitneyFinish>>
 	<</if>>
 
 	<<clotheson>>
@@ -4811,9 +4739,8 @@ and hastily flees the scene<<if $enemyno is 2>>, <<his>> friend trailing behind<
 		<<link [[Break down (0:05)|Whitney Rescue Break]]>><<pass 5>><<npcincr Whitney dom 3>><</link>><<ggdom>>
 		<br>
 	<</if>>
-	<<if $promiscuity gte 55>>
-		<<link [[Get on your knees|Whitney Rescue Sex]]>><<set $sexstart to 1>><<stress 6>><<npcincr Whitney dom 1>><</link>><<promiscuous4>><<gstress>><<gdom>>
-		<br>
+	<<link [[Get on your knees|Whitney Rescue Sex]]>><<set $sexstart to 1>><<stress 6>><<npcincr Whitney dom 1>><</link>><<promiscuous1>><<gstress>><<gdom>>
+	<br>
 	<</if>>
 	<<link [[Reward with a kiss|Whitney Rescue Kiss]]>><<npcincr Whitney dom 1>><<npcincr Whitney lust 5>><</link>><<promiscuous1>><<kissvirginitywarning>><<gdom>><<glust>>
 	<br>
@@ -4879,7 +4806,7 @@ Whitney pulls away from the kiss, finishing with a long, slow lick along your ne
 	"C'mon," <<he>> breathes in your ear. "You didn't really think that was gonna be enough, did you?" <<He>> places a hand atop your head, trying to force you to your knees.
 	<br><br>
 
-	<<link [[Go along with it|Whitney Rescue Sex]]>><<set $sexstart to 1>><<stress 6>><<npcincr Whitney dom 1>><</link>><<promiscuous4>><<gstress>><<gdom>>
+	<<link [[Go along with it|Whitney Rescue Sex]]>><<set $sexstart to 1>><<stress 6>><<npcincr Whitney dom 1>><</link>><<promiscuous1>><<gstress>><<gdom>>
 	<br>
 	<<link [[Comply grudgingly|Whitney Rescue Sex]]>><<set $molestationstart to 1>><<set $phase to 1>><<sub 1>><<trauma 6>><<stress 6>><<npcincr Whitney dom 1>><</link>><<gtrauma>><<gstress>><<gdom>>
 	<br>
@@ -5019,7 +4946,7 @@ Whitney drags you through the halls until you arrive at a locker. Passing <<peop
 			<br>
 		<</if>>
 		<<if $promiscuity gte 55>>
-			<<link [[Get on your knees|Whitney Rescue Sex]]>><<set $sexstart to 1>><<stress 6>><<npcincr Whitney dom 1>><</link>><<promiscuous4>><<gstress>><<gdom>>
+			<<link [[Get on your knees|Whitney Rescue Sex]]>><<set $sexstart to 1>><<stress 6>><<npcincr Whitney dom 1>><</link>><<promiscuous1>><<gstress>><<gdom>>
 			<br>
 		<</if>>
 		<<link [[Reward with a kiss|Whitney Rescue Kiss]]>><<npcincr Whitney dom 1>><<npcincr Whitney lust 5>><</link>><<promiscuous1>><<kissvirginitywarning>><<gdom>><<glust>>
@@ -5110,7 +5037,7 @@ Whitney drags you through the halls until you arrive at a locker. Passing <<peop
 	<<neutral 1>>
 
 	You drop to your knees. Whitney doesn't hesitate to take advantage, grabbing the back of your head and forcing it against <<his>> crotch.
-	<<promiscuity4>>
+	<<promiscuity1>>
 
 	<<maninit>>
 	<<silently>><<npcoral>><</silently>>
@@ -5617,3 +5544,831 @@ You shove Whitney away from you. One of <<his>> friends smirks, but shrinks at a
 
 <<link [[Next|Hallways]]>><<set $eventskip to 1>><</link>>
 <br>
+
+:: Whitney Pub Approach
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+<<npc Whitney>><<person1>>
+
+You approach the delinquents. They're noisier up close. Whitney leers at you,
+<<if $NPCName[$NPCNameList.indexOf("Whitney")].love gte 10>>
+	then grins. You're not given a chance to speak before <<he>> pulls you into the booth.
+	<br><br>
+
+	Once you're seated, <<he>> slings <<his>> arm over your shoulder. "Good timing, slut. We were just talking about you." <<His>> friends snicker.
+	<br><br>
+
+	Glasses clatter aside as <<he>> slides <<his>> beer to you. "Drink up," <<he>> says. "Let's see how much you can take."
+	<br><br>
+
+	<<link [[Drink (0:05)|Whitney Pub Drink]]>><<pass 5>><<stress -6>><<alcohol 120>><<npcincr Whitney love 1>><<npcincr Whitney dom 1>><</link>><<lstress>><<galcohol>><<glove>><<gdom>>
+	<br>
+	<<link [[Refuse|Whitney Pub Refuse]]>><<npcincr Whitney dom -1>><<set $phase to 0>><</link>><<ldom>>
+	<br>
+<<else>>
+	then whispers to <<his>> friends. They all smirk.
+	<br><br>
+
+	Before you can react, <<his>> goons lunge for you and grab your arms. Beer in hand, Whitney rises and <span class="red">pours the drink over your head.</span> <span class="lewd">It soaks through your clothes.</span>
+	<<water>><<stress 6>><<gstress>>
+	<br><br>
+
+	"Get lost, loser," <<he>> sneers. "We're trying to enjoy our evening. No one invited you."
+	<br><br>
+
+	<<tearful>> you flee, pursued by laughter.
+	<br><br>
+
+	<<link [[Next|Pub]]>><<endevent>><</link>>
+	<br>
+<</if>>
+
+:: Whitney Pub
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $arousal gte $arousalmax>>
+	The delinquents prattle on, but it's all muddled. <span class="lewd">A haze washes over you.</span>
+	<br><br>
+
+	<<if $whitneyPub gte 6>>
+		Whitney doesn't relent. <<He>> follows a torturous rhythm, grinding into your <<genitals>>, then easing up just enough to let the sensation swell. <<His>> fist clenches around your <<print $worn.lower.name>>, ready to finish you proper. Your body doesn't give <<him>> the chance.
+		<br>
+	<<elseif $whitneyPub gte 4>>
+		On cue,
+		<<if $phase is "penis">>
+			Whitney's hands dig into your thighs, pulling you hard against <<his>> <<print $NPCList[0].penisdesc>>. Desperate for release, your body forces you to take it. You impulsively rub your <<bottom>> against <<him>>, each thrust pushing you further towards the edge, until it's too much to bear.
+		<<else>>
+			Whitney leans forward, pressing <<his>> ass hard against your <<genitals>>. Desperate for release, your body succumbs to instinct. You impulsively hump <<his>> ass, <<his>> grinding pushing you further towards the edge, until it's too much to bear.
+		<</if>>
+		<br>
+	<<elseif $whitneyPub gte 2>>
+		On cue, Whitney's hand dives back to your <<genitals>>. One finger strokes up, slowly, then back down. It's a cry from <<his>> earlier handling. <<He>> doesn't bother slipping into your <<print $worn.lower.name>>. <<He>> doesn't need to.
+		<br>
+	<</if>>
+	<<orgasm>>
+
+	Your cries silence the table. The whole pub must've heard. Once it sinks in, the silence turns to laughter.
+	<<if $whitneyPub lte 1>>
+		Whitney's rings the loudest. "I didn't even touch <<phim>> yet!"
+	<<else>>
+		Whitney reclines with <<his>> beer.
+	<</if>>
+	<<gtrauma>><<gstress>><<trauma 6>><<stress 6>><<fameexhibitionism 10>>
+	<br><br>
+
+	<<link [[Next|Whitney Pub End]]>><</link>>
+	<br>
+<<else>>
+	<<switch $whitneyPub>>
+		<<case 6>>
+			Whitney's breath is sharp, audible over the din of the pub. You tense in anticipation of <<his>> next move. Before it can come, <span class="green"><<he>> stops,</span> scanning over the crowd.
+			<br><br>
+
+			"Fuck it," <<he>> mutters. "I'm not getting kicked out over a slut." <<He>> <<if $phase is "penis">>shoves you off <<his>> lap<<else>>slinks to your side<</if>>. "Finish your damn drink."
+			<br><br>
+
+			<<He>> snatches another shot to cover <<his>> fluster. If <<his>> friends notice, they make no mention of it.
+			<br><br>
+
+			<<link [[Next|Whitney Pub End]]>><</link>>
+			<br>
+		<<case 5>>
+			Heedless to <<his>> friends, <<he>> bucks <<his>> hips, <span class="lewd"><<if $phase is "penis" and !npcHasStrapon(0)>><<his>> <<print $NPCList[0].penisdesc>> erect against your crotch<<else>><<his>> skin hot against yours<</if>>.</span> <<Hes>> about as close to fucking you as <<he>> can get.
+			<br><br>
+
+			The others remain oblivious, even as Whitney pins you down by the shoulders and leans in close. <<His>> beer-tinged breath makes your skin crawl.
+			<br><br>
+
+			"One way or another," <<he>> growls, "you're getting smashed tonight."
+			<br><br>
+
+			<<if $promiscuity gte 75>>
+				<<if $player.penisExist and (!$player.vaginaExist or $penileskill gte $vaginalskill)>>
+					<<link [[Thrust|Whitney Pub Thrust]]>><<set $phase2 to "penis">><</link>><<skill_difficulty "$penileskill" "Penile Skill" 1 $drunk>><<note "Failure will increase arousal" "purple">>
+					<br>
+				<<else>>
+					<<link [[Thrust|Whitney Pub Thrust]]>><<set $phase2 to "pussy">><</link>><<skill_difficulty "$vaginalskill" "Vaginal Skill" 1 $drunk>><<note "Failure will increase arousal" "purple">>
+					<br>
+				<</if>>
+			<</if>>
+			<<link [[Resist|Whitney Pub Resist]]>><</link>><<willpowerdifficulty 1 $drunk>><<note "Failure will increase arousal" "purple">>
+			<br>
+			<<link [[Let it happen|Whitney Pub Let]]>><<arousal 7000>><<npcincr Whitney dom 1>><</link>><<gggarousal>><<gdom>>
+			<br>
+		<<case 4>>
+			<<generatey2>><<person2>>
+			Whitney whispers to the <<person>> at <<person1>><<his>> side. <<person2>><<He>> stumbles out of <<his>> seat and over to the bar.
+			<br><br>
+
+			<<if $phase is "penis">>
+				Grabbed by the rear, you're picked up and spun around. Whitney settles you back in <<person1>><<his>> lap, where you're greeted with a smirk.
+			<<else>>
+				Still sat in your lap, Whitney turns to face you. <<person1>><<He>> leans in close, pinning you against the booth.
+			<</if>>
+			"This one's gonna fuck you up," <<he>> says. "But you're used to that."
+			<br><br>
+
+			The <<person2>><<person>> returns with a tray of shots. Whitney takes one for you, and one for <<person1>><<himself>>. "Bottoms up."
+			<br><br>
+
+			<<link [[Drink (0:05)|Whitney Pub Drink]]>><<pass 5>><<stress -6>><<alcohol 240>><</link>><<lstress>><<galcohol>>
+			<br>
+			<<link [[That's enough|Whitney Pub Refuse]]>><<lcool>><<status -10>><<set $phase to 1>><</link>><<lcool>>
+			<br>
+		<<case 3>>
+			<<His>> hand smacks down on your thigh. Penned between bodies,
+			<<if $phase is "penis">>
+				you're helplessly whisked off your seat and onto <<his>> lap. <span class="lewd"><<His>> <<print $NPCList[0].penisdesc>> pokes your <<bottom>>.</span>
+				<br><br>
+
+				<<He>> yanks your hair back, bringing your ear to <<his>> lips.
+			<<else>>
+				you can only watch as <<he>> drops <<himself>> down on your lap. <span class="lewd"><<His>> butt presses against your <<genitals>>.</span>
+				<br><br>
+
+				<<He>> tilts <<his>> head back.
+			<</if>>
+			"Hope you're not out cold yet," <<he>> whispers. "I want you to feel this."
+			<br><br>
+
+			<<if $promiscuity gte 55>>
+				<<if $phase is "penis">>
+					<<link [[Rub back|Whitney Pub Rub]]>><<set $phase2 to "bottom">><</link>><<skill_difficulty "$bottomskill" "Bottom Skill" 1 $drunk>><<note "Failure will increase arousal" "purple">>
+					<br>
+				<<elseif $player.penisExist>>
+					<<link [[Rub back|Whitney Pub Rub]]>><<set $phase2 to "penile">><</link>><<skill_difficulty "$penileskill" "Penile Skill" 1 $drunk>><<note "Failure will increase arousal" "purple">>
+					<br>
+				<<else>>
+					<<link [[Rub back|Whitney Pub Rub]]>><<set $phase2 to "thigh">><</link>><<skill_difficulty "$thighskill" "Thigh Skill" 1 $drunk>><<note "Failure will increase arousal" "purple">>
+					<br>
+				<</if>>
+			<</if>>
+			<<link [[Resist|Whitney Pub Resist]]>><</link>><<willpowerdifficulty 1 $drunk>><<note "Failure will increase arousal" "purple">>
+			<br>
+			<<link [[Let it happen|Whitney Pub Let]]>><<arousal 5000>><<npcincr Whitney dom 1>><</link>><<ggarousal>><<gdom>>
+			<br>
+		<<case 2>>
+			Another glass clinks onto the table. This one's taller than the last. Whitney slides it in front of you.
+			<br><br>
+
+			"Go on," <<he>> snickers. "If it's bitter, I got something you can wash it down with."
+			<br><br>
+
+			<<link [[Drink (0:05)|Whitney Pub Drink]]>><<pass 5>><<stress -6>><<alcohol 180>><</link>><<lstress>><<galcohol>>
+			<br>
+			<<link [[That's enough|Whitney Pub Refuse]]>><<lcool>><<status -10>><<set $phase to 1>><</link>><<lcool>>
+			<br>
+		<<case 1>>
+			<<if $NPCList[0].penis isnot "none">>
+				<<set $phase to "penis">>
+			<<else>>
+				<<set $phase to "pussy">>
+			<</if>>
+
+			Something brushes your thigh. Whitney's hand works its way past your <<print $worn.lower.name>>, <span class="lewd">towards your <<genitals 1>>.</span> <<He>> flashes a smirk.
+			<br><br>
+
+			<<if $worn.genitals.type.includes("chastity")>>
+				When <<he>> reaches your <<print $worn.genitals.name>>, <<he>> stops. Some rough handling, and <<his>> confusion gives way to a low chuckle. "You're shitting me."
+				<br><br>
+
+				<<link [[Next|Whitney Pub Chastity]]>><</link>>
+				<br>
+			<<else>>
+				"You're lucky," <<he>> whispers. "Got in a fight here last week. Almost got booted out. Now I gotta mind my manners." <<He>> sinks <<his>> hand lower and flicks <<if $player.penisExist>>the tip of your cock<<else>>your clit<</if>>. "I'd <<if $phase is "penis">>bend you over<<else>>pin you down on<</if>> the table if I could. But I'll settle on making you squeal."
+				<br><br>
+
+				Warmth spreads at <<his>> touch, accelerated by the alcohol. You can't think straight. <i><span class="blue">The more intoxicated you are, the harder it'll be to control yourself.</span></i>
+				<br><br>
+
+				<<if $promiscuity gte 35>>
+					<<link [[Return the favour|Whitney Pub Hand]]>><</link>><<skill_difficulty "$handskill" "Hand Skill" 1 $drunk>><<note "Failure will increase arousal" "purple">>
+					<br>
+				<</if>>
+				<<link [[Resist|Whitney Pub Resist]]>><</link>><<willpowerdifficulty 1 $drunk>><<note "Failure will increase arousal" "purple">>
+				<br>
+				<<link [[Let it happen|Whitney Pub Let]]>><<arousal 3000>><<npcincr Whitney dom 1>><</link>><<garousal>><<gdom>>
+				<br>
+			<</if>>
+	<</switch>>
+	<<set $whitneyPub += 1>>
+<</if>>
+
+:: Whitney Pub Chastity
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You're forced out of your seat. Whitney's right behind you with a hand in your <<print $worn.lower.name>>. With <<his>> friends' eyes on you,
+<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
+	<<he>> flicks <<lowerit>> up,
+<<else>>
+	<<he>> pulls <<lowerit>> down to your ankles,
+<</if>>
+<span class="lewd">exposing your <<print $worn.genitals.name>></span>
+<br><br>
+
+Silence hangs over the table. Then, laughter. It rings through the whole pub. Someone across the room whistles. <<embarrassment>><<gtrauma>><<trauma 6>>
+<br><br>
+
+<<link [[Next|Whitney Pub Chastity 2]]>><</link>>
+<br>
+
+:: Whitney Pub Chastity 2
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You quickly cover up. Whitney slides back in <<his>> seat with a smirk.
+<br><br>
+
+"What'd you do to get your junk muzzled?" <<he>> says. "I'd best not indulge you. Wouldn't want you going feral." <<His>> friends snicker.
+<br><br>
+
+<<tearful>> you <<if $submissive gte 1150>>shuffle<<elseif $submissive lte 850>>stomp<<else>>walk<</if>> away. Aside from a few leers, no one harasses you further.
+<br><br>
+
+<<link [[Next|Pub]]>><<endevent>><</link>>
+<br>
+
+
+:: Whitney Pub Refuse
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $phase is 1>>
+	<<if $submissive gte 1150>>
+		"I-" you hiccup. "I can't handle any more."
+	<<elseif $submissive lte 850>>
+		"That'll do," you belch. "No more."
+	<<else>>
+		"That's enough for me," you slur.
+	<</if>>
+<<else>>
+	<<if $submissive gte 1150>>
+		You nudge the glass away. "I'm sorry," you say. "I'd rather not drink right now."
+	<<elseif $submissive lte 850>>
+		You wrinkle your nose. "I'm not drinking this shit."
+	<<else>>
+		You push the glass away. "Thanks, but I'm not thirsty."
+	<</if>>
+<</if>>
+<br><br>
+
+Whitney rolls <<his>> eyes. <<His>> friends are just as annoyed.
+<<if $phase is 1>>
+	"You're too easy to please."
+<<else>>
+	"What? Scared you won't be able to keep your whore legs closed after one drink?"
+<</if>>
+<<He>> nabs your drink and downs it in a gulp. "Stop wasting our time, loser. You're boring us."
+<br><br>
+
+<<if $whitneyPub gte 4>>
+	<<if $NPCList[0].penis isnot "none">>
+		<<He>> heaves you off <<his>> lap and out of the booth.
+	<<else>>
+		<<He>> bumps you with <<his>> hip, knocking you off your seat.
+	<</if>>
+<<else>>
+	<<He>> pulls <<his>> arm back and shoves you off the seat.
+<</if>>
+You land on your <<bottom>>.<<pain 2>><<gpain>>
+<br><br>
+
+<<link [[Next|Pub]]>><<endevent>><</link>>
+<br>
+
+:: Whitney Pub Drink
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $whitneyPub gte 5>>
+	All eyes are on you as you raise the glass to your lips. They're more interested in you than their own drinks. With a deep breath, you down it one go.
+	<br><br>
+
+	The shot's size belies its strength. Your throat burns, and you fight the urge to grimace. It's a struggle, but you manage to keep it down.
+	<br><br>
+
+	They all cheer as you set down the empty shot. All except Whitney.
+<<elseif $whitneyPub gte 3>>
+	You steel yourself and guzzle it down. The others murmur. They clearly weren't expecting you to last so long. Whitney slams <<his>> own glass down.
+	<br><br>
+
+	"Still thirsty?" <<he>> slurs, arm slinking to your waist. "Let me fix that."
+<<else>>
+	<<if $submissive gte 1150>>
+		You start with an experimental sip. The urge to spit it out is almost overwhelming. It takes you a lot longer than the others to finish your whole glass.
+	<<elseif $submissive lte 850>>
+		You knock your drink back as quickly as you can. Perhaps too quickly. You struggle to keep it down as Whitney and <<his>> friends finish theirs.
+	<<else>>
+		You cautiously sip your drink. It's strong, but you manage. You reach the bottom of the glass in time with the others.
+	<</if>>
+	<br><br>
+
+	Whitney watches you drink. Before you can set it down, <<he>> orders you a refill.
+<</if>>
+<br><br>
+
+<<link [[Next|Whitney Pub]]>><</link>>
+<br>
+
+:: Whitney Pub Let
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $whitneyPub gte 6>>
+	<<if $phase is "penis" and $player.vaginaExist>>
+		You rest your body against <<hers>> as <<he>> teases your <<pussy>>.
+		<<if $NPCList[0].penissize gte 4>>
+			With <<his>> size and savagery, not an inch of <<him>> is left to your imagination.
+		<<elseif $NPCList[0].penissize lte 1>>
+			What <<he>> lacks in size, <<he>> makes up for in sheer ferocity.
+		<<else>>
+			The thin layer of protection between you does little against <<his>> harsh motions.
+		<</if>>
+		It's a wonder <<he>> doesn't tear through your clothes to fuck you on the spot.
+	<<elseif $phase is "penis">>
+		You rest your body against <<hers>> as <<he>> frots your dicks together.
+		<<if $NPCList[0].penissize gte 4>>
+			<<His>> <<print $NPCList[0].penisdesc>> dominates yours. The shaft grinds up and down your crotch, and the tip jabs your belly.
+		<<elseif $NPCList[0].penissize lte 1>>
+			<<He>> compensates <<his>> lack of size with dexterity,
+			<<if playerHasStrapon()>>
+				pushing past your <<print $worn.under_lower.name>> and grinding <<his>> tip against your clit.
+			<<else>>
+				teasing <<his>> tip against your shaft with sharp thrusts.
+			<</if>>
+		<<else>>
+			<<He>> starts slow, rubbing up and down your shaft, until <<his>> arousal spurs <<him>> to quicken <<his>> pace.
+		<</if>>
+		With <<his>> hands firm on your <<bottom>>, you're forced to sit still and take it.
+	<<elseif $phase is "vagina" and $player.penisExist>>
+		You hold <<him>> steady as <<he>> teases your <<penis>>.
+		<<if $player.penissize gte 3>>
+			Even with your clothes in the way, <<he>> has no trouble pushing up against your shaft.
+		<<elseif $player.penissize lte 0>>
+			Struggling to find it beneath your <<print $worn.lower.name>>, <<he>> resorts to grinding <<his>> body into you.
+		<<else>>
+			<<He>> rides you through your <<print $worn.lower.name>>, just rough enough to make you squirm without drawing looks.
+		<</if>>
+		<<He>> slams <<his>> pelvis down, pressing your bodies tight every time you connect.
+		<<if $NPCList[0].breastsize gte 1>>
+			<<His>> <<print $NPCList[0].breastsdesc>> squish against you,
+		<<else>>
+			<<His>> chest crushes yours,
+		<</if>>
+		<<his>> nails pierce your shoulders, and <<his>> breath rings heavy in your ear. It threatens to send you both over the edge.
+	<<else>>
+		You hold <<him>> steady as <<he>> rubs your pussies together. Between <<his>> tipsiness and growing thirst, it's a struggle to keep <<him>> upright. <<He>> gropes all over, from your hips to your chest, just to avoid falling off your lap. <<He>> has no such trouble finding your clit beneath your <<print $worn.lower.name>>, smashing it into <<his>> crotch.
+	<</if>>
+	<br><br>
+
+	With each thrust, <<he>> puts more pressure on you. You're still through it all, save for Whitney's throttling and the odd, involuntary twitch.<<gggarousal>>
+<<elseif $whitneyPub gte 4>>
+	<<if $phase is "penis">>
+		You settle into Whitney's lap. With <<his>> <<print $NPCList[0].penisdesc>> between your cheeks, <<he>> begins to rub. You have to cover your mouth as the tip passes over your asshole.
+		<br><br>
+
+		By instinct, your body jerks against <<his>> probing. You're stopped when <<he>> seizes your <<bottom>> in both hands. "Sit that ass down," <<he>> snarls. <<He>> holds you down on <<his>> cock, groping in tandem with <<his>> grinding. You're not given an inch of reprieve.<<ggarousal>>
+	<<else>>
+		With a leer over <<his>> shoulder, Whitney rises from your lap, slow enough to stir your anticipation. <<He>> shakes <<his>> bottom, drops it back down, and grinds. From your position, all you can do is sit back and let your body succumb as <<he>> repeats <<his>> assault.
+		<br><br>
+
+		Sometimes <<his>> motions are quick and heavy. Sometimes they're painfully slow. Sometimes <<he>> doesn't move at all, content with the feeling of your <<genitals>> pressed beneath <<his>> ass. The only constant is the effect <<hes>> having on you.<<ggarousal>>
+	<</if>>
+<<else>>
+	You spread your legs in invitation.
+	<<if $player.penisExist and (!$player.vaginaExist or random(1))>>
+		An invitation <<he>> eagerly accepts, sliding <<his>> hand to your <<penis>>. <<He>> wraps tight around the shaft, takes <<his>> thumb to the tip, and rubs.
+	<<else>>
+		An invitation <<he>> eagerly accepts, sliding <<his>> hand to your <<pussy>>. <<He>> plunges <<his>> fingers in, takes <<his>> thumb to your clit, and rubs.
+	<</if>>
+	You lean back and bask in it.
+	<br><br>
+
+	A second order of drinks arrives, putting an end to Whitney's show. <<He>> pulls away with a wink. You're left trembling.<<garousal>>
+<</if>>
+<br><br>
+
+<<link [[Next|Whitney Pub]]>><</link>>
+<br>
+
+:: Whitney Pub Resist
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You try to tune out Whitney's molestation,
+<<if $willpowerSuccess>>
+	<span class="green">and succeed.</span>
+	<br><br>
+
+	<<if $whitneyPub gte 6>>
+		You slowly drift your crotch away from <<hers>>. Oblivious, <<he>> humps your leg. By the time <<he>> notices, <<hes>> too caught up in <<his>> own arousal to slow down.
+		<br><br>
+
+		<<He>> makes a sudden thrust at your <<genitals>>. You weave aside. Another thrust, another dodge. You keep this up until <<hes>> red in the face.<<npcincr Whitney lust 5>><<glust>>
+	<<elseif $whitneyPub gte 4>>
+		<<if $phase is "penis">>
+			You swivel your hips in time with <<hers>>, keeping your <<bottom>> just out of reach. <<He>> thrusts harder in retaliation, but <<he>> struggles to stay on-target, <<his>> <<print $NPCList[0].penisdesc>> angled away from your anus.
+		<<else>>
+			You hold fast against the pressure on your <<genitals>>, to Whitney's annoyance. <<He>> jerks <<himself>> back and forth across your leg, desperate for a reaction.
+		<</if>>
+		Judging by <<his>> laboured breaths, <<hes>> only managed to get <<himself>> off.<<npcincr Whitney lust 5>><<glust>>
+		<br><br>
+
+		Frustrated, <<he>> <<if $phase is "penis">>shoves you off <<his>> lap, onto <<his>> leg,<<else>>settles down on your leg<</if>> and huffs into <<his>> drink.
+	<<else>>
+		You swing one leg over the other and trap <<his>> hand beneath your thigh. <<He>> smirks, until <<he>> tries pulling away. <<He>> can't. Just as <<he>> reels back, you release <<him>>. <<He>> nearly keels over, to <<his>> friends' confusion.
+		<br><br>
+
+		<<He>> laughs it off as simple intoxication. The look in <<his>> eyes tells a different story.<<npcincr Whitney lust 5>><<glust>>
+	<</if>>
+<<else>>
+	<span class="red">but you can't focus.</span><<gwillpower>><<willpower 2>>
+	<br><br>
+
+	<<if $whitneyPub gte 6>>
+		You're so set on avoiding <<his>> <<print $phase>>, you fail to notice <<his>> hands on your hips. They pull you in and hold you down. Without the luxury of movement, you're forced to endure.<<arousal 7000>><<gggarousal>>
+		<br><br>
+
+		<<He>> grinds into your <<genitals>>, growing rougher by the second, all while you're powerless to resist. Not in your position. Not with the warmth overtaking your body. All you can do is sit still and take it.
+	<<elseif $whitneyPub gte 4>>
+		<<if $phase is "penis">>
+			<<He>> takes advantage of your immobility and pushes <<his>> <<print $NPCList[0].penisdesc>> closer to your anus. It's even more unbearable from this position. A fact <<he>> relishes in, if the snickering in your ear is any indication.
+			<br><br>
+
+			Relief finally comes as Whitney slides you down <<his>> leg, away from <<his>> <<print $NPCList[0].penisdesc>>, to finish <<his>> drink. <<He>> leaves a yearning feeling behind.<<arousal 5000>><<ggarousal>>
+		<<else>>
+			You thrust your hips in an effort to buck <<him>> off. <<He>> doesn't budge. You try again, and again.
+			<<if $player.penisExist and !playerHasStrapon()>>
+				Blood pulses through your <<penis>> as you inadvertently wedge yourself deeper between <<his>> ass.
+			<<else>>
+				With each thrust, the heat between your legs grows.
+			<</if>>
+			<<arousal 5000>><<ggarousal>>
+			<br><br>
+
+			<<He>> takes it with a smirk, no longer bothered to grind against you. You're doing plenty on your own. Face flushed, you give up and settle back in your seat. <<He>> doesn't push you further. For now.
+		<</if>>
+	<<else>>
+		In your effort to squirm away, your thigh shifts.
+		<<if $player.penisExist and (!$player.vaginaExist or random(1))>>
+			It gives <<him>> a straight shot to your <<penis>>. <<He>> wraps tight around the shaft, takes <<his>> thumb to the tip, and rubs.
+		<<else>>
+			It gives <<him>> a straight shot to your <<pussy>>. <<He>> plunges <<his>> fingers in, takes <<his>> thumb to your clit, and rubs.
+		<</if>>
+		Your struggles only amplify the sensation.
+		<br><br>
+
+		A second order of drinks arrives, putting an end to Whitney's show. <<He>> pulls away with a wink. You're left trembling.<<arousal 3000>><<garousal>>
+	<</if>>
+<</if>>
+<br><br>
+
+<<link [[Next|Whitney Pub]]>><</link>>
+<br>
+
+:: Whitney Pub Hand
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+You slip your hand into <<his>> <<npcClothesText $NPCList[0] "lower">>, where it finds <<his>> <<print $phase>>.
+<<promiscuity3>>
+
+Shock flashes in <<his>> eyes, but it quickly turns to lust. <<He>> smiles, mouths "you're on," and quickens <<his>> pace.
+<br><br>
+
+<<if $handskill gte random(1, $drunk)>>
+	<span class="green">You're able to keep up, and then some.</span>
+	<<if $player.penisExist and (!$player.vaginaExist or random(1))>>
+		<<His>> grip on your cock steadily weakens,
+	<<else>>
+		<<His>> fingering degrades to quivering,
+	<</if>>
+	until <<hes>> forced to retract <<his>> hand just to pry yours away. Satisfied, you let <<him>> finish <<his>> beer.<<npcincr Whitney lust 5>><<glust>>
+<<else>>
+	<<He>> <<if $player.penisExist and (!$player.vaginaExist or random(1))>>pumps your cock<<else>>fingers your pussy<</if>> with increasing vigour. <span class="red">It's enough to overwhelm you.</span> The stimulation and your inebriation combine to drive all thought from your mind.
+	<br><br>
+
+	A second order of drinks arrives, putting an end to Whitney's show. <<He>> pulls away with a wink. You're left trembling.<<arousal 3000>><<garousal>>
+<</if>>
+<br><br>
+
+<<link [[Next|Whitney Pub]]>><</link>>
+<br>
+
+:: Whitney Pub Rub
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $phase2 is "bottom">>
+	You push back, catching <<his>> cock with your <<bottom>> and matching <<his>> movement.
+	<<promiscuity4>>
+
+	You're not sure <<he>> can even feel it through <<his>> <<npcClothesText $NPCList[0] "lower">>.
+	<<if $bottomskill gte random(1, $drunk)>>
+		<span class="green">Until a moan slips out.</span> <<He>> hides it in <<his>> beer, but <<he>> still catches looks.
+		<br><br>
+
+		You give <<his>> <<print $NPCList[0].penisdesc>> a parting squeeze before sliding off <<his>> lap. To your surprise, <<he>> holds you in place, though a distance from <<his>> groin.<<npcincr Whitney lust 5>><<glust>>
+	<<else>>
+		<span class="red">But you can.</span> With <<his>> <<print $NPCList[0].penisdesc>> rubbing up against your anus, you only succeed in exposing yourself to <<his>> assault.
+		<br><br>
+
+		<<Hes>> quick to take advantage, probing your asshole through your <<print $worn.lower.name>>. With no room to move, you're forced to endure, until <<<he>> finally shoves you off with a smack.<<arousal 5000>><<ggarousal>>
+	<</if>>
+<<elseif $phase2 is "penile">>
+	As Whitney rises, you wedge your <<penis>> against <<his>> ass and begin to rub.
+	<<promiscuity4>>
+
+	You're not sure <<he>> can even feel it through <<his>> <<npcClothesText $NPCList[0] "lower">>.
+	<<if $penileskill gte random(1, $drunk)>>
+		<span class="green">Until a moan slips out.</span> <<He>> hides it in <<his>> beer, but <<he>> still catches looks.
+		<br><br>
+
+		<<He>> tries to keep up, but it's too much for <<him>>. <<He>> jerks away from your groin and seats <<himself>> on your leg. From the look <<hes>> giving you, you can't tell if <<hes>> upset.<<npcincr Whitney lust 5>><<glust>>
+	<<else>>
+		<span class="red">But you can.</span> Caught between <<his>> cheeks, your length is mercilessly pounded. You can't muster the strength to match <<him>>.
+		<br><br>
+
+		<<He>> doesn't relent, despite the change of position. If it weren't for a sly look over <<his>> shoulder, you'd think <<him>> oblivious to <<his>> torment. It's only through <<him>> pausing to finish <<his>> beer that you're able to stave off the rising warmth.<<arousal 5000>><<ggarousal>>
+	<</if>>
+<<else>>
+	You raise your thigh to <<his>> pussy and rub, hoping to redirect.
+	<<promiscuity4>>
+
+	<<He>> continues to grind,
+	<<if $thighskill gte random(1, $drunk)>>
+		<span class="green">but <<he>> falters.</span> Gradually, <<he>> drifts to your leg, until <<hes>> lost sight of your <<genitals>> completely.
+		<br><br>
+
+		A moan slips out, muffled in <<his>> beer. <<He>> catches <<himself>> and comes to a halt. <<His>> friends shoot <<him>> odd looks, but <<he>> brushes them off.<<npcincr Whitney lust 5>><<glust>>
+	<<else>>
+		<span class="red">unaffected by your effort.</span> It backfires entirely, the added friction making <<his>> teasing all the more unbearable.
+		<br><br>
+
+		<<He>> presses <<his>> ass down hard, torturing you with short, sharp motions. Your leg trembles beneath <<him>>, unable to keep up with <<his>> grinding and your own arousal. At last, <<he>> slows to a stop with a wink over <<his>> shoulder.<<arousal 5000>><<ggarousal>>
+	<</if>>
+<</if>>
+<br><br>
+
+<<link [[Next|Whitney Pub]]>><</link>>
+<br>
+
+:: Whitney Pub Thrust
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+In an effort to quell <<him>>, you press your <<print $phase2>> to <<if $phase is $phase2>><<hers>><<else>><<his>> crotch<</if>>. <<He>> answers your challenge with a grunt and pushes back twice as hard.
+<<promiscuity5>>
+
+<<if $phase is "penis" and $phase2 is "penis">>
+	You frot your dicks together.
+	<<if $NPCList[0].penissize gte 4>>
+		<<His>> <<print $NPCList[0].penisdesc>> dominates yours. The shaft grinds up and down your crotch, and the tip jabs your belly.
+	<<elseif $NPCList[0].penissize lte 1>>
+		<<He>> compensates <<his>> lack of size with dexterity,
+		<<if playerHasStrapon()>>
+			pushing past your <<print $worn.under_lower.name>> and grinding <<his>> tip into your clit.
+		<<else>>
+			teasing <<his>> tip against your shaft with sharp thrusts.
+		<</if>>
+	<<else>>
+		<<He>> starts slow, rubbing up and down your shaft, until <<his>> arousal spurs <<his>> pace.
+	<</if>>
+	With <<his>> hands firm on your <<bottom>>, you're given no room to breathe, or escape. You can only hope to overwhelm <<him>>.
+<<elseif $phase is "pussy" and $phase2 is "pussy">>
+	You rub your pussies together. Between <<his>> tipsiness and growing thirst, it's a struggle to keep <<him>> upright. <<He>> gropes all over, from your hips to your chest, just to avoid falling off your lap. <<He>> has no such trouble finding your clit beneath your <<print $worn.lower.name>>, smashing it into <<his>> crotch.
+<<elseif $phase is "penis" and $phase2 is "pussy">>
+	You tease <<his>> <<print $NPCList[0].penisdesc>>, shivering at the feel of <<his>> length pressing into you.
+	<<if $NPCList[0].penissize gte 4>>
+		With <<his>> size and savagery, not an inch of <<him>> is left to your imagination.
+	<<elseif $NPCList[0].penissize lte 1>>
+		What <<he>> lacks in size, <<he>> makes up for in sheer ferocity.
+	<<else>>
+		The thin layer of fabric between you does little against <<his>> harsh motions.
+	<</if>>
+	It's a wonder <<he>> doesn't tear through your clothes to fuck you on the spot.
+<<else>>
+	<<if $player.penissize gte 3>>
+		Even with your clothes in the way, you have no trouble rubbing your <<penis>> between <<his>> legs. Trying to keep up is another story.
+	<<elseif $player.penissize lte 0>>
+		Straining to find your <<penis>> beneath your <<print $worn.lower.name>>, <<he>> resorts to grinding <<his>> body into you.
+	<<else>>
+		<<He>> rides your <<penis>> through your <<print $worn.lower.name>>, just rough enough to make you squirm without drawing looks.
+	<</if>>
+	<<He>> slams <<his>> pelvis down, pressing your bodies tight every time you connect.
+	<<if $NPCList[0].breastsize gte 1>>
+		<<His>> <<print $NPCList[0].breastsdesc>> squish against you,
+	<<else>>
+		<<His>> chest crushes yours,
+	<</if>>
+	<<his>> nails pierce your shoulders, and <<his>> breath rings heavy in your ear. It threatens to send you both over the edge.
+<</if>>
+<br><br>
+
+With each thrust,
+<<if ($phase2 is "penis" and $penileskill gte random(1, $drunk)) or ($phase2 is "pussy" and $vaginalskill gte random(1, $drunk))>>
+	<span class="green"><<he>> gets sloppier.</span> You're not fighting to keep up with <<him>>, anymore. <<Hes>> fighting to keep up with you. Fighting and losing. Lacking a drink,
+	<<if $phase is "penis">>
+		<<he>> muffles <<himself>> in your chest.
+	<<else>>
+		<<he>> bites your neck to muffle <<himself>>.
+	<</if>>
+	<<npcincr Whitney lust 5>><<glust>>
+<<else>>
+	<<he>> puts more pressure on you. <span class="red">It's overwhelming.</span> Despite your efforts, you're reduced to twitching <<if $phase is "pussy">>beneath<<else>>against<</if>> <<him>> as <<he>> pounds your <<genitals>>.<<arousal 7000>><<gggarousal>>
+<</if>>
+<br><br>
+
+<<link [[Next|Whitney Pub]]>><</link>>
+<br>
+
+:: Whitney Pub End
+<<set $outside to 0>><<set $location to "pub">><<effects>>
+
+<<if $whitneyPub gte 7>>
+	Whitney slumps back in <<his>> seat, face red. You doubt it has much to do with the alcohol. Despite <<his>> clear exhaustion, <<hes>> smiling.
+	<br><br>
+
+	<<if $whitneyromance is 1>>
+		"That's my babe,"
+	<<else>>
+		"This <<bitch>> is trained,"
+	<</if>>
+	<<he>> says, giving your thigh a squeeze.
+	<<if $NPCList[0].penis isnot "none">>
+		"And here I thought I'd have to teach you to take that kind of shot, too."
+	<<else>>
+		"You sure know how to use your mouth."
+	<</if>>
+	<<status 20>><<gggcool>>
+<<else>>
+	Whitney lets you stew in <<his>> friends' mockery as <<he>> finishes <<his>> drink. <<He>> finally interrupts them with a clap on your back.
+	<br><br>
+
+	"I thought the liquor'd do you in first," <<he>> laughs, trailing <<his>> hand down. "Forgot who I was dealing with."<<npcincr Whitney lust 10>><<glust>>
+<</if>>
+<br><br>
+
+<<He>> wipes <<his>> mouth on <<his>> sleeve and rises. You're pulled up with <<him>>. "Better take my slut to that shithole <<pshe>> calls home," <<he>> tells <<his>> friends. "Can't have <<phim>> getting in trouble without my permission."
+<br><br>
+
+<<link [[Next|Whitney Pub Walk]]>><<endevent>><</link>>
+<br>
+
+:: Whitney Pub Walk
+<<set $outside to 1>><<set $location to "pub">><<effects>>
+<<npc Whitney>><<person1>>
+
+You leave the pub with Whitney. You have some trouble walking straight, so <<he>> has to support you most of the way.
+<br><br>
+
+"I knew you were a lightweight," <<he>> scoffs. "You're lucky I'm here. I bet you're even easier when you're drunk."
+<br><br>
+
+The pub's ambience fades to the quiet of the night. You can't hear a thing, save your own footsteps. Suddenly, Whitney stops in <<his>> tracks.
+<br><br>
+
+<<link [[Next|Whitney Pub Walk 2]]>><</link>>
+<br>
+
+:: Whitney Pub Walk 2
+<<set $outside to 1>><<set $location to "pub">><<effects>>
+
+You cling to <<him>>, lest you topple over in your drunken state. <<His>> arm snakes around your waist, pulling you closer.
+<br><br>
+
+"On second thought," <<he>> says. "Maybe I don't want to wait till you're home. Maybe I want to fuck you right here on the pavement."
+<br><br>
+
+<<link [[Let it happen|Whitney Pub Walk Sex]]>><<set $sexstart to 1>><<npcincr Whitney dom 1>><</link>><<promiscuous1>><<gdom>>
+<br>
+<<link [[Refuse|Whitney Pub Walk Refuse]]>><<npcincr Whitney dom -1>><</link>><<ldom>>
+<br>
+
+:: Whitney Pub Walk Refuse
+<<set $outside to 1>><<set $location to "town">><<set $bus to "domus">><<effects>>
+
+<<if $submissive gte 1150>>
+	"I'm sorry," you say. "I really want to go home."
+<<elseif $submissive lte 850>>
+	"I'm not in the mood," you snap. "Just take me home."
+<<else>>
+	"I thought you were taking me home," you say.
+<</if>>
+<br><br>
+
+<<if $whitneyPub gte 7>>
+	<span class="green"><<He>> releases you with a sigh.</span> "Can't even cut loose when you're wasted," <<he>> mutters. "Whatever. I got my fix back there, anyway."
+	<br><br>
+
+	You continue towards the orphanage in silence.
+	<br><br>
+
+	<<link [[Next|Whitney Pub Walk 3]]>><<pass 20>><</link>>
+	<br>
+<<else>>
+	<span class="red"><<His>> grip tightens, and <<his>> face twists into a scowl.</span> "You think I need a whore's permission?"
+	<br><br>
+
+	<<link [[Next|Whitney Pub Walk Sex]]>><<set $molestationstart to 1>><</link>>
+	<br>
+<</if>>
+
+:: Whitney Pub Walk Sex
+
+<<if $sexstart is 1>>
+	<<set $sexstart to 0>>
+	<<consensual>>
+	<<set $consensual to 1>>
+	<<neutral 1>>
+	<<maninit>>
+
+	<<He>> wasn't kidding. You barely get a word in before Whitney pulls you to the ground. <<Hes>> on you in an instant.
+	<<promiscuity1>>
+<<elseif $molestationstart is 1>>
+	<<set $molestationstart to 0>>
+	<<violence 1>>
+	<<neutral 1>>
+	<<molested>>
+	<<maninit>>
+
+	<<He>> throws you down, pressing your face to the pavement.
+	<<controlloss>>
+<</if>>
+
+<<effects>>
+<<effectsman>>
+<<man>>
+<<stateman>>
+<br><br>
+<<actionsman>>
+
+<<if _combatend>>
+	<span id="next"><<link [[Next|Whitney Pub Walk Sex Finish]]>><</link>></span><<nexttext>>
+<<else>>
+	<span id="next"><<link [[Next|Whitney Pub Walk Sex]]>><</link>></span><<nexttext>>
+<</if>>
+
+:: Whitney Pub Walk Sex Finish
+<<set $outside to 1>><<set $location to "pub">><<effects>>
+
+<<if $enemyarousal gte $enemyarousalmax>>
+	<<ejaculation>>
+
+	<<He>> lies atop you, <<his>> breath heavy against your skin.<<npcincr Whitney lust -20>><<llust>>
+	<br><br>
+
+	<<if $consensual is 1>><<set _walk to true>>
+		<<if $orgasmcurrent is 0 and !$worn.genitals.type.includes("chastity")>>
+			<<whitneyFinish>>
+		<</if>>
+
+		"Fuck," <<he>> pants. "I've been trying to keep it together all night, but you're pushing it, slut." <<He>> runs a hand through <<his>> fringe. "Not that I'm complaining."
+		<br><br>
+
+		<<He>> pulls you to your feet. <<tearful>> you steady yourself and continue on.
+	<<else>>
+		"That's what you get, <<bitch>>," <<he>> spits. "Have fun being easy prey." Without a second glance, <<he>> lights a cigarette and leaves.
+		<br><br>
+
+		<<tearful>> you rise to your feet.
+	<</if>>
+<<elseif $enemyhealth lte 0>>
+	You shove <<him>> away and retreat into the night. You're not sure if <<hes>> behind you, and you don't care to find out.
+	<br><br>
+
+	<<tearful>> you keep running, until you're sure you're alone.
+<<else>><<set _walk to true>>
+	You're left lying on the sidewalk, watching Whitney storm off. Halfway down the street, <<he>> throws a glare over <<his>> shoulder. <<He>> doesn't slow down.
+	<br><br>
+
+	"The fuck you waiting for?" <<he>> shouts. "Come on." <<tearful>> you hurry after <<him>>.
+<</if>>
+<br><br>
+
+<<clotheson>>
+<<endcombat>>
+
+<<if _walk>>
+	<<link [[Next|Whitney Pub Walk 3]]>><<pass 20>><<npc Whitney>><<person1>><</link>>
+	<br>
+<<else>>
+	<<link [[Next|Harvest Street]]>><<set $eventskip to 1>><</link>>
+	<br>
+<</if>>
+
+:: Whitney Pub Walk 3
+<<set $outside to 1>><<set $location to "town">><<set $bus to "domus">><<effects>>
+
+You arrive at the orphanage. Whitney walks you to the door. "Don't get used to this," <<he>> snaps. "I just don't want some perv's hands on my property."
+<br><br>
+
+<<if $whitneyromance is 1>>
+	<<He>> loiters on the doorstep. After a pause, <<he>> leans in for a kiss. You're pushed away before your lips meet.
+	<br><br>
+
+	"Go wash up," <<he>> says. "Your breath reeks." <<He>> lights a cigarette. "See you round, <<girl>>. Don't stay out."
+<<else>>
+	<<He>> lights a cigarette and takes a deep drag. For a moment, <<hes>> quiet.
+	<br><br>
+
+	"Done with you for tonight," <<he>> says. "Don't bother us again."
+<</if>>
+<br><br>
+
+You watch <<him>> skulk into an alley, leaving you alone.
+<br><br>
+
+<<link [[Next|Domus Street]]>><<endevent>><<set $eventskip to 1>><</link>>
+<br>
\ No newline at end of file
diff --git a/game/overworld-town/special-whitney/widgets.twee b/game/overworld-town/special-whitney/widgets.twee
index 9aeb261474..9630b2dda8 100644
--- a/game/overworld-town/special-whitney/widgets.twee
+++ b/game/overworld-town/special-whitney/widgets.twee
@@ -239,6 +239,60 @@
 	<<unset $whitneyRescueUniform>>
 <</widget>>
 
+<<widget "whitneyFinish">>
+	<<if $player.penisExist and $penisuse isnot 0>>
+		<<set $penisuse to 0>>
+	<</if>>
+	<<if $audiencepresent gte 1>>
+		<<He>> pulls your head close and whispers. "Couldn't even fake it? You're embarrassing me in front of the crowd."
+	<<else>>
+		"Don't think I wouldn't return the favour, slut."
+	<</if>>
+	<<if !$genderknown.includes("Whitney") and ($player.gender is "h") or ($player.gender_appearance is "m" and $player.gender isnot "m") or ($player.gender_appearance is "f" and $player.gender isnot "f")>>
+		<<set $genderknown.pushUnique("Whitney")>>
+		<<His>> hand trails down, until it makes contact with your <<genitals>>. For a moment, <<he>> seems surprised by what <<he>> feels, but <<he>> smiles anyway.
+		<br><br>
+	<</if>>
+	<<He>> quickly grabs your <<genitals>> and
+	<<if $player.gender is "h">>
+		starts to jerk you off with one hand, plunging a finger from <<his>> other hand into your <<pussy>>.
+	<<elseif $player.penisExist>>
+		starts to jerk you off, paying extra attention to the tip of your <<penis>>.
+	<<else>>
+		plunges a finger into your <<pussy>>, swirling it around.
+	<</if>>
+	<<arousal 5000>>
+	<<if $arousal gte $arousalmax>>
+		<<orgasm>><<He>> smiles.
+	<<else>>
+		<<if $audiencepresent gte 1>>
+			"I'll teach you to appreciate a good fuck."
+		<<else>>
+			"Can't have you leaving without a little gift."
+		<</if>>
+		<br><br>
+		<<He>> locks eyes with you, and the speed of <<his>> assault increases.
+		<<if $player.gender is "h">>
+			<<He>> uses <<his>> thumb to rub your tip in circles, while sliding a second finger into your <<pussy>>.
+		<<elseif $player.penisExist>>
+			<<He>> uses <<his>> thumb to rub your tip in circles<<if $NPCName[$NPCNameList.indexOf("Whitney")].dom gte 16 and $analdisable is "f">>, and slowly slides a finger into your <<bottom>>. <<He>> grins as <<he>> reaches your prostate<<else>>, giving your <<bottom>> a slap with <<his>> other hand<</if>>.
+		<<else>>
+			<<He>> plunges a second finger into your <<pussy>>, and uses <<his>> other hand to fondle your <<breasts>>.
+		<</if>>
+		<<He>> kisses you, muffling your involuntary moans.
+		<<if $location is "park">>
+			Someone on the far side of the park seems to notice you two, and they quickly turn away.
+		<</if>>
+		<br><br>
+		<<set $arousal to 10000>>
+		<<if $arousal gte $arousalmax>>
+			<<orgasm>>
+		<</if>>
+		Whitney gives you a wicked smile<<if $audiencepresent gte 1>>, and the crowd cheers once again<</if>>.
+	<</if>>
+	<br><br>
+<</widget>>
+
 <<widget "dismissWhitney">>
 <<npcset Whitney state "dungeon">>
 <<if $loveInterest.primary is "Whitney">>
-- 
GitLab


From fc840592a503391ebf7c1bb4039616090e93dbad Mon Sep 17 00:00:00 2001
From: Braymann <19001-Braymann@users.noreply.gitgud.io>
Date: Thu, 15 Sep 2022 00:52:39 +0000
Subject: [PATCH 35/50] Bug fixes

---
 game/base-combat/actions-anus.twee            | 46 ++++++++++---------
 game/base-combat/actions-vagina.twee          | 40 ++++++++--------
 game/base-combat/widgets.twee                 | 10 ++--
 game/base-system/bodywriting.twee             | 10 ++--
 .../loc-lake/ivory/snatched.twee              |  2 +
 game/overworld-town/loc-school/exam.twee      |  2 +-
 6 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/game/base-combat/actions-anus.twee b/game/base-combat/actions-anus.twee
index 37de443074..dc6a7b396d 100644
--- a/game/base-combat/actions-anus.twee
+++ b/game/base-combat/actions-anus.twee
@@ -250,31 +250,33 @@
 <<if $anusaction is "anustopenis">>
 	<<personselect $anustarget>>
 	<<set $anusaction to 0>><<submission 10 $anustarget>><<analskilluse>><<combatpromiscuity5>>
-	<<if combatSkillCheck("anal", $anustarget)>>
-		<<if $NPCList[$anustarget].penis is 0>>
-			<<submission 2 $anustarget>><<set $anususe to "penis">><<set $NPCList[$anustarget].penis to "anusentrance">><<set $anusstate to "entrance">><<set $anusactiondefault to "penistease">>
-			<<if $leftarm is "anus">>
-				<<set $leftarm to 0>>
-			<</if>>
-			<<if $rightarm is "anus">>
-				<<set $rightarm to 0>>
-			<</if>>
-			<span class="lblue">You straddle <<combatperson>> and press <<his>> <<npcPenis $anustarget>> with your <<bottom>>.</span>
-			<<if $NPCList[$anustarget].type is "plant" and $NPCList[$anustarget].penissize gte 4>>
-				<span class="red">Something about it scares you.</span>
-			<</if>>
-			<<if $condomUse is false>>
-			<<elseif ($condomUse is true or (random(0,100) lt $condomautochance and $npcCondoms isnot undefined)) and $NPCList[$anustarget].condom is false>>
-				<<equipCondom $anustarget>>
-				<span class="green"><<He>> slips a condom on <<his>> penis.</span>
+	<<if $anususe is 0>>
+		<<if combatSkillCheck("anal", $anustarget)>>
+			<<if $NPCList[$anustarget].penis is 0>>
+				<<submission 2 $anustarget>><<set $anususe to "penis">><<set $NPCList[$anustarget].penis to "anusentrance">><<set $anusstate to "entrance">><<set $anusactiondefault to "penistease">>
+				<<if $leftarm is "anus">>
+					<<set $leftarm to 0>>
+				<</if>>
+				<<if $rightarm is "anus">>
+					<<set $rightarm to 0>>
+				<</if>>
+				<span class="lblue">You straddle <<combatperson>> and press <<his>> <<npcPenis $anustarget>> with your <<bottom>>.</span>
+				<<if $NPCList[$anustarget].type is "plant" and $NPCList[$anustarget].penissize gte 4>>
+					<span class="red">Something about it scares you.</span>
+				<</if>>
+				<<if $condomUse is false>>
+				<<elseif ($condomUse is true or (random(0,100) lt $condomautochance and $npcCondoms isnot undefined)) and $NPCList[$anustarget].condom is false>>
+					<<equipCondom $anustarget>>
+					<span class="green"><<He>> slips a condom on <<his>> penis.</span>
+				<</if>>
+				<<if $enemytype is "beast">><<set $NPCList[$anustarget].stance to "top">><</if>>
+				<<set $NPCList[$anustarget].location.genitals to "genitals">>
+			<<else>>
+				<span class="blue">You try to straddle <<combatperson>> with your <<bottom>>, but the phallus is already occupied.</span><<set $anusactiondefault to "anustopenis">>
 			<</if>>
-			<<if $enemytype is "beast">><<set $NPCList[$anustarget].stance to "top">><</if>>
-			<<set $NPCList[$anustarget].location.genitals to "genitals">>
 		<<else>>
-			<span class="blue">You try to straddle <<combatperson>> with your <<bottom>>, but the phallus is already occupied.</span><<set $anusactiondefault to "anustopenis">>
+			<span class="blue">You try to straddle <<combatperson>> with your <<bottom>> but <<ohe>> pushes you off.</span><<set $anusactiondefault to "anustopenis">>
 		<</if>>
-	<<else>>
-		<span class="blue">You try to straddle <<combatperson>> with your <<bottom>> but <<ohe>> pushes you off.</span><<set $anusactiondefault to "anustopenis">>
 	<</if>>
 <</if>>
 
diff --git a/game/base-combat/actions-vagina.twee b/game/base-combat/actions-vagina.twee
index da559e1a2f..d8e6e4a430 100644
--- a/game/base-combat/actions-vagina.twee
+++ b/game/base-combat/actions-vagina.twee
@@ -327,28 +327,30 @@
 <<if $vaginaaction is "vaginatopenis">>
 	<<personselect $vaginatarget>>
 	<<set $vaginaaction to 0>><<submission 10 $vaginatarget>><<vaginalskilluse>><<combatpromiscuity5>>
-	<<if combatSkillCheck("vaginal", $vaginatarget)>>
-		<<if $NPCList[$vaginatarget].penis is 0>>
-			<<submission 2 $vaginatarget>><<set $vaginause to "penis">><<set $NPCList[$vaginatarget].penis to "vaginaentrance">><<set $vaginastate to "entrance">><<set $vaginaactiondefault to "penistease">>
-			<<if $leftarm is "vagina">>
-				<<set $leftarm to 0>>
-			<</if>>
-			<<if $rightarm is "vagina">>
-				<<set $rightarm to 0>>
-			<</if>>
-			<<if $condomUse is false>>
-			<<elseif ($condomUse is true or (random(0,100) lt $condomautochance and $npcCondoms isnot undefined)) and $NPCList[$vaginatarget].condom is false>>
-				<<equipCondom $vaginatarget>>
-				<span class="green"><<He>> slips a condom on <<his>> penis.</span>
+	<<if $vaginause is 0>>
+		<<if combatSkillCheck("vaginal", $vaginatarget)>>
+			<<if $NPCList[$vaginatarget].penis is 0>>
+				<<submission 2 $vaginatarget>><<set $vaginause to "penis">><<set $NPCList[$vaginatarget].penis to "vaginaentrance">><<set $vaginastate to "entrance">><<set $vaginaactiondefault to "penistease">>
+				<<if $leftarm is "vagina">>
+					<<set $leftarm to 0>>
+				<</if>>
+				<<if $rightarm is "vagina">>
+					<<set $rightarm to 0>>
+				<</if>>
+				<<if $condomUse is false>>
+				<<elseif ($condomUse is true or (random(0,100) lt $condomautochance and $npcCondoms isnot undefined)) and $NPCList[$vaginatarget].condom is false>>
+					<<equipCondom $vaginatarget>>
+					<span class="green"><<He>> slips a condom on <<his>> penis.</span>
+				<</if>>
+				<span class="lblue">You straddle <<combatperson>> and kiss <<his>> $NPCList[$vaginatarget].penisdesc with your <<pussy>><<if $NPCList[$vaginatarget].chastity.penis.includes("chastity")>> through <<his>> $NPCList[$vaginatarget].chastity.penis<</if>>.</span>
+				<<if $enemytype is "beast">><<set $NPCList[$vaginatarget].stance to "top">><</if>>
+				<<set $NPCList[$vaginatarget].location.genitals to "genitals">>
+			<<else>>
+				<span class="blue">You try to straddle <<combatpersons>> $NPCList[$vaginatarget].penisdesc, but the phallus is already occupied.</span><<set $vaginaactiondefault to "vaginatopenis">>
 			<</if>>
-			<span class="lblue">You straddle <<combatperson>> and kiss <<his>> $NPCList[$vaginatarget].penisdesc with your <<pussy>><<if $NPCList[$vaginatarget].chastity.penis.includes("chastity")>> through <<his>> $NPCList[$vaginatarget].chastity.penis<</if>>.</span>
-			<<if $enemytype is "beast">><<set $NPCList[$vaginatarget].stance to "top">><</if>>
-			<<set $NPCList[$vaginatarget].location.genitals to "genitals">>
 		<<else>>
-			<span class="blue">You try to straddle <<combatpersons>> $NPCList[$vaginatarget].penisdesc, but the phallus is already occupied.</span><<set $vaginaactiondefault to "vaginatopenis">>
+			<span class="blue">You try to straddle <<combatperson>> but <<ohe>> pushes you off.</span><<set $vaginaactiondefault to "vaginatopenis">>
 		<</if>>
-	<<else>>
-		<span class="blue">You try to straddle <<combatperson>> but <<ohe>> pushes you off.</span><<set $vaginaactiondefault to "vaginatopenis">>
 	<</if>>
 <</if>>
 
diff --git a/game/base-combat/widgets.twee b/game/base-combat/widgets.twee
index 8693327aec..a944932490 100644
--- a/game/base-combat/widgets.twee
+++ b/game/base-combat/widgets.twee
@@ -141,14 +141,18 @@
 	<<set $_vType to _args[1]>>
 	<!-- if the first argument is a name, find which npc has that name, else assume it is an index. -->
 	<<if typeof $_npcId is "string">>
-		<<set $_npc to $NPCList.find(npc => npc.fullDescription === $_npcId)>>
-		<<set $_straponvirginityIgnore to ($_vType is "penile" and npcHasStrapon($NPCList.findIndex(npc => npc.fullDescription === $_npcId)))>>
-	<<elseif $_npcId isnot undefined>>
+		<<set $_npcId to $NPCList.findIndex(npc => npc.fullDescription === $_npcId)>>
+	<</if>>
+	<<if $_npcId isnot undefined and $_npcId gte 0>>
 		<<set $_npc to $NPCList[$_npcId]>>
 		<<set $_straponvirginityIgnore to ($_vType is "penile" and npcHasStrapon($_npcId))>>
 	<</if>>
 
 	<<if $_npc and $_vType and $_npc.virginity and $_npc.virginity[$_vType] and (!$wraith or $wraith.mimic isnot $_npc.nam) and !$_straponvirginityIgnore>>
+		<<if ($_vType is "vaginal" or $_vType is "penile") and $_npc.virginity.temple is true and $templePromised isnot $_npc.fullDescription>>
+			<<set $_npc.virginity.temple to false>>
+		<</if>>
+		
 		/* note: virginity must be exactly equal to true; only true means that they still have their virginity. */
 		<<if $_npc.virginity[$_vType] is true>>
 			<<personselect $_npcId>>
diff --git a/game/base-system/bodywriting.twee b/game/base-system/bodywriting.twee
index c718553e66..8f298f1159 100755
--- a/game/base-system/bodywriting.twee
+++ b/game/base-system/bodywriting.twee
@@ -1513,10 +1513,10 @@ Second arg: tool */
 		<<switch $skin[_args[0]].writing>>
 			<<case "Reserved for Kylar">>
 				"Reserved for me," <<he>> says lovingly as <<he>>
-				<<if _args[0] is "left_cheek" or _args[0] is "right_cheek" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "head" and $NPCList[_n].penis is 0 and $mouthuse is 0>>
+				<<if (_args[0] is "left_cheek" or _args[0] is "right_cheek") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "head" and $NPCList[_n].penis is 0 and $mouthuse is 0>>
 					<span class="blue">positions <<his>> $NPCList[_n].penisdesc in front of your mouth</span>.
 					<<neutral 5>><<set $mouthuse to "penis">><<set $NPCList[_n].penis to "mouthentrance">><<set $mouthstate to "entrance">><<set $NPCList[_n].location.genitals to "head">><<set $mouthtarget to _n>>
-				<<elseif _args[0] is "left_cheek" or _args[0] is "right_cheek" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "head" and $NPCList[_n].vagina is 0 and $mouthuse is 0>>
+				<<elseif (_args[0] is "left_cheek" or _args[0] is "right_cheek") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "head" and $NPCList[_n].vagina is 0 and $mouthuse is 0>>
 					<<if random(4) is 0 and $facesitdisable is "f">>
 						gently rolls you onto your back and <span class="purple">straddles your face, lowering <<his>> pussy down onto your mouth</span>.
 						<<submission 5>><<set $NPCList[_n].vagina to "facesit">><<set $mouthuse to "facesit">><<set $mouthstate to "vagina">><<set $position to "missionary">><<set $mouthtarget to _n>>
@@ -1524,13 +1524,13 @@ Second arg: tool */
 						<span class="blue">wraps <<his>> legs around your head, pressing <<his>> pussy against your mouth</span>.
 						<<submission 5>><<set $mouthuse to "othervagina">><<set $NPCList[_n].vagina to "mouth">><<set $mouthstate to "othervagina">><<set $mouthtarget to _n>>
 					<</if>>
-				<<elseif _args[0] is "back" or _args[0] is "right_bottom" or _args[0] is "left_bottom" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals" and $worn.lower.anus_exposed gte 1 and $worn.under_lower.anus_exposed gte 1 and $NPCList[_n].penis is 0 and $anususe is 0>>
+				<<elseif (_args[0] is "back" or _args[0] is "right_bottom" or _args[0] is "left_bottom") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals" and $worn.lower.anus_exposed gte 1 and $worn.under_lower.anus_exposed gte 1 and $NPCList[_n].penis is 0 and $anususe is 0>>
 					<span class="blue">positions <<his>> penis in front of your <<bottom>></span>.
 					<<neutral 5>><<set $anususe to "penis">><<set $NPCList[_n].penis to "anusentrance">><<set $anusstate to "entrance">><<set $anustarget to _n>>
-				<<elseif _args[0] is "pubic" or _args[0] is "left_thigh" or _args[0] is "right_thigh" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals" and $player.vaginaExist and $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1 and $NPCList[_n].penis is 0 and $vaginause is 0>>
+				<<elseif (_args[0] is "pubic" or _args[0] is "left_thigh" or _args[0] is "right_thigh") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals" and $player.vaginaExist and $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1 and $NPCList[_n].penis is 0 and $vaginause is 0>>
 					<span class="blue">moves between your legs, positioning <<his>> $NPCList[_n].penisdesc in front of your pussy</span>.
 					<<neutral 5>><<set $NPCList[_n].penis to "vaginaentrance">><<set $vaginause to "penis">><<set $vaginastate to "entrance">><<set $NPCList[_n].location.genitals to "genitals">><<set $vaginatarget to _n>>
-				<<elseif _args[0] is "pubic" or _args[0] is "left_thigh" or _args[0] is "right_thigh" and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals" and $player.penisExist and $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1 and $NPCList[_n].vagina is 0 and $penisuse is 0>>
+				<<elseif (_args[0] is "pubic" or _args[0] is "left_thigh" or _args[0] is "right_thigh") and $NPCList[_n].location.genitals is 0 and $NPCList[_n].location.head isnot "genitals" and $player.penisExist and $worn.lower.vagina_exposed gte 1 and $worn.under_lower.vagina_exposed gte 1 and $NPCList[_n].vagina is 0 and $penisuse is 0>>
 					<span class="blue">straddles you, <<his>> pussy hovering close to your <<penis>></span>.
 					<<neutral 5>><<set $penisuse to "othervagina">><<set $NPCList[_n].vagina to "penisentrance">><<set $penisstate to "entrance">><<set $NPCList[_n].location.genitals to "genitals">><<set $penistarget to _n>>
 				<<else>>
diff --git a/game/overworld-forest/loc-lake/ivory/snatched.twee b/game/overworld-forest/loc-lake/ivory/snatched.twee
index 034c36f28d..1b1993f449 100644
--- a/game/overworld-forest/loc-lake/ivory/snatched.twee
+++ b/game/overworld-forest/loc-lake/ivory/snatched.twee
@@ -320,6 +320,7 @@ Your head quickly tilts to the side, making sickening cracks. Your hands open an
 	It vanishes in a torrent of water. You slowly regain feeling in your body, and try to stand. It takes a few tries, but eventually, you hoist yourself up.
 	<br><br>
 	<<tearful>> you try to make sense of what happened to you.
+	<br><br>
 <<else>>
 	<span class="gold">You stop.</span>
 	<br><br>
@@ -339,6 +340,7 @@ Your head quickly tilts to the side, making sickening cracks. Your hands open an
 		<br><br>
 	<</if>>
 	A massive torrent of water shoots up from below, completely engulfing it. You can only see its <<wraithEyes>> eyes glowing through it. When it passes, the figure is gone. <<tearful>> you try to make sense of what you just went through.
+	<br><br>
 <</if>>
 <<exposure>>
 <<clotheson>>
diff --git a/game/overworld-town/loc-school/exam.twee b/game/overworld-town/loc-school/exam.twee
index a81f3ad406..77914a9328 100644
--- a/game/overworld-town/loc-school/exam.twee
+++ b/game/overworld-town/loc-school/exam.twee
@@ -114,7 +114,7 @@
 
 <<widget "exam_cheat">>
 	<<set $_trait to V[_args[0] + 'trait']>>
-	<<set $skulduggerydifficulty to [100,200,400,700,1100,1100][Math.clamp($_trait, -1, 4)]>>
+	<<set $skulduggerydifficulty to [100,200,400,700,1100,1100][Math.clamp($_trait + 1, 0, 5)]>>
 <</widget>>
 
 
-- 
GitLab


From 6d72f5b370aea9822e89d51e75b88303c7cc2d69 Mon Sep 17 00:00:00 2001
From: hwp <22502-hwp@users.noreply.gitgud.io>
Date: Sat, 17 Sep 2022 09:40:23 +0000
Subject: [PATCH 36/50] tattoo parlour rework

---
 game/base-system/bodywriting.twee             | 380 ++++++++----------
 .../loc-school/widgets-events.twee            | 265 +++++-------
 game/overworld-town/loc-shop/tattoo.twee      |  84 ++--
 game/overworld-town/special-whitney/main.twee | 173 ++++----
 4 files changed, 385 insertions(+), 517 deletions(-)

diff --git a/game/base-system/bodywriting.twee b/game/base-system/bodywriting.twee
index c718553e66..bb283b5de1 100755
--- a/game/base-system/bodywriting.twee
+++ b/game/base-system/bodywriting.twee
@@ -2277,72 +2277,45 @@ Second arg: tool */
 <</widget>>
 
 <<widget "bodywriting_exposure_check">>/*Checks if bodywriting or tattoos are visible to NPCs.*/
-<<if _skin_array is undefined or _args[0] is true>>
-	<<set _skin_array to []>>
-	<<set _skin_array_special to []>>
-	<<set _bodywriting_exposed to 0>>
-	<<if $skin.forehead.writing>>
-		<<set _skin_array.push("forehead")>>
-		<<set _skin_array_special.push($skin.forehead.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.left_cheek.writing and !$worn.face.type.includes("mask")>>
-		<<set _skin_array.push("left_cheek")>>
-		<<set _skin_array_special.push($skin.left_cheek.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.right_cheek.writing and !$worn.face.type.includes("mask")>>
-		<<set _skin_array.push("right_cheek")>>
-		<<set _skin_array_special.push($skin.right_cheek.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.left_shoulder.writing and ($worn.over_upper.exposed gte 1 or $worn.over_upper.open is 1) and ($worn.upper.exposed gte 1 or $worn.upper.open is 1) and ($worn.under_upper.exposed gte 1 or $worn.under_upper is 1)>>
-		<<set _skin_array.push("left_shoulder")>>
-		<<set _skin_array_special.push($skin.left_shoulder.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.right_shoulder.writing and ($worn.over_upper.exposed gte 1 or $worn.over_upper.open is 1) and ($worn.upper.exposed gte 1 or $worn.upper.open is 1) and ($worn.under_upper.exposed gte 1 or $worn.under_upper is 1)>>
-		<<set _skin_array.push("right_shoulder")>>
-		<<set _skin_array_special.push($skin.right_shoulder.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.breasts.writing and ($worn.over_upper.exposed gte 1) and ($worn.upper.exposed gte 1) and ($worn.under_upper.exposed gte 1)>>
-		<<set _skin_array.push("breasts")>>
-		<<set _skin_array_special.push($skin.breasts.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.back.writing and ($worn.over_upper.exposed gte 1 or $worn.over_upper.state isnot "waist") and ($worn.upper.exposed gte 1 or $worn.upper.state isnot "waist") and ($worn.under_upper.exposed gte 1 or $worn.under_upper.state isnot "waist")>>
-		<<set _skin_array.push("back")>>
-		<<set _skin_array_special.push($skin.back.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.left_bottom.writing and ($worn.over_lower.exposed gte 1 or $worn.over_lower.anus_exposed gte 1) and ($worn.lower.exposed gte 1 or $worn.lower.anus_exposed gte 1) and ($worn.under_lower.exposed gte 1 or !$worn.under_lower.type.includes("athletic"))>>
-		<<set _skin_array.push("left_bottom")>>
-		<<set _skin_array_special.push($skin.left_bottom.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.right_bottom.writing and ($worn.over_lower.exposed gte 1 or $worn.over_lower.anus_exposed gte 1) and ($worn.lower.exposed gte 1 or $worn.lower.anus_exposed gte 1) and ($worn.under_lower.exposed gte 1 or !$worn.under_lower.type.includes("athletic"))>>
-		<<set _skin_array.push("right_bottom")>>
-		<<set _skin_array_special.push($skin.right_bottom.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.pubic.writing and $worn.over_lower.exposed gte 1 and $worn.lower.exposed gte 1 and ($worn.under_lower.exposed gte 1 or !$worn.under_lower.type.includes("athletic"))>>
-		<<set _skin_array.push("pubic")>>
-		<<set _skin_array_special.push($skin.pubic.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.left_thigh.writing and $worn.over_lower.vagina_exposed gte 1 and $worn.lower.vagina_exposed gte 1 and !$worn.under_lower.type.includes("athletic")>>
-		<<set _skin_array.push("left_thigh")>>
-		<<set _skin_array_special.push($skin.left_thigh.special)>>
-		<<set _bodywriting_exposed to 1>>
-	<</if>>
-	<<if $skin.right_thigh.writing and $worn.over_lower.vagina_exposed gte 1 and $worn.lower.vagina_exposed gte 1 and !$worn.under_lower.type.includes("athletic")>>
-		<<set _skin_array.push("right_thigh")>>
-		<<set _skin_array_special.push($skin.right_thigh.special)>>
-		<<set _bodywriting_exposed to 1>>
+	<<if _skin_array is undefined or _args[0] is true>>
+		<<set _visible_areas to []>>
+		<<set _bodywriting_exposed to 0>>
+		
+		<!-- first: construct a set of all locations where writing COULD be seen (doesn't matter if there is any writing or not) -->
+		<<set _visible_areas.push("forehead")>>
+		<<if !$worn.face.type.includes("mask")>>
+			<<set _visible_areas.push("left_cheek", "right_cheek")>>
+		<</if>>
+		<<if ($worn.over_upper.exposed gte 1 or $worn.over_upper.open is 1) and ($worn.upper.exposed gte 1 or $worn.upper.open is 1) and ($worn.under_upper.exposed gte 1 or $worn.under_upper.open is 1)>>
+			<<set _visible_areas.push("left_shoulder", "right_shoulder")>>
+		<</if>>
+		<<if ($worn.over_upper.exposed gte 1) and ($worn.upper.exposed gte 1) and ($worn.under_upper.exposed gte 1)>>
+			<<set _visible_areas.push("breasts")>>
+		<</if>>
+		<<if ($worn.over_upper.exposed gte 1 or $worn.over_upper.state isnot "waist") and ($worn.upper.exposed gte 1 or $worn.upper.state isnot "waist") and ($worn.under_upper.exposed gte 1 or $worn.under_upper.state isnot "waist")>>
+			<<set _visible_areas.push("back")>>
+		<</if>>
+		<<if ($worn.over_lower.exposed gte 1 or $worn.over_lower.anus_exposed gte 1) and ($worn.lower.exposed gte 1 or $worn.lower.anus_exposed gte 1) and ($worn.under_lower.exposed gte 1 or !$worn.under_lower.type.includes("athletic"))>>
+			<<set _visible_areas.push("left_bottom", "right_bottom")>>
+		<</if>>
+		<<if $worn.over_lower.exposed gte 1 and $worn.lower.exposed gte 1 and ($worn.under_lower.exposed gte 1 or !$worn.under_lower.type.includes("athletic"))>>
+			<<set _visible_areas.push("pubic")>>
+		<</if>>
+		<<if $worn.over_lower.vagina_exposed gte 1 and $worn.lower.vagina_exposed gte 1 and !$worn.under_lower.type.includes("athletic")>>
+			<<set _visible_areas.push("left_thigh", "right_thigh")>>
+		<</if>>
+
+		<!-- second: filter out every area where there is no writing and store it in _skin_array -->
+		<<set _skin_array to _visible_areas.filter(loc => $skin[loc].writing)>>
+		
+		<!-- third: make an array of all the special properties of the visible bodywriting -->
+		<<set _skin_array_special to _skin_array.map(loc => $skin[loc].special)>>
+
+		<<if _skin_array.length gte 1>>
+			<<set _bodywriting_exposed to 1>>
+		<</if>>
 	<</if>>
-<</if>>
-<<set _bodypart to _skin_array.random()>>
+	<<set _bodypart to _skin_array.random()>>
 <</widget>>
 
 <<widget "bodywriting_prostitution_check">>
@@ -2350,179 +2323,168 @@ Second arg: tool */
 <</widget>>
 
 <<widget "tattoo_parlour">>
-<<generate1>><<person1>>
-<<if $tattoo_choice>>
-	<<if $tattoo_parlour.special is "bestiality" or $tattoo_parlour.special is "Black Wolf" or $tattoo_parlour.special is "Great Hawk">>
-	Blushing, you tell the tattoo artist you want <<if $tattoo_parlour.type is "text">><span class="pink">"<<print $tattoo_parlour.writing>>"</span><<else>>a <span class="pink"><<print $tattoo_parlour.writing>></span><</if>> tattooed on your <<bodypart $tattoo_bodypart>>. <<Hes>> unfazed by your deviant request.
-	<<control 50>><<gggcontrol>>
-
+	<<generate1>><<person1>>
+	<<if ["bestiality", "Black Wolf", "Great Hawk"].includes($tattoo_parlour.special)>>
+		<<set $_embarassingType to "deviant">>
 	<<elseif $tattoo_parlour.lewd is 1>>
-	Blushing, you tell the tattoo artist you want <<if $tattoo_parlour.type is "text">><span class="pink">"<<print $tattoo_parlour.writing>>"</span><<else>>a <span class="pink"><<print $tattoo_parlour.writing>></span><</if>> tattooed on your <<bodypart $tattoo_bodypart>>. <<Hes>> unfazed by your lewd request.
-	<<control 50>><<gggcontrol>>
-
-	<<elseif $tattoo_bodypart is "left_bottom" or $tattoo_bodypart is "right_bottom" or $tattoo_bodypart is "pubic" or $tattoo_bodypart is "breasts">>
-	Blushing, you tell the tattoo artist you want <<if $tattoo_parlour.type is "text">><span class="pink">"<<print $tattoo_parlour.writing>>"</span><<else>>a <span class="pink"><<print $tattoo_parlour.writing>></span><</if>> tattooed on your <<bodypart $tattoo_bodypart>>. <<Hes>> unfazed by the location.
-	<<control 50>><<gggcontrol>>
-
-	<<else>>
-	You tell the tattoo artist you want <<if $tattoo_parlour.type is "text">><span class="pink">"<<print $tattoo_parlour.writing>>"</span><<else>>a <span class="pink"><<print $tattoo_parlour.writing>></span><</if>> tattooed on your <<bodypart $tattoo_bodypart>>.
-	<<control 25>><<ggcontrol>>
-
+		<<set $_embarassingType to "lewd">>
+	<<elseif ["left_bottom", "right_bottom", "pubic", "breasts"].includes($tattoo_bodypart)>>
+		<<set $_embarassingType to "location">>
 	<</if>>
-<<else>>
-	<<if $tattoo_parlour.special is "bestiality" or $tattoo_parlour.special is "Black Wolf" or $tattoo_parlour.special is "Great Hawk">>
-	Blushing, you tell the tattoo artist you want <<if $tattoo_parlour.type is "text">>writing<<else>>image<</if>> on your <<bodypart $tattoo_bodypart>> to become permanent. <<Hes>> unfazed by your deviant request.
-
-	<<elseif $tattoo_parlour.lewd is 1>>
-	Blushing, you tell the tattoo artist you want the <<if $tattoo_parlour.type is "text">>writing<<else>>image<</if>> on your <<bodypart $tattoo_bodypart>> to become permanent. <<Hes>> unfazed by your lewd request.
-
-	<<elseif $tattoo_bodypart is "left_bottom" or $tattoo_bodypart is "right_bottom" or $tattoo_bodypart is "pubic" or $tattoo_bodypart is "breasts">>
-	Blushing, you tell the tattoo artist you want the <<if $tattoo_parlour.type is "text">>writing<<else>>image<</if>> on your <<bodypart $tattoo_bodypart>> to become permanent. <<Hes>> unfazed by the location.
-
+	<<if $tattoo_choice>>
+		<<if $tattoo_parlour.type is "text">>
+			<<set $_request to `<span class="pink">"<<print $tattoo_parlour.writing>>"</span>`>>
+		<<else>>
+			<<set $_request to `a <span class="pink"><<print $tattoo_parlour.writing>></span>`>>
+		<</if>>
+		<<if $_embarassingType>>
+			Blushing, you tell the tattoo artist you want $_request tattooed on your <<bodypart $tattoo_bodypart>>.
+			<<control 50>><<gggcontrol>>
+		<<else>>
+			You tell the tattoo artist you want $_request tattooed on your <<bodypart $tattoo_bodypart>>.
+			<<control 25>><<ggcontrol>>
+		<</if>>
 	<<else>>
-	You tell the tattoo artist you want the <<if $tattoo_parlour.type is "text">>writing<<else>>image<</if>> on your <<bodypart $tattoo_bodypart>> to become permanent.
-
+		<<set $_writing to ($tattoo_parlour.type is "text" ? "writing" : "image")>>
+		<<if $_embarassingType>>
+			Blushing, you tell the tattoo artist you want the $_writing on your <<bodypart $tattoo_bodypart>> to become permanent.
+		<<else>>
+			You tell the tattoo artist you want the $_writing on your <<bodypart $tattoo_bodypart>> to become permanent.
+		<</if>>
 	<</if>>
-<</if>>
-<br><br>
-<<if $tattoo_bodypart is "left_bottom" or $tattoo_bodypart is "right_bottom">>
-"Alright," <<he>> says, pulling the curtain shut. "Lets see your bottom."
-	<<if $worn.lower.name isnot "naked">>
-		<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
-			<<if $worn.under_lower.name isnot "naked">>
-				You <<nervously>> flip up your skirt, baring your $worn.under_lower.name. "Those need to go," <<he>> says. "Or they'll get in the way."
-					<<if $worn.under_lower.set is $worn.under_upper.set>>
-						You follow <<his>> instruction, and shuffle out of your $worn.under_upper.name while <<his>> back is turned.
-					<<else>>
-						You follow <<his>> instruction, and pull down your $worn.under_lower.name while <<his>> back is turned.
-					<</if>>
+	<<if $_embarassingType is "deviant">>
+		<<Hes>> unfazed by your deviant request.
+	<<elseif $_embarassingType is "lewd">>
+		<<Hes>> unfazed by your lewd request.
+	<<elseif $_embarassingType is "location">>
+		<<Hes>> unfazed by the location.
+	<</if>>
+	<br><br>
+
+	<<set $_skirt to setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt>>
+	<<if ["left_bottom", "right_bottom"].includes($tattoo_bodypart)>>
+		"Alright," <<he>> says, pulling the curtain shut. "Lets see your bottom."
+		<<if $worn.lower.type.includes("naked")>>
+			<<if $worn.under_lower.type.includes("naked")>>
+				You <<nervously>> turn, showing <<him>> your <<bottom>>.
 			<<else>>
+				You <<nervously>> pull down your $worn.under_lower.name, baring your <<bottom>>.
+			<</if>>
+		<<elseif $worn.under_lower.type.includes("naked")>>
+			<<if $_skirt is 1>>
 				You <<nervously>> flip up your skirt, baring your <<bottom>>.
+			<<else>>
+				You <<nervously>> pull down your $worn.lower.name, baring your <<bottom>>.
 			<</if>>
 		<<else>>
-			<<if $worn.lower.set is $worn.upper.set>>
-				<<if !$worn.under_lower.type.includes("naked")>>
-					You <<nervously>> remove your $worn.upper.name, baring your <<undertop>> and $worn.under_lower.name. "Those need to go," <<he>> says. "Or they'll get in the way."
-						<<if $worn.under_lower.est is $worn.under_upper.set>>
-							You follow <<his>> instruction, and shuffle out of your $worn.under_upper.name while <<his>> back is turned.
-						<<else>>
-							You follow <<his>> instruction, and pull down your $worn.under_lower.name while <<his>> back is turned.
-						<</if>>
+			<<if $_skirt is 1>>
+				You <<nervously>> flip up your skirt, baring your $worn.under_lower.name.
+			<<elseif $worn.lower.set is $worn.upper.set>>
+				You <<nervously>> remove your $worn.upper.name, baring your <<undertop>> and $worn.under_lower.name.
+			<<else>>
+				You <<nervously>> pull down your $worn.lower.name, baring your $worn.under_lower.name.
+			<</if>>
+			"Those need to go," <<he>> says. "Or they'll get in the way."
+			<<if $worn.under_lower.set is $worn.under_upper.set>>
+				You follow <<his>> instruction, and shuffle out of your $worn.under_upper.name while <<his>> back is turned.
+			<<else>>
+				You follow <<his>> instruction, and pull down your $worn.under_lower.name while <<his>> back is turned.
+			<</if>>
+		<</if>>
+
+	<<elseif ["pubic", "left_thigh", "right_thigh"].includes($tattoo_bodypart)>>
+		"Alright," <<he>> says, pulling the curtain shut.
+		<<if $worn.lower.type.includes("naked")>>
+			<<if $tattoo_bodypart is "pubic" and !$worn.under_lower.type.includes("naked")>>
+				"Those need to go," <<he>> says. "Or they'll get in the way."
+				<<if $worn.under_lower.set is $worn.under_upper.set>>
+					You <<nervously>> follow <<his>> instruction, and shuffle out of your $worn.under_upper.name while <<his>> back is turned.
 				<<else>>
-					You <<nervously>> pull down your $worn.lower.name, baring your <<bottom>>.
+					You <<nervously>> follow <<his>> instruction, and pull down your $worn.under_lower.name while <<his>> back is turned.
 				<</if>>
+			<</if>>
+		<<else>>
+			<<if $_skirt is 1>>
+				"You'll have to pull your skirt right up. Don't want fabric getting in the way."
+				You <<nervously>> lift your $worn.lower.name, baring your <<undies>>.
+			<<elseif $worn.upper.set is $worn.lower.set>>
+				"You'll have to strip right down. Don't want fabric getting in the way."
+				You <<nervously>> remove your $worn.upper.name, baring your <<undertop>> and <<undies>>.
 			<<else>>
-				<<if !$worn.under_lower.type.includes("naked")>>
-					You <<nervously>> pull down your $worn.lower.name, baring your $worn.under_lower.name. "Those need to go," <<he>> says. "Or they'll get in the way."
-						<<if $worn.under_lower.est is $worn.under_upper.set>>
-							You follow <<his>> instruction, and shuffle out of your $worn.under_upper.name while <<his>> back is turned.
-						<<else>>
-							You follow <<his>> instruction, and pull down your $worn.under_lower.name while <<his>> back is turned.
-						<</if>>
+				"You'll have to take your bottoms off. Don't want the fabric getting in the way."
+				You <<nervously>> pull down your $worn.lower.name, baring your <<undies>>.
+			<</if>>
+
+			<<if $tattoo_bodypart is "pubic" and !$worn.under_lower.type.includes("naked")>>
+				"Those need to go too," <<he>> says.
+				<<if $worn.under_lower.set is $worn.under_upper.set>>
+					You follow <<his>> instruction, and shuffle out of your $worn.under_upper.name while <<his>> back is turned.
 				<<else>>
-					You <<nervously>> pull down your $worn.lower.name, baring your <<bottom>>.
+					You follow <<his>> instruction, and pull down your $worn.under_lower.name while <<his>> back is turned.
 				<</if>>
 			<</if>>
 		<</if>>
-	<<else>>
-		<<if $worn.under_lower.name isnot "naked">>
-			You <<nervously>> pull down your $worn.under_lower.name, baring your <<bottom>>.
-		<<else>>
-			You <<nervously>> turn, showing <<him>> your <<bottom>>.
+
+	<<elseif ["breasts", "back"].includes($tattoo_bodypart)>>
+		"Alright," <<he>> says, pulling the curtain shut.
+		<<if !$worn.upper.type.includes("naked")>>
+			<<if $worn.upper.open is 1 or $worn.upper.type.includes("naked")>>
+				"Could you pull your top down?" You <<nervously>> tug down your $worn.upper.name,
+			<<else>>
+				"Could you take your top off?" You <<nervously>> remove your $worn.upper.name,
+			<</if>>
+			exposing your <<undertop>>.
 		<</if>>
 	<</if>>
-<br><br>
-<<He>> pulls a lever, and the chair beside <<him>> reclines. "Lie on your side," <<he>> says.
-	<<if $worn.genitals.name isnot "naked">>
-		<<He>> doesn't mention your $worn.genitals.name. You assume that means it won't get in the way.
-	<</if>>
-	<<if $worn.under_lower.name is "naked">>
-		Bare from the waist down, you lie as instructed. "This will hurt a bit."
-	<<else>>
-		You lie as instructed. "This will hurt a bit."
-	<</if>>
-<br><br>
+	<br><br>
 
-<<elseif $tattoo_bodypart is "pubic" or $tattoo_bodypart is "left_thigh" or $tattoo_bodypart is "right_thigh">>
-"Alright," <<he>> says, pulling the curtain shut.
-	<<if $worn.lower.name is "naked">>
+	<<if ["left_bottom", "right_bottom", "pubic", "left_thigh", "right_thigh"].includes($tattoo_bodypart)>>
+		<<He>> pulls a lever, and the chair beside <<him>> reclines. "Lie <<print (["left_bottom", "right_bottom"].includes($tattoo_bodypart) ? "on your side" : "down")>>," <<he>> says.
 
-	<<elseif $worn.upper.set is $worn.lower.set and setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt isnot 1>>
-		"You'll have to strip right down. Don't want fabric getting in the way."
-
-		You <<nervously>> remove your $worn.upper.name, baring your <<undertop>> and <<undies>>.
-	<<elseif setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt isnot 1>>
-		"You'll have to take your bottoms off. Don't want the fabric getting in the way."
+		<<if $worn.genitals.name isnot "naked">>
+			<<He>> doesn't mention your $worn.genitals.name. You assume that means it won't get in the way.
+			<br><br>
+		<</if>>
 
-		You <<nervously>> pull down your $worn.lower.name, baring your <<undies>>.
+		<<if $worn.under_lower.type.includes("naked")>>
+			Bare from the waist down, you lie as instructed. "This will hurt a bit."
+		<<else>>
+			You lie as instructed. "This will hurt a bit."
+		<</if>>
 	<<else>>
-		"You'll have to pull your skirt right up. Don't want fabric getting in the way."
-
-		You <<nervously>> lift your $worn.lower.name, baring your <<undies>>.
-	<</if>>
-	<<He>> pulls a lever, and the chair beside <<him>> reclines. "Lie down," <<he>> says.
-	<<if $worn.genitals.name isnot "naked">>
-		<<He>> doesn't mention your $worn.genitals.name. You assume that means it won't get in the way.
+		<<He>> pulls a lever, and the chair beside <<him>> reclines. "Lie down." You lie as instructed. "This will hurt a bit."
 	<</if>>
+	<br><br>
 
-	<<if $worn.under_lower.name is "naked">>
-		Bare from the waist down, you lie as instructed. "This will hurt a bit."
-	<<else>>
-		You lie as instructed. "This will hurt a bit."
+	<<Hes>> not wrong. Your <<bodypart $tattoo_bodypart>> stings the whole way through, but you get used to it, becoming bored instead.
+	<<if $_embarassingType is "location">>
+		The artist remains professional despite the lewd location.
 	<</if>>
+	<br><br>
 
-<<elseif $tattoo_bodypart is "breasts" or $tattoo_bodypart is "back">>
-	"Alright," <<he>> says, pulling the curtain shut.
-	<<if $worn.upper.type.includes("naked")>>
-
-	<<elseif $worn.upper.open is 1 or $worn.upper.name is "naked">>
-		"Could you pull your top down?"
-		<<if $worn.under_upper.type.includes("naked")>>
-			You <<nervously>> tug down your $worn.upper.name, exposing your <<breasts>>.
-		<<else>>
-			You <<nervously>> tug down your $worn.upper.name, exposing your $worn.under_upper.name.
-		<</if>>
-
+	"There we go," <<he>> says at last, reaching for a mirror. You examine your new tattoo,
+	<<set $_colour to ($tattoo_parlour.lewd is 1 ? "lewd" : "purple")>>
+	<<if $tattoo_parlour.type is "text">>
+		<span @class="$_colour">"<<print $tattoo_parlour.writing>>"</span>
 	<<else>>
-		"Could you take your top off?"
-		<<if $worn.under_upper.type.includes("naked")>>
-			You <<nervously>> remove your $worn.upper.name, exposing your <<breasts>>.
-		<<else>>
-			You <<nervously>> remove your $worn.upper.name, exposing your $worn.under_upper.name.
-		<</if>>
-
+		a <span @class="$_colour"><<print $tattoo_parlour.writing>></span>
 	<</if>>
-	<<He>> pulls a lever, and the chair beside <<him>> reclines. "Lie down." You lie as instructed. "This will hurt a bit."
+	now permanently emblazoned on your <<bodypart $tattoo_bodypart>>.
+	<br><br>
+	The artist explains how to care for your skin while the tattoo is still raw. You get the gist. "Thanks for your custom," <<he>> says as you stand.
+	<<if $tattoo_bodypart is "left_bottom" or $tattoo_bodypart is "right_bottom">>
+		"Oh, and be careful sitting down."
+	<</if>>
+	<br><br>
 
-<<else>>
-	<<He>> pulls a lever, and the chair beside <<him>> reclines. "Lie down." You lie as instructed. "This will hurt a bit."
-<</if>>
-<br><br>
-<<Hes>> not wrong. Your <<bodypart $tattoo_bodypart>> stings the whole way through, but you get used to it, becoming bored instead.
-<<if $tattoo_bodypart is "pubic" or $tattoo_bodypart is "breasts" or $tattoo_bodypart is "left_bottom" or $tattoo_bodypart is "right_bottom">>
-The artist remains professional despite the lewd location.
-<</if>>
-<br><br>
-"There we go," <<he>> says at last, reaching for a mirror. You examine your new tattoo,
-<<if $tattoo_parlour.lewd is 1>>
-	<<if $tattoo_parlour.type is "text">><span class="lewd">"<<print $tattoo_parlour.writing>>"</span><<else>>a <span class="lewd"><<print $tattoo_parlour.writing>></span><</if>>
-<<else>>
-	<<if $tattoo_parlour.type is "text">><span class="purple">"<<print $tattoo_parlour.writing>>"</span><<else>>a <span class="purple"><<print $tattoo_parlour.writing>></span><</if>>
-<</if>>
-now permanently emblazoned on your <<bodypart $tattoo_bodypart>>.
-<br><br>
-The artist explains how to care for your skin while the tattoo is still raw. You get the gist. "Thanks for your custom," <<he>> says as you stand.
-<<if $tattoo_bodypart is "left_bottom" or $tattoo_bodypart is "right_bottom">>"Oh, and be careful sitting down."<</if>>
-<br><br>
-
-<<if $tattoo_parlour.writing is "Book Criminal >:(" or $tattoo_parlour.writing is "Book Criminal <3">>
-	<<earnFeat "A Crime Most Foul">>
-<</if>>
+	<<if $tattoo_parlour.writing is "Book Criminal >:(" or $tattoo_parlour.writing is "Book Criminal <3">>
+		<<earnFeat "A Crime Most Foul">>
+	<</if>>
 
-<<unset $tattoo_parlour>>
-<<unset $tattoo_bodypart>>
-<<unset $tattoo_choice>>
-<<endevent>>
+	<<unset $tattoo_parlour>>
+	<<unset $tattoo_bodypart>>
+	<<unset $tattoo_choice>>
+	<<endevent>>
 <</widget>>
 
 <<widget "bodywriting_dungeon_select">>
diff --git a/game/overworld-town/loc-school/widgets-events.twee b/game/overworld-town/loc-school/widgets-events.twee
index 73e63f44a7..a994585291 100644
--- a/game/overworld-town/loc-school/widgets-events.twee
+++ b/game/overworld-town/loc-school/widgets-events.twee
@@ -2020,190 +2020,115 @@
 		Whitney looms around a corner and rests <<his>> arm on your shoulder. <<His>> friends appear a moment later, trapping you against the wall.
 		<br><br>
 		"Just the slut I wanted to see," <<he>> says.
-		<<if $skin.forehead.special is "Whitney" and $skin.forehead.pen is "tattoo" and $bodywritingLvl gte 2>>
-			<<He>> examines your <span class="lewd">"<<print $skin.forehead.writing>>" tattoo</span>
-			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-			<<if $whitneyromance isnot 1>>
-				<<gtrauma>><<trauma 6>>
-			<</if>>
-			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
-			<br><br>
-			<<endevent>><<set $eventskip to 1>>
-			<<playground>>
-		<<elseif $skin.left_cheek.special is "Whitney" and $skin.left_cheek.pen is "tattoo" and $bodywritingLvl gte 2>>
-			<<if $worn.face.type.includes("mask")>>
-				<<He>> pulls your mask aside and examines your <span class="lewd">"<<print $skin.left_cheek.writing>>" tattoo.</span>
-			<<else>>
-				<<He>> examines your <span class="lewd">"<<print $skin.left_cheek.writing>>" tattoo</span>
-			<</if>>
-			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-			<<if $whitneyromance isnot 1>>
-				<<gtrauma>><<trauma 6>>
-			<</if>>
-			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
-			<br><br>
-			<<endevent>><<set $eventskip to 1>>
-			<<playground>>
-
-		<<elseif $skin.right_cheek.special is "Whitney" and $skin.right_cheek.pen is "tattoo" and $bodywritingLvl gte 2>>
-			<<if $worn.face.type.includes("mask")>>
-				<<He>> pulls your mask aside and examines your <span class="lewd">"<<print $skin.right_cheek.writing>>" tattoo.</span>
-			<<else>>
-				<<He>> examines your <span class="lewd">"<<print $skin.right_cheek.writing>>" tattoo</span>
-			<</if>>
-			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-			<<if $whitneyromance isnot 1>>
-				<<gtrauma>><<trauma 6>>
-			<</if>>
-			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
-			<br><br>
-			<<endevent>><<set $eventskip to 1>>
-			<<playground>>
+		<<set $phase to 0>>
+		<<if $bodywritingLvl gte 2>>
+			<<set $_targetLocs to ["forehead","left_cheek","right_cheek","left_shoulder","right_shoulder"].filter(loc => $skin[loc].special is "Whitney" or !$skin[loc].pen or ["pen","lipstick","mud"].includes($skin[loc].pen))>>
+			
+			<<set $_whitneyTattooedLocs to $_targetLocs.filter(loc => $skin[loc].special is "Whitney" and $skin[loc].pen is "tattoo")>>
+			<<set $_whitneyWritingLocs to $_targetLocs.filter(loc => $skin[loc].special is "Whitney")>>
+			<<set $_erasableWritingLocs to $_targetLocs.filter(loc => ["pen","lipstick","mud"].includes($skin[loc].pen))>>
+			<<set $_writableLocs to $_targetLocs.filter(loc => !$skin[loc].pen)>>
+			
+			<<if $_whitneyTattooedLocs.length gte 1>>
+				<<set $_loc to $_whitneyTattooedLocs.random()>>
+				<<if ($_loc is "left_cheek" or $_loc is "right_cheek") and $worn.face.type.includes("mask")>>
+					<<He>> pulls your mask aside and
+				<<elseif ($_loc is "left_shoulder" or $_loc is "right_shoulder") and !($worn.upper.open is 1 or $worn.upper.name is "naked")>>
+					<<He>> jerks your $worn.upper.name down and
+				<<else>>
+					<<He>>
+				<</if>>
+				examines your <span class="lewd">"<<print $skin[$_loc].writing>>" tattoo.</span>
+				"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
+				<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>>
+
+			<<elseif $_whitneyWritingLocs.length gte 1>>
+				<<set $_loc to $_whitneyWritingLocs.random()>>
+				<<if $_loc is "forehead">>
+					<<He>> strokes your forehead. 
+				<<elseif $_loc is "left_cheek" or $_loc is "right_cheek">>
+					<<if $worn.upper.type.includes("mask")>>
+						<<He>> pulls your mask aside and strokes your cheek.
+					<<else>>
+						<<He>> strokes your cheek.
+					<</if>>
+				<<elseif $_loc is "left_shoulder" or $_loc is "right_shoulder">>
+					<<if !($worn.upper.open is 1 or $worn.upper.name is "naked")>>
+						<<He>> tugs your $worn.upper.name down and strokes your shoulder.
+					<<else>>
+						<<He>> strokes your shoulder.
+					<</if>>
+				<</if>>
+				"Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
+				<<set $phase to 2>><<set $whitneyDaily.writingTarget to $_loc>>
+				<br><br>
+				<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
+				<br>
+				<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+				<br>
 
-		<<elseif $skin.left_shoulder.special is "Whitney" and $skin.left_shoulder.pen is "tattoo" and $bodywritingLvl gte 2>>
-			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-				<<He>> examines your <span class="lewd">"<<print $skin.left_shoulder.writing>>" tattoo.</span>
-			<<else>>
-				<<He>> jerks your $worn.upper.name down and examines your <span class="lewd">"<<print $skin.left_shoulder.writing>>" tattoo.</span>
-			<</if>>
-			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-			<<if $whitneyromance isnot 1>>
-				<<gtrauma>><<trauma 6>>
-			<</if>>
-			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
-			<br><br>
-			<<endevent>><<set $eventskip to 1>>
-			<<playground>>
-		<<elseif $skin.right_shoulder.special is "Whitney" and $skin.right_shoulder.pen is "tattoo" and $bodywritingLvl gte 2>>
-			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-				<<He>> examines your <span class="lewd">"<<print $skin.right_shoulder.writing>>" tattoo.</span>
-			<<else>>
-				<<He>> jerks your $worn.upper.name down and examines your <span class="lewd">"<<print $skin.right_shoulder.writing>>" tattoo.</span>
-			<</if>>
-			"Good. Still labelled properly." <<He>> assaults your face with <<his>> tongue, then shoves you away. "Later slut."
-			<<glove>><<npcincr Whitney love 1>><<gdom>><<npcincr Whitney dom 1>><<glust>><<npcincr Whitney lust 1>>
-			<<if $whitneyromance isnot 1>>
-				<<gtrauma>><<trauma 6>>
-			<</if>>
-			<<gstress>><<stress 6>><<garousal>><<arousal 600>>
-			<br><br>
-			<<endevent>><<set $eventskip to 1>>
-			<<playground>>
-		<<elseif $skin.forehead.special is "Whitney" and $bodywritingLvl gte 2>>
-			<<He>> strokes your forehead. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-			<br><br>
-			<<set $phase to 2>>
-			<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
-		<<elseif ($skin.left_cheek.special is "Whitney" or $skin.right_cheek.special is "Whitney") and $bodywritingLvl gte 2>>
-			<<if $worn.upper.type.includes("mask")>>
-				<<He>> pulls your mask aside and strokes your cheek. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-			<<else>>
-				<<He>> strokes your cheek. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-			<</if>>
-			<br><br>
-			<<set $phase to 2>>
-			<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
-		<<elseif ($skin.left_shoulder.special is "Whitney" or $skin.right_shoulder.special is "Whitney") and $bodywritingLvl gte 2>>
-			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-				<<He>> strokes your shoulder. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-			<<else>>
-				<<He>> tugs your $worn.upper.name down and strokes your shoulder. "Still labelled too. Good." <<He>> grasps your collar. "Let's make it permanent." <<He>> pulls you towards the street.
-			<</if>>
-			<br><br>
-			<<set $phase to 2>>
-			<<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
-		<<elseif $skin.forehead.pen is "pen" and $bodywritingLvl gte 2>>
-			<<bodywriting_clear forehead>>
-			<<He>> leans in and licks your forehead, then wipes it with <<his>> sleeve. "I've thought of something better." <<He>> pulls a pen from <<his>> pocket. "Hold still."
-			<br><br>
-			<<set $phase to 1>>
-			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
-		<<elseif ($skin.left_cheek.pen is "pen" or $skin.right_cheek.pen is "pen" or $skin.left_cheek.pen is "lipstick" or $skin.right_cheek.pen is "lipstick" or $skin.left or $skin.left_cheek.pen is "mud" or $skin.right_cheek.pen is "pen" or $skin.left) and $bodywritingLvl gte 2>>
-			<<if $skin.left_cheek.pen is "pen" or $skin.left_cheek is "lipstick" or $skin.left_cheek is "mud">>
-				<<bodywriting_clear left_cheek>>
-			<<else>>
-				<<bodywriting_clear right_cheek>>
-			<</if>>
-			<<if $worn.face.type.includes("mask")>>
-				<<He>> leans in, pulls your mask aside, and licks your cheek.
-			<<else>>
-				<<He>> leans in and licks your cheek.
-			<</if>>
-			"I've thought of something better." <<He>> rubs your face with <<his>> sleeve while pulling a pen from <<his>> pocket. "Hold still."
-			<br><br>
-			<<set $phase to 1>>
-			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
+			<<elseif $_erasableWritingLocs.length gte 1>>
+				<<set $_loc to $_erasableWritingLocs.random()>>
+				<<bodywriting_clear $_loc>>
+				<<if $_loc is "forehead">>
+					<<He>> leans in and licks your forehead, then wipes it with <<his>> sleeve. "I've thought of something better." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+				<<elseif $_loc is "left_cheek" or $_loc is "right_cheek">>
+					<<if $worn.face.type.includes("mask")>>
+						<<He>> leans in, pulls your mask aside, and licks your cheek. "I've thought of something better." <<He>> rubs your face with <<his>> sleeve while pulling a pen from <<his>> pocket. "Hold still."
+					<<else>>
+						<<He>> leans in and licks your cheek. "I've thought of something better." <<He>> rubs your face with <<his>> sleeve while pulling a pen from <<his>> pocket. "Hold still."
+					<</if>>
+				<<elseif $_loc is "left_shoulder" or $_loc is "right_shoulder">>
+					<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
+						<<He>> leans in and licks your shoulder, while pulling a pen from <<his>> pocket. "I've thought of something better." <<He>> rubs your shoulder with <<his>> sleeve. "Hold still."
+					<<else>>
+						<<He>> leans in, pulls your $worn.upper.name aside, and licks your shoulder. "I've thought of something better." <<He>> pulls a pen from <<his>> pocket while rubbing your shoulder with <<his>> sleeve. "Hold still."
+					<</if>>
+				<</if>>
+				<<set $phase to 1>><<set $whitneyDaily.writingTarget to $_loc>>
+
+			<<elseif $_writableLocs.length gte 1>>
+				<<set $_loc to $_writableLocs.random()>>
+				<<if $_loc is "forehead">>
+					<<He>> leans in and licks your forehead.
+				<<elseif $_loc is "left_cheek" or $_loc is "right_cheek">>
+					<<if $worn.face.type.includes("mask")>>
+						<<He>> leans in, pulls your mask aside, and licks your cheek.
+					<<else>>
+						<<He>> leans in and licks your cheek.
+					<</if>>
+				<<elseif $_loc is "left_shoulder" or $_loc is "right_shoulder">>
+					<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
+						<<He>> leans in and licks your shoulder.
+					<<else>>
+						<<He>> leans in, pulls your $worn.upper.name aside, and licks your shoulder.
+					<</if>>
+				<</if>>
+				"I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+				<<set $phase to 1>><<set $whitneyDaily.writingTarget to $_loc>>
 
-		<<elseif ($skin.left_shoulder.pen is "pen" or $skin.right_shoulder.pen is "pen" or $skin.left_shoulder.pen is "lipstick" or $skin.right_shoulder.pen is "lipstick" or $skin.left_shoulder.pen is "mud" or $skin.right_shoulder.pen is "mud") and $bodywritingLvl gte 2>>
-			<<if $skin.left_shoulder.pen is "pen" or $skin_left_shoulder is "lipstick" or $skin.left_shoulder is "mud">>
-				<<bodywriting_clear left_shoulder>>
 			<<else>>
-				<<bodywriting_clear right_shoulder>>
-			<</if>>
-			<<if $worn.upper.open is 1 or $worn.upper.name is "naked">>
-				<<He>> leans in and licks your shoulder, while pulling a pen from <<his>> pocket. "I've thought of something better." <<He>> rubs your shoulder with <<his>> sleeve. "Hold still."
-			<<else>>
-				<<He>> leans in, pulls your $worn.upper.name aside, and licks your shoulder "I've thought of something better." <<He>> pulls a pen from <<his>> pocket while rubbing your shoulder with <<his>> sleeve. "Hold still."
+				<<He>> grasps your hair, pulls your head back, and assaults your face with <<his>> tongue. <<He>> shoves you away before you can respond.
+				<br><br>
+				"Later slut." <<He>> saunters away with <<his>> friends.
 			<</if>>
+		<<else>>
+			<<He>> grasps your hair, pulls your head back, and assaults your face with <<his>> tongue. <<He>> shoves you away before you can respond.
 			<br><br>
-			<<set $phase to 1>>
-			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
+			"Later slut." <<He>> saunters away with <<his>> friends.
+		<</if>>
 
-		<<elseif !$skin.forehead.pen and $bodywritingLvl gte 2>>
-			<<He>> leans in and licks your forehead. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
+		<<if $phase is 1>>
 			<br><br>
-			<<set $phase to 1>>
 			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
 			<br>
 			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
 			<br>
-		<<elseif (!$skin.left_cheek.pen or !$skin.right_cheek.pen) and $bodywritingLvl gte 2>>
-			<<He>> leans in and licks your cheek. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
-			<br><br>
-			<<set $phase to 1>>
-			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
-		<<elseif (!$skin.left_shoulder.pen or !$skin.right_shoulder.pen) and $bodywritingLvl gte 2>>
-			<<He>> leans in and licks your shoulder. "I've decided to mark you properly." <<He>> pulls a pen from <<his>> pocket. "Hold still."
-			<br><br>
-			<<set $phase to 1>>
-			<<link [[Let it happen (0:20)|Bully Tattoo Write]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
-			<br>
-			<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-			<br>
-		<<else>>
-			<<He>> grasps your hair, pulls your head back, and assaults your face with <<his>> tongue. <<He>> shoves you away before you can respond.
-			<br><br>
-			"Later slut." <<He>> saunters away with <<his>> friends.
-			<<glust>>
+		<<elseif $phase is 0>>
 			<<if $whitneyromance isnot 1>>
 				<<gtrauma>><<trauma 6>>
 			<</if>>
-			<<gstress>><<garousal>><<stress 6>><<arousal 600>><<npcincr Whitney lust 1>>
+			<<gstress>><<stress 6>><<garousal>><<arousal 600>><<glust>><<npcincr Whitney lust 1>>
 			<br><br>
 			<<endevent>><<set $eventskip to 1>>
 			<<playground>>
diff --git a/game/overworld-town/loc-shop/tattoo.twee b/game/overworld-town/loc-shop/tattoo.twee
index 8263fc567c..a0c1d83893 100644
--- a/game/overworld-town/loc-shop/tattoo.twee
+++ b/game/overworld-town/loc-shop/tattoo.twee
@@ -21,17 +21,16 @@
 
 <<set $outside to 0>><<effects>><<set $lock to 0>>
 
-You are in the tattoo parlour. The artists here can turn anything drawn on you into a tattoo. They also have a selection of tattoo designs available. Costs £500.
+You are in the tattoo parlour. The artists here can turn anything drawn on you into a tattoo. They also have a selection of tattoo designs available. Costs <<printmoney 50000>>.
 <br><br>
 
 <<if $daystate is "night">>
 	You are alone in the darkness.
+	<br><br>
 <<elseif $exposed gte 1>>
 	You hide in a cupboard to protect your dignity.
-<<else>>
-
+	<br><br>
 <</if>>
-<br><br>
 
 <<if $stress gte $stressmax>>
 	<<passoutshop>>
@@ -74,41 +73,51 @@ You are in the tattoo parlour. The artists here can turn anything drawn on you i
 <<effects>>
 
 <<for _active_bodypart range setup.bodyparts>>
-	<<if ["pen","marker","lipstick","mud"].includes($skin[_active_bodypart].pen)>>
-		<<if $money gte 50000>>
-		You have <<if $skin[_active_bodypart].type is "text">><span class="pink">"<<print $skin[_active_bodypart].writing>>"</span> written<<else>>a $skin[_active_bodypart].writing drawn<</if>> on your <<bodypart _active_bodypart>>.
-			<<if ($skin[_active_bodypart].special is "bestiality" or $skin[_active_bodypart].special is "Black Wolf" or $skin[_active_bodypart].special is "Great Hawk") and $deviancy lte 34>>
-				<<if (_active_bodypart is "left_bottom" or _active_bodypart is "right_bottom" or _active_bodypart is "pubic" or _active_bodypart is "breasts") and $exhibitionism lte 34>>
-					<span class="blue">You can't bear to show your <<bodypart _active_bodypart>> to the tattoo artist, and you're not deviant enough to have such a thing made into a tattoo anyway.</span>
-				<<else>>
-					<span class="blue">You're not deviant enough to have such a thing made into a tattoo.</span>
-				<</if>>
-			<<elseif $skin[_active_bodypart].lewd is 1 and $skin[_active_bodypart].special isnot "bestiality" and $promiscuity lte 34>>
-				<<if (_active_bodypart is "left_bottom" or _active_bodypart is "right_bottom" or _active_bodypart is "pubic" or _active_bodypart is "breasts") and $exhibitionism lte 34>>
-					<span class="blue">You can't bear to show your <<bodypart _active_bodypart>> to the tattoo artist, and you're not lewd enough to have such a thing made into a tattoo anyway.</span>
+	<<set _part to $skin[_active_bodypart]>>
+	<<switch _part.pen>>
+		<<case "pen" "marker" "lipstick" "mud">>
+			You have
+			<<if _part.type is "text">>
+				<span class="pink">"<<print _part.writing>>"</span> written
+			<<else>>
+				<span class="pink">a _part.writing</span> drawn
+			<</if>>
+			on your <<bodypart _active_bodypart>>.
+			<<set _tooShy to (["left_bottom","right_bottom","pubic","breasts"].includes(_active_bodypart) and $exhibitionism lte 34)>>
+			<<set _deviant to ["bestiality", "Black Wolf", "Great Hawk"].includes(_part.special)>>
+			<<set _lewd to _part.lewd is 1>>
+			<<if $money lte 50000>>
+				<span class="red">You cannot afford to turn it into a tattoo.</span>
+			<<elseif (_deviant and $deviancy lte 34) or (_lewd and $promiscuity lte 34)>>
+				<<set _lewdOrDeviant to (_deviant ? "deviant" : "lewd")>>
+				<<if _tooShy>>
+					<span class="blue">You can't bear to show your <<bodypart _active_bodypart>> to the tattoo artist, and you're not _lewdOrDeviant enough to have such a thing made into a tattoo anyway.</span>
 				<<else>>
-					<span class="blue">You're not lewd enough to have such a thing made into a tattoo.</span>
+					<span class="blue">You're not _lewdOrDeviant enough to have such a thing made into a tattoo.</span>
 				<</if>>
-			<<elseif (_active_bodypart is "left_bottom" or _active_bodypart is "right_bottom" or _active_bodypart is "pubic" or _active_bodypart is "breasts") and $exhibitionism lte 34>>
+				<<unset _lewdOrDeviant>>
+			<<elseif _tooShy>>	
 				<span class="blue">You can't bear to show your <<bodypart _active_bodypart>> to the tattoo artist.</span>
 			<<else>>
-			<<capture _active_bodypart>> | <<link [[Turn into tattoo (£500 1:00)|Tattoo Bodywriting]]>><<pass 60>><<set $money -= 50000>><<set $tattoo_bodypart to _active_bodypart>><<set $tattoo_parlour to clone($skin[_active_bodypart])>><<if $skin[_active_bodypart].lewd is 1 or $skin[_active_bodypart].special is "bestiality" or $skin[_active_bodypart].special is "Black Wolf" or $skin[_active_bodypart].special is "Great Hawk">><<control 50>><<else>><<control 25>><</if>><<set $skin[_active_bodypart].pen to "tattoo">><<pain 6>><</link>><</capture>> <<if $skin[_active_bodypart].lewd is 1 or $skin[_active_bodypart].special is "bestiality" or $skin[_active_bodypart].special is "Black Wolf" or $skin[_active_bodypart].special is "Great Hawk">><<gggcontrol>><<else>><<ggcontrol>><</if>>
-			<</if>><<gpain>>
-		<br>
-		<</if>>
-	<<elseif $skin[_active_bodypart].pen is "tattoo">>
-		Your <<bodypart _active_bodypart>> is already tattooed.
-		<br>
-	<<elseif $skin[_active_bodypart].pen is "brand">>
-		Your <<bodypart _active_bodypart>> is <span class="red">branded</span>.
-		<br>
-	<<elseif $skin[_active_bodypart].pen is "magic">>
-		Your <<bodypart _active_bodypart>> has a magical <span class="pink">seal</span>.
-		<br>
-	<<elseif !$skin[_active_bodypart].pen>>
-		Nothing is written on your <<bodypart _active_bodypart>>.
-		<br>
-	<</if>>
+				<<capture _active_bodypart _part _deviant _lewd>>
+					| <<link [[Turn into tattoo (£500 1:00)|Tattoo Bodywriting]]>>
+						<<pass 60>><<set $money -= 50000>><<set $tattoo_bodypart to _active_bodypart>><<set $tattoo_parlour to clone(_part)>>
+						<<if _lewd or _deviant>><<control 50>><<else>><<control 25>><</if>>
+						<<set _part.pen to "tattoo">><<pain 6>>
+					<</link>><<if _lewd or _deviant>><<gggcontrol>><<else>><<ggcontrol>><</if>><<gpain>>
+				<</capture>>
+			<</if>>
+			<<unset _tooShy>><<unset _deviant>><<unset _lewd>>
+		<<case "tattoo">>
+			Your <<bodypart _active_bodypart>> is already tattooed.
+		<<case "brand">>
+			Your <<bodypart _active_bodypart>> is <span class="red">branded</span>.
+		<<case "magic">>
+			Your <<bodypart _active_bodypart>> has a magical <span class="pink">seal</span>.
+		<<default>>
+			Nothing is written on your <<bodypart _active_bodypart>>.
+	<</switch>>
+	<br>
 <</for>>
 <br>
 <<link [[Back|Tattoo Parlour]]>><</link>>
@@ -122,9 +131,8 @@ They have a board displaying a number of tattoo designs.
 
 Location:<br>
 <<for _active_bodypart range setup.bodyparts>>
-	<<if $skin[_active_bodypart].writing>>
-
-	<<else>><<set _bodypart_detected to 1>>
+	<<if !$skin[_active_bodypart].writing>>
+		<<set _bodypart_detected to 1>>
 		<label>Your <<bodypart _active_bodypart>> <<capture _active_bodypart>><<radiobutton "$tattoo_bodypart" _active_bodypart>><</capture>></label>
 		<br>
 	<</if>>
diff --git a/game/overworld-town/special-whitney/main.twee b/game/overworld-town/special-whitney/main.twee
index 4cf00e0fad..99a76e8061 100644
--- a/game/overworld-town/special-whitney/main.twee
+++ b/game/overworld-town/special-whitney/main.twee
@@ -1042,17 +1042,17 @@ You stand on the other side. You're in an open space behind a large building. Th
 
 :: Bully Outside Fight
 <<if $fightstart is 1>>
-<<set $fightstart to 0>>
+	<<set $fightstart to 0>>
 
-<<neutral 1>>
+	<<neutral 1>>
 
-<<maninit>>
-<<set $enemytrust -= 100>>
-<<set $enemyanger += 200>>
-<<npcidlegenitals>><<hand_gag 0 left>>
-You shove Whitney away and try to escape, but <<he>> grabs you from behind and wraps <<his>> arm around your mouth.
-<br><br>
-<<if $delinquency lt 400>><<enable_rescue>><</if>>
+	<<maninit>>
+	<<set $enemytrust -= 100>>
+	<<set $enemyanger += 200>>
+	<<npcidlegenitals>><<hand_gag 0 left>>
+	You shove Whitney away and try to escape, but <<he>> grabs you from behind and wraps <<his>> arm around your mouth.
+	<br><br>
+	<<if $delinquency lt 400>><<enable_rescue>><</if>>
 <</if>>
 
 <<effects>>
@@ -1074,64 +1074,62 @@ You shove Whitney away and try to escape, but <<he>> grabs you from behind and w
 <<set _phase to $phase>>
 <<if $enemyhealth lte 0>>
 
-You push <<him>> to the ground, giving you a chance to escape. <<tearful>> you shove <<his>> friends aside and flee to safety.
-<br><br>
+	You push <<him>> to the ground, giving you a chance to escape. <<tearful>> you shove <<his>> friends aside and flee to safety.
+	<br><br>
 
-<<clotheson>>
-<<endcombat>>
+	<<clotheson>>
+	<<endcombat>>
 
-<<set $eventskip to 1>>
-<<playground>>
+	<<set $eventskip to 1>>
+	<<playground>>
 
 <<elseif $enemyarousal gte $enemyarousalmax>>
-<<ejaculation "short">>
+	<<ejaculation "short">>
 
-"You... stupid..." <<he>> pants, leaning against the wall. <<His>> friends are so bemused by <<his>> state that they don't notice you slip away. <<tearful>> you escape to safety.
-<<llust>><<npcincr Whitney lust -20>>
-<br><br>
+	"You... stupid..." <<he>> pants, leaning against the wall. <<His>> friends are so bemused by <<his>> state that they don't notice you slip away. <<tearful>> you escape to safety.
+	<<llust>><<npcincr Whitney lust -20>>
+	<br><br>
 
-<<clotheson>>
-<<endcombat>>
+	<<clotheson>>
+	<<endcombat>>
 
-<<set $eventskip to 1>>
-<<playground>>
+	<<set $eventskip to 1>>
+	<<playground>>
 
 <<elseif $alarm is 1 and $rescue is 1>>
 
-Your cries attract attention. "Crybaby," Whitney says. "We'll get you next time." <<He>> and <<his>> friends leave. <<tearful>> you struggle to your feet.
-<br><br>
+	Your cries attract attention. "Crybaby," Whitney says. "We'll get you next time." <<He>> and <<his>> friends leave. <<tearful>> you struggle to your feet.
+	<br><br>
 
-<<clotheson>>
-<<endcombat>>
+	<<clotheson>>
+	<<endcombat>>
 
-<<set $eventskip to 1>>
-<<playground>>
+	<<set $eventskip to 1>>
+	<<playground>>
 
 <<else>>
 
-You're too battered and bruised to resist.
-<br><br>
+	You're too battered and bruised to resist.
+	<br><br>
 
-<<endcombat>>
+	<<endcombat>>
 
-<<npc Whitney>><<person1>>
+	<<npc Whitney>><<person1>>
 
 	<<if $bullyeventoutside is 1>>
-	<<link [[Next|Bully Theft]]>><</link>>
+		<<link [[Next|Bully Theft]]>><</link>>
 	<<elseif $bullyeventoutside is 2>>
-	<<link [[Next|Bully Light]]>><</link>>
+		<<link [[Next|Bully Light]]>><</link>>
 	<<elseif $bullyeventoutside is 3>>
-	<<link [[Next|Bully Romance]]>><</link>>
+		<<link [[Next|Bully Romance]]>><</link>>
 	<<elseif $bullyeventoutside is 4>>
-	<<link [[Next|Bully Theft]]>><</link>>
+		<<link [[Next|Bully Theft]]>><</link>>
 	<<elseif $bullyeventoutside is 5>>
-	<<link [[Next|Bully Whore]]>><</link>>
+		<<link [[Next|Bully Whore]]>><</link>>
+	<<elseif _phase is 1>>
+		<<link [[Next|Bully Tattoo Write]]>><</link>>
 	<<else>>
-		<<if _phase is 1>>
-			<<link [[Next|Bully Tattoo Write]]>><</link>>
-		<<else>>
-			<<link [[Next|Bully Tattoo]]>><</link>>
-		<</if>>
+		<<link [[Next|Bully Tattoo]]>><</link>>
 	<</if>>
 
 <</if>>
@@ -3447,26 +3445,12 @@ You shove Whitney away. Some of <<his>> friends laugh. <<He>> silences them with
 :: Bully Tattoo Write
 <<effects>>
 
-<<if $skin.forehead.special is "Whitney">>
-	Whitney examines your forehead with a satisfied smile.
-<<elseif !$skin.left_cheek.special is "Whitney">>
-	Whitney examines your cheek with a satisfied smile.
-<<elseif !$skin.right_cheek.special is "Whitney">>
-	Whitney examines your cheek with a satisfied smile.
-<<elseif !$skin.left_shoulder.special is "Whitney">>
-	Whitney examines your shoulder with a satisfied smile.
-<<elseif !$skin.right_shoulder.special is "Whitney">>
-	Whitney examines your shoulder with a satisfied smile.
-<<elseif !$skin.forehead.writing>>
-	Whitney leans forward, pen in hand, and scrawls on your forehead. <<He>> steps back to admire <<his>> handiwork, before snatching a mirror from one of <<his>> friends. <<He>> holds it up for you. Your forehead now reads: <<bodywriting_npc_whitney forehead>>
-<<elseif !$skin.left_cheek.writing>>
-	Whitney leans forward, pen in hand, and scrawls on your cheek. <<He>> steps back to admire <<his>> handiwork, before snatching a mirror from one of <<his>> friends. <<He>> holds it up for you. Your cheek now reads: <<bodywriting_npc_whitney left_cheek>>
-<<elseif !$skin.right_cheek.writing>>
-	Whitney leans forward, pen in hand, and scrawls on your cheek. <<He>> steps back to admire <<his>> handiwork, before snatching a mirror from one of <<his>> friends. <<He>> holds it up for you. Your cheek now reads: <<bodywriting_npc_whitney right_cheek>>
-<<elseif !$skin.left_shoulder.writing>>
-	Whitney leans forward, pen in hand, and scrawls on your shoulder. <<He>> steps back to admire <<his>> handiwork, before snatching a mirror from one of <<his>> friends. <<He>> holds it up for you. Your shoulder now reads: <<bodywriting_npc_whitney left_shoulder>>
-<<else>>
-	Whitney leans forward, pen in hand, and scrawls on your shoulder. <<He>> steps back to admire <<his>> handiwork, before snatching a mirror from one of <<his>> friends. <<He>> holds it up for you. Your shoulder now reads: <<bodywriting_npc_whitney right_shoulder>>
+<<set _loc to $whitneyDaily.writingTarget>>
+<<set _loc_text to _loc.replace(/(left_|right_)/, "")>> <!-- example: converts "left_cheek" to just "cheek", or "right_shoulder" to just "shoulder" -->
+<<if $skin[_loc].special is "Whitney">>
+	Whitney examines your _loc_text with a satisfied smile.
+<<elseif !$skin[_loc].writing>>
+	Whitney leans forward, pen in hand, and scrawls on your _loc_text. <<He>> steps back to admire <<his>> handiwork, before snatching a mirror from one of <<his>> friends. <<He>> holds it up for you. Your _loc_text now reads: <<bodywriting_npc_whitney _loc>>
 <</if>>
 <br><br>
 
@@ -3480,8 +3464,8 @@ You shove Whitney away. Some of <<his>> friends laugh. <<He>> silences them with
 <<link [[Let it happen (0:20)|Bully Tattoo]]>><<sub 1>><<npcincr Whitney dom 1>><<trauma 6>><<stress 6>><</link>><<gtrauma>><<gstress>><<gdom>>
 <br>
 <<if $pain lt 100>>
-<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
-<br>
+	<<link [[Fight|Bully Outside Fight]]>><<def 1>><<npcincr Whitney dom -1>><<set $fightstart to 1>><</link>><<ldom>>
+	<br>
 <</if>>
 
 :: Bully Tattoo
@@ -3499,14 +3483,7 @@ You're pulled from the playground and into the street by Whitney and <<his>> fri
 Whitney drags you to the high street, and into the shopping centre. You come to a stop outside tattoo parlour.
 <br><br>
 
-"Here's what you're gonna do," Whitney says, stroking the ink on your
-<<if $skin.forehead.special is "Whitney" and $skin.forehead.pen isnot "tattoo">>
-	forehead.
-<<elseif $skin.left_cheek.special is "Whitney" and $skin.left_cheek.pen isnot "tattoo" or $skin.right_cheek.special is "Whitney" and $skin.right_cheek.pen isnot "tattoo">>
-	cheek.
-<<else>>
-	shoulder.
-<</if>>
+"Here's what you're gonna do," Whitney says, stroking the ink on your <<print $whitneyDaily.writingTarget.replace(/(left_|right_)/, "")>>.
 "You're gonna go in there and get those words tattooed on." <<He>> shoves a crumpled bundle of banknotes against your chest. "I'll even pay for it. Aren't I nice?" <<He>> kicks you through the door.
 <<set $money += 20000>>
 <br><br>
@@ -3526,34 +3503,30 @@ The interior is cramped. A <<person>> sits at a desk, reading a magazine. A row
 :: Bully Tattoo Accept
 <<effects>>
 
-<<set $tattoo_parlour to {}>>
-<<if $skin.forehead.special is "Whitney">>
-	<<set $skin.forehead.pen to "tattoo">><<set $tattoo_parlour to clone($skin.forehead)>><<set $tattoo_bodypart to "forehead">>
-<<elseif $skin.left_cheek.special is "Whitney">>
-	<<set $skin.left_cheek.pen to "tattoo">><<set $tattoo_parlour to clone($skin.left_cheek)>><<set $tattoo_bodypart to "left_cheek">>
-<<elseif $skin.right_cheek.special is "Whitney">>
-	<<set $skin.right_cheek.pen to "tattoo">><<set $tattoo_parlour to clone($skin.right_cheek)>><<set $tattoo_bodypart to "right_cheek">>
-<<elseif $skin.left_shoulder.special is "Whitney">>
-	<<set $skin.left_shoulder.pen to "tattoo">><<set $tattoo_parlour to clone($skin.left_shoulder)>><<set $tattoo_bodypart to "left_shoulder">>
-<<else>>
-	<<set $skin.right_shoulder.pen to "tattoo">><<set $tattoo_parlour to clone($skin.right_shoulder)>><<set $tattoo_bodypart to "right_shoulder">>
-<</if>>
+<<set _loc to $whitneyDaily.writingTarget>>
+<<set $skin[_loc].pen to "tattoo">>
+<<set _writing to $skin[_loc].writing>>
 
 Blushing, you tell the artist what you want. <<Hes>> unfazed by the request. "Young lovers, eh?" <<he>> says. "Bit of a lewd one, but I won't judge. Please have a seat."
 <br><br>
-You sit as instructed. "This will sting a bit." <<Hes>> not wrong. Your <<bodypart $tattoo_bodypart>> stings the whole way through, but you get used to it, becoming bored instead.
+You sit as instructed. "This will sting a bit." <<Hes>> not wrong. Your <<bodypart _loc>> stings the whole way through, but you get used to it, becoming bored instead.
 
 "There we go," <<he>> says at least, reaching for a mirror. You examine your new tattoo,
 
-<span class="lewd"><<if $tattoo_parlour.type is "text">>"<<print $tattoo_parlour.writing>>"<<else>>a <<print $tattoo_parlour.writing>><</if>></span>
-
-now permanently emblazoned on your <<bodypart $tattoo_bodypart>>.
+<span class="lewd">
+<<if $skin[_loc].type is "text">>
+	"_writing"
+<<else>>
+	a _writing
+<</if>>
+</span>
+now permanently emblazoned on your <<bodypart _loc>>.
 <br><br>
+
 The artist explains how to care for your skin while the tattoo is still raw. You get the gist. "Thanks for your custom," <<he>> says at the end.
 <br><br>
 
-<<unset $tattoo_parlour>>
-<<unset $tattoo_bodypart>>
+<<run delete $whitneyDaily.writingTarget>>
 <<link [[Next|Bully Tattoo Accept 2]]>><</link>>
 <br>
 
@@ -3587,20 +3560,20 @@ You grasp Whitney's hair and pull <<his>> head to face yours. <<He>> barely has
 <<He>> kisses back after the initial shock. <<His>> pulse races by the time you pull away.
 
 <<if $submissive gte 1150>>
-"Thanks for paying for my tattoo," you say.
-<br><br>
+	"Thanks for paying for my tattoo," you say.
+	<br><br>
 
-"D-don't mention it," <<he>> responds, looking flushed. "Anything for my slut."
+	"D-don't mention it," <<he>> responds, looking flushed. "Anything for my slut."
 <<elseif $submissive lte 850>>
-"Are you blushing?" you tease. "Cute."
-<br><br>
+	"Are you blushing?" you tease. "Cute."
+	<br><br>
 
-"F-fuck off," <<he>> says, blushing harder. "It's just warm in here."
+	"F-fuck off," <<he>> says, blushing harder. "It's just warm in here."
 <<else>>
-"Thanks for paying for my tattoo," you say.
-<br><br>
+	"Thanks for paying for my tattoo," you say.
+	<br><br>
 
-"D-don't mention it," <<he>> responds, looking flushed. "Anything for my slut."
+	"D-don't mention it," <<he>> responds, looking flushed. "Anything for my slut."
 <</if>>
 <<He>> looks at <<his>> watch. "I've got places to be. See you later."
 <br><br>
-- 
GitLab


From 14cb1a434ab7b000ed0a3cc8503d6b5939ae1138 Mon Sep 17 00:00:00 2001
From: Crimson Tide <literallyjustrandomletters@gmail.com>
Date: Sat, 17 Sep 2022 09:47:21 +0000
Subject: [PATCH 37/50] Contributed scenes

---
 game/03-JavaScript/ingame.js                 |  13 +-
 game/base-system/text.twee                   |  24 +-
 game/overworld-town/special-kylar/main.twee  |  37 ++-
 game/overworld-town/special-kylar/manor.twee |  52 +++-
 game/overworld-town/special-robin/main.twee  | 248 ++++++++++++++++++-
 5 files changed, 352 insertions(+), 22 deletions(-)

diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index 21f47dbc1a..93b5e2d8c3 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -654,8 +654,12 @@ function getRobinLocation() {
 		T.robin_location = V.robinlocationoverride.location;
 	} else if (["docks", "landfill", "dinner", "pillory"].includes(V.robinmissing)) {
 		T.robin_location = V.robinmissing;
-	} else if (!between(V.hour, 7, 20)) { // if hour is 6 or lower, or 21 or higher
-		T.robin_location = "sleep";
+	} else if (!between(V.hour, 7, 20)){ //if hour is 6 or lower, or 21 or higher
+		if (V.NPCName[V.NPCNameList.indexOf("Robin")].lust >= 80 && V.robinromance === 1 && between(V.hour, 21, 23) && !V.robinDaily.sleepMasturbate){
+			return T.robin_location = "sleepMasturbate";
+		} else {
+			return T.robin_location = "sleep";
+		}
 	} else if (V.schoolday === 1 && between(V.hour, 8, 15)) {
 		return (T.robin_location = "school");
 	} else if ((V.weekday === 7 || V.weekday === 1) && between(V.hour, 9, 16) && V.NPCName[V.NPCNameList.indexOf("Robin")].trauma < 80) {
@@ -698,6 +702,7 @@ function getRobinCrossdressingStatus(crossdressLevel) {
 	switch (getRobinLocation()) {
 		case "orphanage":
 		case "sleep":
+		case "sleepMasturbate":
 			if (crossdressLevel >= 2) T.robin_cd = 2;
 			break;
 		case "park":
@@ -1465,9 +1470,9 @@ window.getSexesFromRandomGroup = getSexesFromRandomGroup;
 
 function getColourClassFromPercentage(percentage) {
 	/* This function is for picking the right color to use when coloring various things, primarily the sidebar stats. */
-	/* When using this function, try to keep in mind what value of your input variable you want "red" to be at. 
+	/* When using this function, try to keep in mind what value of your input variable you want "red" to be at.
 	 * Example: $drugged goes higher than 500, but we want the bar to become red at 500, so we call this function as getColourClassFromPercentage($drugged / 5).
-	 */
+	*/
 	if (percentage <= 0) return "green";
 	if (percentage < 20) return "teal";
 	if (percentage < 40) return "lblue";
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index b59f4b2538..0124602029 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -6984,9 +6984,27 @@ Argument 2, where appropriate, determines whether it's the player undressing the
 <</silently>><<print _text_output>><</widget>>
 
 <<widget "npcRevealText">><<silently>>
-	<<set $_npc to _args[0]>>
-	<<set $_part to _args[1]>> /* can be "upper" or "lower" */
-	<<set _text_output to "revealing <<his>> ">>
+	<<set $_npc to _args[0]>><<set _foo0 to _args[0]>>
+	<<set $_part to _args[1]>><<set _foo1 to _args[0]>> /* can be "upper" or "lower" */
+	<<set $_mod to _args[2]>><<set _foo2 to _args[0]>>
+	<<set _text_output to "revealing ">>
+	<<if $_mod is "name">>
+		<<if $NPCNameList.includes($_npc.fullDescription)>>
+			<<set _text_output += "$_npc.fullDescription's ">>
+		<<elseif $_npc.name_known is 1>>
+			<<set _text_output += "$_npc.name's ">>
+		<<else>>
+			<<set _text_output += "the $_npc.fullDescription's ">>
+		<</if>>
+	<<elseif $_mod is "desc">>
+		<<if $NPCNameList.includes($_npc.fullDescription)>>
+			<<set _text_output += "the $_npc.description's ">>
+		<<else>>
+			<<set _text_output += "the $_npc.fullDescription's ">>
+		<</if>>
+	<<else>>
+		<<set _text_output += "<<his>> ">>
+	<</if>>
 	<<if $_part is "both">>
 		<<set _text_output += "$_npc.breastsdesc and ">>
 	<</if>>
diff --git a/game/overworld-town/special-kylar/main.twee b/game/overworld-town/special-kylar/main.twee
index 56c84626af..37b5d910c8 100644
--- a/game/overworld-town/special-kylar/main.twee
+++ b/game/overworld-town/special-kylar/main.twee
@@ -56,14 +56,16 @@
 
 		<<kylaroptionsleave>>
 	<<elseif ($bus is "starfish" or $bus is "park") and $daystate isnot "day">>
-		<<if _kylarStatus.includes("Love")>>
+		<<if $syndromekylar is 1>>
+			<<He>> looks at <<his>> watch. "I need to go," <<he>> says. "They're waiting for me." <<He>> looks at you.
+		<<elseif _kylarStatus.includes("Love")>>
 			<<He>> looks at <<his>> watch. "I need to go," <<he>> says. "They're waiting for me." <<He>> keeps looking over <<his>> shoulder as <<he>> walks.
 		<<else>>
 			<<He>> looks at <<his>> watch, mumbles something, then walks away.
 		<</if>>
 		<br><br>
 
-		<<kylaroptionsleave>>
+		<<kylaroptionsleave "manor">>
 	<<elseif $bus is "kylarmanor" and $hour lt 18>>
 		<<unset $kylar_action>>
 		Kylar looks at a monitor. "I should sleep," <<he>> says. <<He>> walks over to <<his>> bed and collapses atop it, fully dressed. <<He>> watches you, longing on <<his>> face, but <<he>> doesn't say anything.
@@ -135,17 +137,16 @@
 			<<link [[Gift Kylar a strap-on|Kylar Gift Strap-on]]>><</link>><<glove>><<lksuspicion>><<gglust>><<lstress>>
 			<br>
 		<</if>>
-		<<kylaroptionsleave true>>
+		<<kylaroptionsleave "leave">>
 	<</if>>
 <</widget>>
 
 <<widget "kylaroptionsleave">>
 	<<run statusCheck("Kylar")>>
-	<<set $_kylarCanStopYou to _args[0] is true>>
 
 	<<if $kylar_action is "stop">>
 		<<link [[Shake off|Kylar Shake]]>><<npcincr Kylar rage 5>><</link>><<ggksuspicion>>
-	<<elseif $_kylarCanStopYou and random(1, 100) lte 40 and _kylarStatus.includes("Love")>>
+	<<elseif _args[0] is "leave" and random(1, 100) lte 40 and _kylarStatus.includes("Love")>>
 		<<link [[Leave|Kylar Stop]]>><</link>>
 	<<else>>
 		<<switch $bus>>
@@ -160,6 +161,10 @@
 			<<default>>
 				<<set $_dest to "School Rear Playground">>
 		<</switch>>
+		<<if _args[0] is "manor" and $syndromekylar is 1>>
+			<<link [["Walk with " + _kylar.pronouns.him + " (0:20)"|Kylar Walk Manor]]>><</link>>
+			<br>
+		<</if>>
 		<<link [[Leave|$_dest]]>><<endevent>><<unset $kylar_action>><</link>>
 	<</if>>
 	<br>
@@ -2114,7 +2119,7 @@ You accompany Kylar to the arcade. <<He>> grasps your hand once outside the orph
 
 :: Kylar Tease 2
 <<effects>><<set _kylar to statusCheck("Kylar")>>
-<<set $kylarDaily.invite to ($location is "school" ? "school" : "home")>>
+<<set $kylarDaily.invite to ($bus is "kylarmanor" ? "manor" : $location)>>
 
 You lean in again, and press your lips to Kylar's cheek, lingering for a few seconds. You can feel <<his>> cheek shift as <<he>> smiles. You're not done yet, though. You hold <<his>> head in place with one hand and kiss <<him>> again, this time a little lower, near the jawline. You keep kissing <<him>>, going over <<his>> chin and down <<his>> neck. <<His>> breathing becomes heavy.
 <br><br>
@@ -2131,15 +2136,29 @@ You rest your other hand on <<his>> _kylar.clothes.lower.name, right over <<his>
 <</if>>
 <<promiscuity2>>
 
-<<if _kylarStatus.includes("Lust")>>
-	Kylar whimpers, before placing <<his>> hands on your shoulders. "I-I need you," <<he>> says. "We can find somewhere private, right?" <<He>> grinds against your hand.
+<<if $bus is "kylarmanor">>
+	<<if _kylarStatus.includes("Lust")>>
+		Kylar whimpers, before placing <<his>> hands on your shoulders. "I-I need you," <<he>> says. "Please, please, please." <<He>> grinds against your hand.
+	<<else>>
+		Kylar whimpers, before placing a hand on your shoulder. "W-We can have sex right now," <<he>> says. "Anytime you want."
+	<</if>>
 <<else>>
-	Kylar whimpers, before placing a hand on your shoulder. "W-We can find somewhere private," <<he>> says. "Anywhere you want."
+	<<if _kylarStatus.includes("Lust")>>
+		Kylar whimpers, before placing <<his>> hands on your shoulders. "I-I need you," <<he>> says. "We can find somewhere private, right?" <<He>> grinds against your hand.
+	<<else>>
+		Kylar whimpers, before placing a hand on your shoulder. "W-We can find somewhere private," <<he>> says. "Anywhere you want."
+	<</if>>
 <</if>>
 <br><br>
 
 <<if $location is "school">>
 	<<link [[Take Kylar to the bathrooms (0:05)|Kylar Tease Bathroom]]>><<pass 5>><</link>><<promiscuous2>>
+<<elseif $bus is "kylarmanor">>
+	<<link [[Take Kylar to the bed|Manor Kylar Invite]]>><<set $phase to 0>><</link>><<promiscuous2>>
+	<<if currentSkillValue('physique') gte $physiquesize>>
+		<br>
+		<<link [[Carry Kylar to the bed|Manor Kylar Invite]]>><<set $phase to 1>><<npcincr Kylar lust 10>><</link>><<promiscuous2>><<gglust>>
+	<</if>>
 <<else>>
 	<<link [[Invite Kylar to the orphanage (0:15)|Kylar Invite]]>><<pass 15>><</link>><<promiscuous2>>
 <</if>>
diff --git a/game/overworld-town/special-kylar/manor.twee b/game/overworld-town/special-kylar/manor.twee
index 9968471ada..aa29189a13 100644
--- a/game/overworld-town/special-kylar/manor.twee
+++ b/game/overworld-town/special-kylar/manor.twee
@@ -462,9 +462,17 @@ You creep towards Kylar. <<He>> conceals <<his>> face with a sheet, only <<his>>
 		<</if>>
 		<br><br>
 		<<kylarFinish>>
-		<<He>> closes <<his>> eyes again, and starts to snore.
+		<<if $hour lt 18>>
+			<<He>> closes <<his>> eyes again, and starts to snore.
+		<<else>>
+			<<He>> eventually sits back up and returns to <<his>> computer.
+		<</if>>
 	<<else>>
-		<<He>> starts to snore.
+		<<if $hour lt 18>>
+			<<He>> starts to snore.
+		<<else>>
+			<<He>> eventually sits back up and returns to <<his>> computer.
+		<</if>>
 	<</if>>
 	<br><br>
 
@@ -473,14 +481,23 @@ You creep towards Kylar. <<He>> conceals <<his>> face with a sheet, only <<his>>
 	<<clotheson>>
 	<<endcombat>>
 <<elseif $enemyhealth lte 0>>
-	You shove Kylar away from you. <<He>> disappears beneath a bundle of covers. You feel <<him>> peering at you through a shadowy gap.
+	You shove Kylar away from you.
+	<<if $hour lt 18>>
+		<<He>> disappears beneath a bundle of covers. You feel <<him>> peering at you through a shadowy gap.
+	<<else>>
+		<<He>> sits up and returns to <<his>> computer, glancing at you warily.
+	<</if>>
 	<br><br>
 	<<tearful>> you climb off the bed.
 	<br><br>
 	<<clotheson>>
 	<<endcombat>>
 <<else>>
-	Kylar disappears beneath a bundle of covers. You feel <<him>> peering at you through a shadowy gap.
+	<<if $hour lt 18>>
+		<<He>> disappears beneath a bundle of covers. You feel <<him>> peering at you through a shadowy gap.
+	<<else>>
+		<<He>> sits up and returns to <<his>> computer.
+	<</if>>
 	<br><br>
 	<<tearful>> you climb off the bed.
 	<br><br>
@@ -655,3 +672,30 @@ You're not sure if one, or both, are beneath the bed, but you sit atop it and ta
 
 <<link [[Next|Manor Parents Room]]>><</link>>
 <br>
+
+:: Manor Kylar Invite
+<<effects>>
+
+<<if $phase is 1>>
+	You pick Kylar up, making <<him>> squeal, and carry <<him>> over to the bed. <<He>> clings to you on the way over, rubbing <<his>> face into your body. When you arrive at the bed, you lower yourself and Kylar onto it.
+<<else>>
+	You gently tug Kylar away from the chair, and <<he>> walks over to the bed with you. <<He>> flops onto it and gazes up at you with needy eyes.
+<</if>>
+<br><br>
+
+<<link [[Next|Manor Kylar Sex]]>><<set $sexstart to 1>><</link>>
+
+:: Kylar Walk Manor
+<<effects>><<location "kylarmanor">>
+
+<<if $submissive lte 850>>
+	"Not without me, you're not," you say as you grab Kylar's arm. "Don't want you getting lost."
+<<elseif $submissive gte 1150>>
+	"Is it okay if I come with you?" You hold out your arm to Kylar, and <<he>> wraps <<his>> around yours.
+<<else>>
+	"I'm coming with you," you say, taking Kylar's arm.
+<</if>>
+You walk to the manor together. Kylar gives you a hug before sitting at <<his>> computer.
+<br><br>
+
+<<kylaroptions>>
\ No newline at end of file
diff --git a/game/overworld-town/special-robin/main.twee b/game/overworld-town/special-robin/main.twee
index af7ee840de..9a6526d208 100644
--- a/game/overworld-town/special-robin/main.twee
+++ b/game/overworld-town/special-robin/main.twee
@@ -60,6 +60,15 @@
 		<<link [[Wait for Robin (DEBUG)|$passage]]>><<set _rem to ($time lt 420 ? (420 - $time) : (1440 - $time + 420))>><<pass _rem>><</link>>
 	<</if>>
 
+<<elseif _robin_location is "sleepMasturbate">>
+	<<set $robinDaily.sleepMasturbate to true>>
+	You go to Robin's room. There's a note on the door. "Sleeping!" <span class="lewd">You notice the door is slightly open.</span>
+	<br><br>
+
+	<<link [[Take a peek|Robin Mischief]]>><</link>>
+	<br>
+	<<link [[Close the door|Robin Mischief Close]]>><</link>>
+	<br>
 <<elseif _robin_location is "beach">>
 	You go to Robin's room. There's a note on the door. "Out selling lemonade!"
 	<br><br>
@@ -4776,7 +4785,7 @@ One of the younger orphans spots you in the hallway as they pass the room. "Robi
 <<if $submissive gte 1150>>
 	"The police took <<him>>? Can you tell me where?" You feel your pulse quicken.
 <<elseif $submissive lte 850>>
-	"What? The police?" you ask. "Where did they take him?" You ball your hands into fists.
+	"What? The police?" you ask. "Where did they take <<him>>?" You ball your hands into fists.
 <<else>>
 	"The police?" you ask. "Do you know where <<he>> went?" You feel sweat form on your brow at the thought.
 <</if>>
@@ -5768,4 +5777,239 @@ You gently put <<him>> down on <<his>> bed and tuck <<him>> in. "Goodnight Robin
 <<run setRobinLocationOverride("sleep", numbersBetween(1, 24))>>
 <br><br>
 
-<<link [[Leave|Orphanage]]>><<endevent>><</link>>
\ No newline at end of file
+<<link [[Leave|Orphanage]]>><<endevent>><</link>>
+
+:: Robin Mischief
+<<effects>><<set _robin to statusCheck("Robin")>>
+<<npc Robin>><<person1>>
+
+You hope the door and take a look inside.
+<br><br>
+
+At first you don't notice anything out of the ordinary. You nearly close the door, when you overhear a faint moan coming from under Robin's covers. The cover isn't lying still, it's moving from side to side as if Robin is tossing and turning.
+<br><br>
+
+You're about to enter when the cover slides down, <<npcRevealText $NPCList[0] "lower" "name">>. <<His>> naked rear and <<npcGenitals>> are on full display. Seemingly unaware of your presence, <<he>> reaches down and pleasures <<himself>> in front of your eyes. <<He>> rubs <<his>> <<personpenis>> with one hand while groping <<his>> $NPCList[0].breastdesc with the other. <<He>> bites into <<his>> pillow to muffle <<his>> moans, though you can still faintly hear them.
+<<arousal 600>><<garousal>>
+<br><br>
+
+<<if _robin.dom gte 60>>
+	Suddenly, <<he>> stops moving and turns <<his>> head to the door, smiling. You have a clear view of <<his>> naked body. "Come in," <<he>> whispers.
+	<br><br>
+
+	<<link [[Enter|Robin Mischief Enter]]>><<npcincr Robin dom 1>><</link>><<gdom>>
+	<br>
+	<<link [[Apologise and leave|Robin Mischief Leave]]>><<npcincr Robin lust -5>><<npcincr Robin love -1>><</link>><<lllust>><<llove>>
+<<else>>
+	<<link [[Watch|Robin Mischief Watch]]>><<pass 5>><<arousal 1200>><</link>><<garousal>>
+	<br>
+	<<link [[Close the door|Robin Mischief Close]]>><</link>>
+	<br>
+	<<if $promiscuity gte 55>>
+		<<link [[Masturbate|Robin Mischief Masturbation]]>><<set $masturbationstart to 1>><</link>><<promiscuous4>>
+		<br>
+	<</if>>
+<</if>>
+
+:: Robin Mischief Watch
+<<effects>><<set _robin to statusCheck("Robin")>>
+
+<<He>> keeps working <<his>> <<personpenis>> while standing on all fours. <<His>> half-clothed body jerks with each movement of <<his>> hand. After a few minutes, <<his>> back arches and
+<<if _robin.penis isnot "none">>
+	cum shoots out of <<his>> <<print $NPCList[0].penisdesc>>. Shuddering,
+<</if>>
+<<he>> falls flat on the bed.
+<br><br>
+
+After regaining <<his>> breath, Robin turns on <<his>> side and pulls the cover over <<him>>. You decide to leave <<him>> to rest and close the door.
+<br><br>
+
+<<link [[Next|Orphanage]]>><<endevent>><</link>>
+
+:: Robin Mischief Close
+<<effects>>
+
+You decide not to bother Robin. You close the door and return to the main hall.
+<br><br>
+
+<<link [[Next|Orphanage]]>><<endevent>><</link>>
+
+:: Robin Mischief Masturbation
+<<effects>>
+<<if $masturbationstart is 1>>
+	<<set $masturbationstart to 0>>
+	<<set $masturbationstat += 1>>
+	You want to touch yourself. What you're watching is way too erotic. You try to find a comfortable position behind the door.
+	<<masturbationstart>>
+	<<set $timer to random(12,48)>>
+	<<promiscuity4>>
+<</if>>
+<<masturbationeffects>>
+<<masturbationactions>>
+
+<<if $orgasmcurrent gte 1>>
+	<<link [[Stop|Robin Mischief Masturbation Finish]]>><<set $finish to 1>><</link>>
+<<else>>
+	<<if $timer lte 0>>
+		<<link [[Continue|Robin Mischief Masturbation Finish]]>><</link>><<nexttext>>
+	<<else>>
+		<<link [[Continue|Robin Mischief Masturbation]]>><</link>><<nexttext>>
+	<</if>>
+	<br>
+	<<if $corruptionMasturbation isnot true and random(0,3) gt $orgasmcurrent and $corruption_slime gt (currentSkillValue('willpower') / 10)>>
+		<<link [[Stop|$passage]]>><<set $corruptionMasturbation to true>><</link>>
+	<<elseif $corruptionMasturbation isnot true>>
+		<<link [[Stop|Robin Mischief Masturbation Finish]]>><<set $finish to 1>><</link>>
+	<<else>>
+		The slime in your ear will not allow you to stop.
+	<</if>>
+<</if>>
+
+:: Robin Mischief Masturbation Finish
+<<effects>>
+<<if $masturbationorgasm gte 1>>
+	You clamp a hand over your mouth to avoid being exposed. Almost simultaneously,
+<<else>>
+	Before you can bring yourself to climax,
+<</if>>
+Robin's back arches and
+<<if $NPCList[0].penis isnot "none">>
+	cum shoots out of <<his>> <<print $NPCList[0].penisdesc>>. Shuddering,
+<</if>>
+<<he>> falls flat on the bed. You step away before <<he>> notices you.
+<br><br>
+
+After regaining <<his>> breath, Robin turns on <<his>> side and pulls the cover over <<him>>. You decide to leave <<him>> to rest and close the door.
+<br><br>
+
+<<endmasturbation>>
+<<endcombat>>
+
+<<link [[Next|Orphanage]]>><<clotheson>><</link>>
+<br>
+
+:: Robin Mischief Leave
+<<effects>>
+
+You apologise and close the door. You hear Robin call out to you, before giving up.
+<br><br>
+
+<<link [[Next|Orphanage]]>><<endevent>><</link>>
+
+:: Robin Mischief Enter
+<<effects>><<set _robin to statusCheck("Robin")>>
+
+You enter, closing the door on your way in. Robin pats a spot on <<his>> bed next to <<him>> and you sit down.
+<br><br>
+
+"I'm sorry you had to see me like that," <<he>> says, blushing. "I've been feeling strange lately, and it helps a lot."
+<br><br>
+
+Before you can answer, <<he>> grabs you by your shoulders and pushes you down onto the bed, straddling you and leaning in for a kiss. You instinctively lean back, and Robin stops.
+<br><br>
+
+"I'm sorry," <<he>> says, looking ashamed. "I should've asked first." <<He>> tries to smile, but the look in <<his>> eyes is apologetic. "You can go back to your room. I don't want you to lose sleep because of me."
+<br><br>
+
+<<link [[Kiss Robin|Robin Mischief Sex]]>><<set $sexstart to 1>><</link>>
+<br>
+<<link [[Leave|Robin Mischief Enter Leave]]>><</link>>
+
+:: Robin Mischief Enter Leave
+<<effects>>
+
+You get up from the bed and leave the room. Robin doesn't look at you.
+<br><br>
+
+<<link [[Next|Orphanage]]>><<endevent>><</link>>
+
+:: Robin Mischief Sex
+<<set _robin to statusCheck("Robin")>>
+<<if $sexstart is 1>>
+	<<set $sexstart to 0>>
+	<<consensual>>
+	<<set $consensual to 1>>
+	<<neutral 1>>
+	<<maninit>>
+	<<set $enemytrust += 500>><<npcexpose>>
+	<<npckiss>>
+	<<set $enemyarousalmax to 600>>
+	<<set _robin.lovewake to 1>>
+	You lean up before <<he>> can pull away, pressing your lips against <<his>>. <<His>> eyes widen as your lips meet, before closing in bliss.
+<</if>>
+
+<<set $enemyanger to 0>>
+<<effects>>
+<<effectsman>>
+<<man>>
+<<stateman>>
+<br><br>
+<<actionsman>>
+
+<<if _combatend>>
+	<span id="next"><<link [[Next|Robin Mischief Sex Finish]]>><</link>></span><<nexttext>>
+<<else>>
+	<span id="next"><<link [[Next|Robin Mischief Sex]]>><</link>></span><<nexttext>>
+<</if>>
+
+:: Robin Mischief Sex Finish
+<<set $outside to 0>><<set $location to "home">><<schooleffects>><<effects>>
+
+<<if $enemyarousal gte $enemyarousalmax>>
+	<<ejaculation>>
+	Robin clings to you and smiles.
+<<elseif $enemyhealth lte 0>>
+	"Ow!" Robin says. <<Hes>> still smiling.
+<<elseif $finish is 1>>
+	Robin clings to you and smiles.
+<</if>>
+<br><br>
+<<He>> gazes into your eyes. "I love you." <<He>> kisses you again.
+
+<<if $penisfucked is 1>>
+	"It feels so good to have you inside me."
+<<elseif $vaginafucked is 1>>
+	"It feels so good inside you."
+<</if>>
+
+<<if $orgasmcurrent is 0 and !$worn.genitals.type.includes("chastity")>>
+	<<set _mouthful to 1>>
+	<<if $player.penisExist>>
+		<<set $penisuse to "othermouth">><<set $penisstate to "othermouth">>
+	<</if>>
+	Robin looks playful. "And now," <<he>> smiles. "<<print either("I make you squeal.","You squeal.","It's your turn.","You cum.","I make you cum.","I get you off.")>>"
+	<br>
+	Robin disappears under the cover. A moment later you feel <<his>> tongue licking your <<genitals>>.
+	<br>
+	<<arousal 4000>>
+	<<if $arousal gte $arousalmax>>
+		<<orgasm>>
+	<<else>>
+		<br>
+		After a while of this, Robin crawls back up. "I'm not giving up," <<he>> breathes. <<He>> nips your ear. "That isn't happening."
+		<br>
+		Robin disappears back under the cover and goes at it with renewed determination.
+		<<if $player.penisExist>>
+			<<set $NPCList[0].mouth to "penis">>
+			<<takeNPCVirginity "Robin" "oral">>
+		<</if>>
+		<<set $arousal to 10000>>
+		<<if $arousal gte $arousalmax>>
+			<<orgasm>>
+		<</if>>
+	<</if>>
+	<<He>> kisses you again. "I love you."
+<</if>>
+<br><br>
+
+<<Hes>> silent for a few seconds, before laughing nervously. "You know," <<he>> says. "I'm glad you were the one who walked in and not... someone else. That could've been awkward."
+<br><br>
+
+<<His>> eyes shut, and <<he>> falls into a gentle sleep.
+
+<<clotheson>>
+<<endcombat>>
+<br><br>
+
+<<link [[Next|Orphanage]]>><</link>>
+<br>
\ No newline at end of file
-- 
GitLab


From 9cec1a1dd8c61d9978e90cc9da09a1e1e8ab6eec Mon Sep 17 00:00:00 2001
From: oyea <23656-oyea@users.noreply.gitgud.io>
Date: Sun, 18 Sep 2022 05:40:28 +0000
Subject: [PATCH 38/50] Small Things

---
 game/03-JavaScript/ingame.js                  |   6 +-
 game/base-combat/actions-mouth.twee           |   9 +
 game/base-combat/actions-text.twee            | 156 +++++++++++++++++-
 game/base-combat/actions-vagina.twee          |  10 +-
 game/base-combat/actionsGeneration.twee       |  17 +-
 game/base-combat/effects.twee                 |  32 +++-
 game/base-combat/ejaculation.twee             |  12 +-
 game/base-system/text.twee                    |  16 ++
 game/overworld-town/loc-adultshop/events.twee |  11 +-
 9 files changed, 242 insertions(+), 27 deletions(-)

diff --git a/game/03-JavaScript/ingame.js b/game/03-JavaScript/ingame.js
index 21f47dbc1a..b4b4f5c3df 100644
--- a/game/03-JavaScript/ingame.js
+++ b/game/03-JavaScript/ingame.js
@@ -135,17 +135,17 @@ const combatActionColours = {
 		],
 		sub: [
 			/* leftaction or rightaction */
-			"leftplay", "leftgrab", "leftstroke", "leftchest", "rightplay", "rightgrab", "rightstroke", "rightchest", "leftchest", "rightchest", "leftwork", "rightwork", "leftclit", "rightclit", "keepchoke", "leftmasturbatepussy", "rightmasturbatepussy", "leftmasturbatepenis", "rightmasturbatepenis", "lefthandholdkeep", "righthandholdkeep", "lefthandholdnew", "righthandholdnew", "handguide", "lubeanus", "lubepussy", "lubepenis", "removebuttplug", "dildoOtherPussyTease", "dildoOtherPussyFuck", "dildoOtherAnusTease", "dildoOtherAnusFuck", "strokerOtherPenisTease", "strokerOtherPenisFuck", "dildoSelfPussyEntrance", "dildoSelfAnusEntrance", "dildoSelfPussy", "dildoSelfAnus", "strokerSelfPenisEntrance", "strokerSelfPenis",
+			"leftplay", "leftgrab", "leftstroke", "leftchest", "rightplay", "rightgrab", "rightstroke", "rightchest", "leftchest", "rightchest", "leftwork", "rightwork", "leftclit", "rightclit", "handedge", "keepchoke", "leftmasturbatepussy", "rightmasturbatepussy", "leftmasturbatepenis", "rightmasturbatepenis", "lefthandholdkeep", "righthandholdkeep", "lefthandholdnew", "righthandholdnew", "handguide", "lubeanus", "lubepussy", "lubepenis", "removebuttplug", "dildoOtherPussyTease", "dildoOtherPussyFuck", "dildoOtherAnusTease", "dildoOtherAnusFuck", "strokerOtherPenisTease", "strokerOtherPenisFuck", "dildoSelfPussyEntrance", "dildoSelfAnusEntrance", "dildoSelfPussy", "dildoSelfAnus", "strokerSelfPenisEntrance", "strokerSelfPenis",
 			/* feetaction */
 			"grab", "vaginagrab", "grabrub", "vaginagrabrub", "rub",
 			/* mouthaction */
-			"peniskiss", "kisslips", "kissskin", "suck", "lick", "moan", "breastsuck", "breastlick", "swallow", "movetochest", "othervagina", "mouth", "kissback", "vaginalick", "askchoke", "anallick", "analkiss", "askrough",
+			"peniskiss", "kisslips", "kissskin", "suck", "lick", "moan", "breastsuck", "breastlick", "swallow", "movetochest", "othervagina", "mouth", "kissback", "vaginalick", "oraledge", "askchoke", "anallick", "analkiss", "askrough",
 			/* penisaction */
 			"penistovagina", "penistoanus", "penisvaginafuck", "penisanusfuck", "othermouthtease", "othermouthrub", "othermouthcooperate", "tease", "cooperate", "otheranustease", "otheranusrub", "otheranuscooperate", "clitrub", "vaginaEdging", "otheranusEdging", "handtease", "handAnusRub", "handcooperate", "strokerCooperate",
 			/* fencing */
 			"otherpenisrub", "penistopenis", "penistopenisfuck", "fencingcooperate",
 			/* vaginaaction */
-			"vaginatopenis", "vaginapenisfuck", "othervaginarub", "vaginatovagina", "vaginatovaginafuck", "tribcooperate", "penisEdging", "vaginatopenisdouble", "vaginapenisdoublefuck", "penispussydouble", "penisanusdvp",
+			"vaginatopenis", "vaginapenisfuck", "othervaginarub", "vaginatovagina", "vaginatovaginafuck", "tribcooperate", "penisEdging", "tribedge", "vaginatopenisdouble", "vaginapenisdoublefuck", "penispussydouble", "penisanusdvp",
 			/* anusaction */
 			"anustopenis", "anuspenisfuck", "penistease", "otherMouthAnusRub", "otherAnusRub", "penisEdging",
 			/* doubleanusaction */
diff --git a/game/base-combat/actions-mouth.twee b/game/base-combat/actions-mouth.twee
index a17f9f0c42..63dbb870ba 100644
--- a/game/base-combat/actions-mouth.twee
+++ b/game/base-combat/actions-mouth.twee
@@ -201,6 +201,9 @@
 <<if !$worn.face.type.includes("covered") and !$worn.face.type.includes("gag")>>
 	<<set _mouthaction["Lick"] to "lick">>
 <</if>>
+<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $oralskill gte 800>>
+	<<set _mouthaction["Edge"] to "oraledge">>
+<</if>>
 <<set _mouthaction["Pull away"] to "pullaway">>
 <<oralswallownew>>
 <<speak>>
@@ -208,6 +211,9 @@
 
 <<widget "combatPenisPenetrated">>
 <<set _mouthaction["Suck"] to "suck">>
+<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $oralskill gte 800>>
+	<<set _mouthaction["Edge"] to "oraledge">>
+<</if>>
 <<if $consensual isnot 1 and ($fightTargets is undefined or $fightTargets.includes($mouthtaget))>>
 	<<set _mouthaction["Bite"] to "bite">>
 <</if>>
@@ -218,6 +224,9 @@
 
 <<widget "combatOthervagina">>
 <<set _mouthaction["Lick"] to "vaginalick">>
+<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $oralskill gte 800>>
+	<<set _mouthaction["Edge"] to "oraledge">>
+<</if>>
 <<if $consensual isnot 1 and ($fightTargets is undefined or $fightTargets.includes($mouthtaget))>>
 	<<set _mouthaction["Bite"] to "bitepussy">>
 <</if>>
diff --git a/game/base-combat/actions-text.twee b/game/base-combat/actions-text.twee
index 9dfe642a2c..415ba2bc09 100644
--- a/game/base-combat/actions-text.twee
+++ b/game/base-combat/actions-text.twee
@@ -692,6 +692,58 @@ Hoping to mollify, you <<handtext>> stroke <<their _args[0]>> clitoris between y
 <</if>>
 <</widget>>
 
+<<widget "actionshandedge">>
+	<<if $arousal gte ($arousalmax / 5) * 4>>
+		<<print either(
+			"It's a struggle to keep still, but you <<handtext>>",
+			"With a trembling hand, you <<handtext>>",
+			"Your hand twitches as you <<handtext>>"
+		)>>
+	<<elseif $arousal gte ($arousalmax / 5) * 2>>
+		<<print either(
+			"Warmth creeps up your arm as you <<handtext>>",
+			"Despite the rising heat, you <<handtext>>",
+			"You steady your hand and <<handtext>>"
+		)>>
+	<<else>>
+		You <<handtext>>
+	<</if>>
+
+	<<if _args[1].includes("penis")>>
+		<<print either(
+			"pinch <<his>> shaft between your fingers,",
+			"trail a finger around <<his>> groin,",
+			"thumb the tip of <<his>> cock,"
+		)>>
+	<<else>>
+		<<print either(
+			"press <<his>> lips between your fingers,",
+			"trail a finger around <<his>> labia,",
+			"ease your palm against <<his>> clit,"
+		)>>
+	<</if>>
+
+	<<if $enemyarousal gte ($enemyarousalmax / 5) * 4>>
+		<<print either(
+			"holding <<him>> on the brink of an orgasm.",
+			"waving relief just out of <<his>> reach.",
+			"torturing <<his>> yearning body."
+		)>>
+	<<elseif $enemyarousal gte ($enemyarousalmax / 5) * 2>>
+		<<print either(
+			"slowly coaxing <<him>> to climax.",
+			"letting <<his>> arousal swell.",
+			"keeping <<him>> on edge."
+		)>>
+	<<else>>
+		<<print either(
+			"controlling <<his>> arousal.",
+			"curbing <<his>> arousal.",
+			"stirring pleasure."
+		)>>
+	<</if>>
+<</widget>>
+
 <<widget "actionskick">>
 <<if $enemytype is "beast">>
 	<<if $pain lte 20>>
@@ -4013,6 +4065,58 @@ You <<oraltext>> lick <<their _args[0]>> penis.
 <</if>>
 <</widget>>
 
+<<widget "actionsoraledge">>
+	<<if $arousal gte ($arousalmax / 5) * 4>>
+		Your lips quiver as you <<oraltext>>
+	<<elseif $arousal gte ($arousalmax / 5) * 2>>
+		You suppress a moan and <<oraltext>>
+	<<else>>
+		You <<oraltext>>
+	<</if>>
+
+	<<if $mouthuse.includes("penis")>>
+		<<if $mouthstate is "imminent">>
+			<<print either(
+				"tease <<his>> $NPCList[$mouthtarget].penisdesc against your lips,",
+				"roll your tongue against the base of <<his>> shaft,",
+				"alternate between slow and sharp licks,"
+			)>>
+		<<else>>
+			<<print either(
+				"vary your bobbing against <<his>> cock,",
+				"slow <<his>> thrusts with your tongue,",
+				"purse your lips around <<his>> shaft,"
+			)>>
+		<</if>>
+	<<else>>
+		<<print either(
+			"alternate between slow and sharp licks,",
+			"press your tongue to <<his>> clit,",
+			"blow on <<his>> clit,"
+		)>>
+	<</if>>
+
+	<<if $enemyarousal gte ($enemyarousalmax / 5) * 4>>
+		<<print either(
+			"holding <<him>> on the brink of an orgasm.",
+			"waving relief just out of <<his>> reach.",
+			"torturing <<his>> yearning body."
+		)>>
+	<<elseif $enemyarousal gte ($enemyarousalmax / 5) * 2>>
+		<<print either(
+			"slowly coaxing <<him>> to climax.",
+			"letting <<his>> arousal swell.",
+			"keeping <<him>> on edge."
+		)>>
+	<<else>>
+		<<print either(
+			"controlling <<his>> arousal.",
+			"curbing <<his>> arousal.",
+			"stirring pleasure."
+		)>>
+	<</if>>
+<</widget>>
+
 <<widget "actionsAnalLick">>
 	<<print either(
 		"You <<oraltext>> lick up and down the crack of the ass pressing down on your mouth",
@@ -4233,11 +4337,11 @@ _otheraction _youraction
 <<if $vaginastate is "imminent">>
 	<<set _otheraction to "">>
 	<<if $arousal gte ($arousalmax / 5) * 4>>
-		<<set _youraction to "Driven partly by instinct, you <<vaginaltext>> rub your ass against their penis to control their arousal as you approach your peak.">>
+		<<set _youraction to "Driven partly by instinct, you <<vaginaltext>> rub your <<pussy>> against their penis to control their arousal as you approach your peak.">>
 	<<elseif $arousal gte ($arousalmax / 5) * 2>>
-		<<set _youraction to "You <<vaginaltext>> rub your <<bottom>> against their penis to control their arousal.">>
+		<<set _youraction to "You <<vaginaltext>> rub your <<pussy>> against their penis to control their arousal.">>
 	<<else>>
-		<<set _youraction to "You <<vaginaltext>> rub your <<bottom>> against their penis to control their arousal, trying to reduce your discomfort.">>
+		<<set _youraction to "You <<vaginaltext>> rub your <<pussy>> against their penis to control their arousal, trying to reduce your discomfort.">>
 	<</if>>
 <<else>>
 	<<pussy>>
@@ -4615,6 +4719,50 @@ _otheraction _youraction
 <</if>>
 <</widget>>
 
+<<widget "actionstribedge">>
+	<<if $arousal gte ($arousalmax / 5) * 4>>
+		Driven partly by instinct, you <<vaginaltext>>
+	<<elseif $arousal gte ($arousalmax / 5) * 2>>
+		You steady your shaky legs and <<vaginaltext>>
+	<<else>>
+		You <<vaginaltext>>
+	<</if>>
+
+	<<if $vaginastate is "othervaginaimminent">>
+		<<print either(
+			"thrust your <<pussy>> just shy of <<hers>>,",
+			"pull back in time with <<his>> thrusts,",
+			"clench your thighs over <<his>> pussy,"
+		)>>
+	<<else>>
+		<<print either(
+			"weave your <<pussy>> away at the apex of each thrust,",
+			"graze <<his>> pussy with yours,",
+			"press against <<his>> clit,"
+		)>>
+	<</if>>
+
+	<<if $enemyarousal gte ($enemyarousalmax / 5) * 4>>
+		<<print either(
+			"holding <<him>> on the brink of an orgasm.",
+			"waving relief just out of <<his>> reach.",
+			"torturing <<his>> yearning body."
+		)>>
+	<<elseif $enemyarousal gte ($enemyarousalmax / 5) * 2>>
+		<<print either(
+			"slowly coaxing <<him>> to climax.",
+			"letting <<his>> arousal swell.",
+			"keeping <<him>> on edge."
+		)>>
+	<<else>>
+		<<print either(
+			"controlling <<his>> arousal.",
+			"curbing <<his>> arousal.",
+			"stirring pleasure."
+		)>>
+	<</if>>
+<</widget>>
+
 <<widget "actionsfencingtake">>
 <<if $enemytype is "beast">>
 	<<if $enemyarousal gte ($enemyarousalmax / 5) * 4>>
@@ -5001,7 +5149,7 @@ You <<peniletext>> tease <<their _args[0]>> anus with your <<penis>>.
 <</widget>>
 
 <<widget "actionsanusedging">>
-<<if $anusaction is "imminent">>
+<<if $anusstate is "imminent">>
 	<<if $arousal gte ($arousalmax / 5) * 4>>
 		Driven partly by instinct, you <<analtext>> rub against their penis to control their arousal as you approach your peak.
 	<<elseif $arousal gte ($arousalmax / 5) * 2>>
diff --git a/game/base-combat/actions-vagina.twee b/game/base-combat/actions-vagina.twee
index d8e6e4a430..3a3af05bcd 100644
--- a/game/base-combat/actions-vagina.twee
+++ b/game/base-combat/actions-vagina.twee
@@ -170,6 +170,9 @@
 	<<set _vaginaaction["Cooperate"] to "othervaginarub">>
 <<else>>
 	<<set _vaginaaction["Rub"] to "othervaginarub">>
+<</if>>
+<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $vaginalskill gte 800>>
+	<<set _vaginaaction["Edge"] to "tribedge">>
 <</if>>
 	<<set _vaginaaction["Pull away"] to "tribescape">>
 <</widget>>
@@ -257,8 +260,11 @@
 <<else>>
 	<<set _vaginaaction["Rub"] to "tribcooperate">>
 <</if>>
-	<<set _vaginaaction["Take it"] to "tribtake">>
-	<<set _vaginaaction["Pull away"] to "tribescape">>
+<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $vaginalskill gte 800>>
+	<<set _vaginaaction["Edge"] to "tribedge">>
+<</if>>
+<<set _vaginaaction["Take it"] to "tribtake">>
+<<set _vaginaaction["Pull away"] to "tribescape">>
 <</widget>>
 
 <<widget "actionsTribRest">>
diff --git a/game/base-combat/actionsGeneration.twee b/game/base-combat/actionsGeneration.twee
index be8daab528..4db4e935ae 100644
--- a/game/base-combat/actionsGeneration.twee
+++ b/game/base-combat/actionsGeneration.twee
@@ -430,6 +430,7 @@
 <<switch _diffAction>>
 	<<case "leftwork" "leftclit">><<handdifficulty>>
 	<<case "leftplay" "leftgrab">><<handdifficulty>> <<combatpromiscuous3>>
+	<<case "handedge">> <<combatpromiscuous4>>
 	<<case "steal">><<skulduggerydifficulty>><<combatcrime>>
 	<<case "spray">>Remaining: $spray / $spraymax
 	<<case "lefthandholdnew">><<handholdingvirginitywarning>><<NPCvirginitywarning $NPCList[$lefttarget].fullDescription "handholding">>
@@ -505,6 +506,9 @@
 				<<set _leftaction["Tease " + $NPCList[$lefttarget].pronouns.him] to "leftwork">>
 			<<else>>
 				<<set _leftaction["Work " + $NPCList[$lefttarget].pronouns.his + " shaft"] to "leftwork">>
+				<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $handskill gte 800>>
+					<<set _leftaction["Edge"] to "handedge">>
+				<</if>>
 			<</if>>
 			<<set _leftaction["Stop"] to "leftstoppenis">>
 		<<case "grappled">>
@@ -516,6 +520,9 @@
 				<<set _leftaction["Tease " + $NPCList[$lefttarget].pronouns.him] to "leftclit">>
 			<<else>>
 				<<set _leftaction["Rub " + $NPCList[$lefttarget].pronouns.his + " clit"] to "leftclit">>
+				<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $handskill gte 800>>
+					<<set _leftaction["Edge"] to "handedge">>
+				<</if>>
 			<</if>>
 			<<set _leftaction["Stop"] to "leftothervaginastop">>
 		<<case "coverVagina">>
@@ -804,6 +811,7 @@
 <<switch _diffAction>>
 	<<case "rightwork" "rightclit">><<handdifficulty>>
 	<<case "rightplay" "rightgrab">><<handdifficulty>> <<combatpromiscuous3>>
+	<<case "handedge">> <<combatpromiscuous4>>
 	<<case "steal">><<skulduggerydifficulty>><<combatcrime>>
 	<<case "spray">>Remaining: $spray / $spraymax
 	<<case "righthandholdnew">><<handholdingvirginitywarning>><<NPCvirginitywarning $NPCList[$lefttarget].fullDescription "handholding">>
@@ -879,6 +887,9 @@
 				<<set _rightaction["Tease " + $NPCList[$righttarget].pronouns.him] to "rightwork">>
 			<<else>>
 				<<set _rightaction["Work " + $NPCList[$righttarget].pronouns.his + " shaft"] to "rightwork">>
+				<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $handskill gte 800>>
+					<<set _rightaction["Edge"] to "handedge">>
+				<</if>>
 			<</if>>
 			<<set _rightaction["Stop"] to "rightstoppenis">>
 		<<case "grappled">>
@@ -890,6 +901,9 @@
 				<<set _rightaction["Tease " + $NPCList[$righttarget].pronouns.him] to "rightclit">>
 			<<else>>
 				<<set _rightaction["Rub " + $NPCList[$righttarget].pronouns.his + " clit"] to "rightclit">>
+				<<if ($consensual is 0 or ($enemytype is "man" ? $promiscuity : $deviancy) gte 55 or $promiscuityIgnore) and $handskill gte 800>>
+					<<set _leftaction["Edge"] to "handedge">>
+				<</if>>
 			<</if>>
 			<<set _rightaction["Stop"] to "rightothervaginastop">>
 		<<case "coverVagina">>
@@ -1319,6 +1333,7 @@
 <</if>>
 <<switch _diffAction>>
 	<<case "mouth" "othervagina">><<oraldifficulty>> <<combatpromiscuous4>>
+	<<case "oraledge">> <<combatpromiscuous4>>
 	<<case "movetochest">><<oraldifficulty>> <<combatpromiscuous3>>
 	<<case "swallow">><<oralvirginitywarning>> <<combatpromiscuous5>>
 	<<case "grasp">><<chestdifficulty>> <<combatpromiscuous3>>
@@ -1858,7 +1873,7 @@
 	<<case "penisDoubleEdging">><<combatpromiscuous5>> <<combataware 4>>
 	<<case "vaginatopenisdouble">><<vaginaldifficulty>> <<combatpromiscuous5>> <<combataware 4>>
 	<<case "vaginapenisdoublefuck">><<vaginaldifficulty>> <<combatpromiscuous5>> <<combataware 4>> <<vaginalvirginitywarning>><<NPCvirginitywarning $NPCList[_n].fullDescription "penile">>
-	<<case "penisEdging">><<combatpromiscuous4>>
+	<<case "penisEdging" "tribedge">><<combatpromiscuous4>>
 <</switch>>
 <</widget>>
 
diff --git a/game/base-combat/effects.twee b/game/base-combat/effects.twee
index 5a4382e1d8..8ee02ac4d1 100644
--- a/game/base-combat/effects.twee
+++ b/game/base-combat/effects.twee
@@ -338,6 +338,16 @@
 	<</if>>
 <</if>>
 
+<<if $leftaction is "handedge">>
+	<<personselect $lefttarget>><<actionshandedge $lefttarget $leftarm>><<set $leftaction to 0>><<set $leftactiondefault to "handedge">>
+	<<submission 5 $lefttarget>><<sexControl 5 $handskill $lefttarget>><<handskilluse>>
+<</if>>
+
+<<if $rightaction is "handedge">>
+	<<personselect $righttarget>><<actionshandedge $righttarget $rightarm>><<set $rightaction to 0>><<set $rightactiondefault to "handedge">>
+	<<submission 5 $righttarget>><<sexControl 5 $handskill $righttarget>><<handskilluse>>
+<</if>>
+
 <<if $leftaction is "leftstoppenis" and $NPCList[$lefttarget].penis is "leftarm">>
 	<<set $leftaction to 0>><<set $leftactiondefault to "leftstoppenis">><<submission 3 $lefttarget>><<set $leftarm to 0>>
 	<<set $NPCList[$lefttarget].penis to 0>>You let go of <<hisselect $lefttarget>> penis.
@@ -3426,6 +3436,11 @@
 	<<set $mouthaction to 0>><<set $mouthactiondefault to "suck">><<actionspenissuck $mouthtarget>><<submission 10 $mouthtarget>><<oralskilluse>>
 <</if>>
 
+<<if $mouthaction is "oraledge">>
+	<<personselect $mouthtarget>><<actionsoraledge $mouthtarget>><<set $mouthaction to 0>><<set $mouthactiondefault to "oraledge">>
+	<<submission 5 $mouthtarget>><<sexControl 5 $oralskill $mouthtarget>><<oralskilluse>>
+<</if>>
+
 <<if $mouthaction is "pullaway">>
 	<<set $mouthaction to 0>><<set $mouthactiondefault to "pullaway">><<personselect $mouthtarget>>
 	You try to pull your head away from the penis threatening your mouth.
@@ -4514,7 +4529,7 @@
 <</if>>
 
 <<if $vaginaaction is "penisDoubleEdging">>
-	<<set $vaginaaction to 0>><<set $vaginaactiondefault to "penisDoubleEdging">><<actionspenisdoubleedging>><<submission 5>><<sexControl 5 $vaginalskill>><<vaginalskilluse>><<combatpromiscuity4>>
+	<<set $vaginaaction to 0>><<set $vaginaactiondefault to "penisDoubleEdging">><<actionspenisdoubleedging>><<submission 5>><<sexControl 5 $vaginalskill>><<vaginalskilluse>>
 <</if>>
 
 <<if $vaginaaction is "doubletake">>
@@ -4530,7 +4545,7 @@
 <</if>>
 
 <<if $vaginaaction is "penisEdging">>
-	<<set $vaginaaction to 0>><<set $vaginaactiondefault to "penisEdging">><<actionspenisedging $vaginatarget>><<submission 5 $vaginatarget>><<sexControl 5 $vaginalskill $vaginatarget>><<vaginalskilluse>><<combatpromiscuity4>>
+	<<set $vaginaaction to 0>><<set $vaginaactiondefault to "penisEdging">><<actionspenisedging $vaginatarget>><<submission 5 $vaginatarget>><<sexControl 5 $vaginalskill $vaginatarget>><<vaginalskilluse>>
 <</if>>
 
 <<if $vaginaaction is "take">>
@@ -4549,6 +4564,11 @@
 	<<set $vaginaaction to 0>><<set $vaginaactiondefault to "tribtake">><<actionstribtake $vaginatarget>>
 <</if>>
 
+<<if $vaginaaction is "tribedge">>
+	<<personselect $vaginatarget>><<actionstribedge $vaginatarget>><<set $vaginaaction to 0>><<set $vaginaactiondefault to "tribedge">>
+	<<submission 5 $vaginatarget>><<sexControl 5 $vaginalskill $vaginatarget>><<vaginalskilluse>>
+<</if>>
+
 <<if $vaginaaction is "tribrest">>
 	<<set $vaginaaction to 0>><<set $vaginaactiondefault to "rest">>
 <</if>>
@@ -4854,7 +4874,7 @@
 <</if>>
 
 <<if $anusaction is "penisEdging">>
-	<<set $anusaction to 0>><<set $anusactiondefault to "penisEdging">><<actionsanusedging $anustarget>><<submission 5 $anustarget>><<sexControl 5 $analskill $anustarget>><<analskilluse>><<combatpromiscuity4>>
+	<<set $anusaction to 0>><<set $anusactiondefault to "penisEdging">><<actionsanusedging $anustarget>><<submission 5 $anustarget>><<sexControl 5 $analskill $anustarget>><<analskilluse>>
 <</if>>
 
 <<if $anusaction is "take">>
@@ -4935,7 +4955,7 @@
 <</if>>
 
 <<if $anusaction is "penisDoubleEdging">>
-	<<set $anusaction to 0>><<set $anusactiondefault to "penisDoubleEdging">><<actionsanusdoubleedging $anustarget $anusdoubletarget>><<submission 5 $anustarget $anusdoubletarget>><<sexControl 5 $analskill $anustarget $anusdoubletarget>><<analskilluse>><<combatpromiscuity5>>
+	<<set $anusaction to 0>><<set $anusactiondefault to "penisDoubleEdging">><<actionsanusdoubleedging $anustarget $anusdoubletarget>><<submission 5 $anustarget $anusdoubletarget>><<sexControl 5 $analskill $anustarget $anusdoubletarget>><<analskilluse>>
 <</if>>
 
 <<if $anusaction is "doubletake">>
@@ -5242,7 +5262,7 @@
 <</if>>
 
 <<if $penisaction is "vaginaEdging">>
-	<<set $penisaction to 0>><<set $penisactiondefault to "vaginaEdging">><<actionspussyedging $penistarget>><<submission 5 $penistarget>><<sexControl 5 $penileskill $penistarget>><<penileskilluse>><<combatpromiscuity4>>
+	<<set $penisaction to 0>><<set $penisactiondefault to "vaginaEdging">><<actionspussyedging $penistarget>><<submission 5 $penistarget>><<sexControl 5 $penileskill $penistarget>><<penileskilluse>>
 <</if>>
 
 <<if $penisaction is "take">>
@@ -5380,7 +5400,7 @@
 <</if>>
 
 <<if $penisaction is "otheranusEdging">>
-	<<set $penisaction to 0>><<set $penisactiondefault to "otheranusEdging">><<actionsotheranusedging $penistarget>><<submission 5 $penistarget>><<sexControl 5 $penileskill $penistarget>><<penileskilluse>><<combatpromiscuity4>>
+	<<set $penisaction to 0>><<set $penisactiondefault to "otheranusEdging">><<actionsotheranusedging $penistarget>><<submission 5 $penistarget>><<sexControl 5 $penileskill $penistarget>><<penileskilluse>>
 <</if>>
 
 <<if $penisaction is "otheranustake">>
diff --git a/game/base-combat/ejaculation.twee b/game/base-combat/ejaculation.twee
index 5b8e3c69b1..1223d1f5b0 100644
--- a/game/base-combat/ejaculation.twee
+++ b/game/base-combat/ejaculation.twee
@@ -818,7 +818,7 @@
 						<<case 1 2>>
 							<<He>> sighs as <<he>> cums, falling back and resting <<his>> arm over <<his>> eyes.
 						<<case 3 4>>
-							<<He>> moans as <<his>> $NPCList[_nn].breastsdesc shake as <<he>> cums.
+							<<He>> moans as <<his>> <<if $NPCList[_nn].breastsize is 0>>chest heaves<<else>>$NPCList[_nn].breastsdesc shake<</if>> as <<he>> cums.
 						<<case 5>>
 							<<He>> screams as <<he>> cums, <<his>> juices running down <<his>> thighs. <<He>> scoops some with a finger, dons a playful smile, then flicks it across your face.
 							<<set _postOrgasmSpeech to `"Now you're messy, just like me."`>>
@@ -830,7 +830,7 @@
 							<<He>> moans and grasps your ankles as <<he>> cums.
 							<<set _postOrgasmSpeech to `"I love being treated like a dirty slut."`>>
 						<<case 3 4>>
-							<<He>> grasps <<his>> $NPCList[_nn].breastsdesc as <<he>> cums against your feet.
+							<<He>> <<if $NPCList[_nn].breastsize is 0>>pinches<<else>>grasps<</if>> <<his>> $NPCList[_nn].breastsdesc as <<he>> cums against your feet.
 							<<set _postOrgasmSpeech to `"I love it when you dominate me."`>>
 						<<case 5>>
 							<<He>> screams as <<he>> cums, almost making you jump. <<His>> juices run over your feet.
@@ -843,7 +843,7 @@
 						<<case 3 4>>
 							<<He>> moans and <<his>> legs shake as <<he>> cums against your <<pussy>>.
 						<<case 5>>
-							<<He>> screams, wrapping <<his>> arms under your shoulders and pressing <<his>> $NPCList[_nn].breastsdesc against you as <<his>> body shakes.
+							<<He>> screams, wrapping <<his>> arms under your shoulders and pressing <<his>> <<npcChest>> against you as <<his>> body shakes.
 							<<vaginalentranceejacstat>><<ejacstat>><<set $hygiene += 500>><<bodyliquid "vaginaoutside" "goo">>
 						<</switch>>
 					<<elseif $NPCList[_nn].vagina is "othermouth">>
@@ -899,7 +899,7 @@
 							<<He>> sighs as <<he>> cums, <<his>> blush deepening.
 							<<set _postOrgasmSpeech to `"Oh, look what your cock did to me."`>>
 						<<case 5>>
-							<<He>> wraps <<his>> arms under your shoulders and presses <<his>> $NPCList[_nn].breastdesc against you as <<he>> cums. You feel <<his>> pussy twitch against your <<penis>>.
+							<<He>> wraps <<his>> arms under your shoulders and presses <<his>> <<npcChest>> against you as <<he>> cums. You feel <<his>> pussy twitch against your <<penis>>.
 						<<case 6>>
 							<<He>> screams and pounds your <<penis>> with <<his>> pelvis as <<he>> cums, <<his>> whole body shaking.
 							<<thighejacstat>><<set $hygiene += 500>><<bodyliquid "thigh" "goo">>
@@ -933,7 +933,7 @@
 					<<elseif $NPCList[_nn].vagina is 0>>
 						<<switch random(1, 7)>>
 						<<case 1 2 3>>
-							<<He>> buckles at the knees, <<his>> $NPCList[_nn].breastsdesc trembling as <<he>> cums. <<His>> juices run down <<his>> thighs.
+							<<He>> buckles at the knees, <<his>> <<if $NPCList[_nn].breastsize is 0>>chest heaving<<else>>$NPCList[_nn].breastsdesc trembling<</if>> trembling as <<he>> cums. <<His>> juices run down <<his>> thighs.
 						<<case 4 5 6>>
 							<<He>> sighs as <<he>> cums, and pats your <<bottom>>.
 							<<set _postOrgasmSpeech to `"That was fun."`>>
@@ -965,7 +965,7 @@
 							<<He>> moans and <span class="blue">grasps your throat</span> as <<he>> cums. <<He>> rubs hard against your <<pussy>>, licking your cheek as <<he>> finishes.
 							<<gstress>><<gtrauma>><<gpain>><<violence 3>><<bruise neck>><<hitstat>>
 						<<case 5>>
-							<<He>> screams, grasping your hair and pushing <<his>> $NPCList[_nn].breastsdesc against you. <<His>> juices drip over you.
+							<<He>> screams, grasping your hair and pushing <<his>> <<npcChest>> against you. <<His>> juices drip over you.
 							<<vaginalentranceejacstat>><<ejacstat>><<set $hygiene += 500>><<bodyliquid "vaginaoutside" "goo">>
 						<</switch>>
 					<<elseif $NPCList[_nn].vagina is "othermouth">>
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index b59f4b2538..53f73095f5 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -6915,6 +6915,22 @@ $worn.genitals.name
 	<</if>>
 <</widget>>
 
+<<widget "npcChest">>
+	<<if !_args[0]>>
+		<<set _npcGen to $index>>
+	<<else>>
+		<<set _npcGen to _args[0]>>
+	<</if>>
+
+	<<if $NPCList[_npcGen].pronoun is "m" or $NPCList[_npcGen].breastsize is 0>>
+		<<set _text_output to "chest">>
+	<<else>>
+		<<set _text_output to $NPCList[_npcGen].breastsdesc>>
+	<</if>>
+
+	<<print _text_output>>
+<</widget>>
+
 <<widget "npcHairColour">>
 <<if _args[0]>>
 	<<switch $NPCName[$NPCNameList.indexOf(_args[0])].hairColour>>
diff --git a/game/overworld-town/loc-adultshop/events.twee b/game/overworld-town/loc-adultshop/events.twee
index 89e432b7ab..389b9885e5 100644
--- a/game/overworld-town/loc-adultshop/events.twee
+++ b/game/overworld-town/loc-adultshop/events.twee
@@ -1900,17 +1900,18 @@ You tap your chin in mock thought.
 :: Adult Shop Sydney Cuffs Struggle
 <<set $outside to 0>><<set $location to "adult_shop">><<effects>>
 
-You resist Sydney's touching, kicking and thrashing against your restraints. <<He>> throws <<his>> arms in front of <<his>> body. "Hey, take it easy! I was just-" <<He>> cuts off as <<he>> stumbles backwards into a stack of boxes.
+You thrash against your restraints. Sydney throws <<his>> arms up. "Hey, take it easy! I was just-" <<He>> cuts off as <<he>> stumbles into a stack of boxes.
 <br><br>
 
-The door swings open as Sirris arrives to investigate the commotion. "Is everything alright? I thought I heard..." <<He>> trails off, taking in the scene before <<him>>.
+<<npc Sirris 2>><<person2>>
+The door swings open. "Everything alright?" It's Sirris. "Thought I heard..." <<He>> trails off, taking in the scene before <<him>>. <<He>> hurries over to free you, before making <<his>> way to Sydney.
+<<unbind>>
 <br><br>
 
-<<He>> hurries over to you, freeing you, before making <<his>> way to Sydney. <<He>> grabs <<him>> by the arm and lifts <<him>> up, a troubled look on <<his>> face. "We need to talk."
-<<unbind>>
+"We need to talk," <<he>> says, a troubled look on <<his>> face. Sydney tries to explain, but <<person1>><<his>> stammering fades as <<hes>> dragged outside. Once you've regained your bearings, you follow them out.
 <br><br>
 
-Sydney tries to explain the situation, but <<his>> stammering fades into the distance as Sirris drags <<him>> outside. Once you've regained your bearings, you dust yourself off and return to the shop.
+The rest of the shift is uneventful. You earn <<adultShopWage>><<moneyGain _wage>>.
 <br><br>
 
 <<link [[Next|Adult Shop]]>><<endevent>><</link>>
-- 
GitLab


From c605335d3e1298d06c3473bf6025608a8374ffa8 Mon Sep 17 00:00:00 2001
From: Host <35009-Host@users.noreply.gitgud.io>
Date: Sun, 18 Sep 2022 04:39:59 +0300
Subject: [PATCH 39/50] Optimise code for tip bonus from clothes of serving
 type

---
 game/03-JavaScript/base-clothing.js    | 23 ++++++++++++++++
 game/base-system/widgets.twee          | 36 ++++----------------------
 game/overworld-town/loc-cafe/main.twee |  8 +++---
 3 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/game/03-JavaScript/base-clothing.js b/game/03-JavaScript/base-clothing.js
index 1f41706e6d..78602dc2de 100644
--- a/game/03-JavaScript/base-clothing.js
+++ b/game/03-JavaScript/base-clothing.js
@@ -207,3 +207,26 @@ function convertNormalToOver() {
 	}
 }
 window.convertNormalToOver = convertNormalToOver;
+
+function getVisibleClothesList() {
+	let visibleClothes = [ 
+		V.worn.over_upper, V.worn.over_lower, V.worn.over_head,
+		V.worn.face, V.worn.neck,
+		V.worn.hands, V.worn.legs, V.worn.feet
+	];
+	// over_head doesn't have 'exposed' parameter, but maybe it will some day (in which case remove check for 'naked')
+	if (V.worn.over_head.name === "naked" || V.worn.over_head.exposed >= 2)
+		visibleClothes.push(V.worn.head);
+	if (V.worn.over_upper.exposed >= 2 || V.overupperwetstage >= 3)
+		visibleClothes.push(V.worn.upper);
+	if (V.worn.over_lower.exposed >= 2 || V.overlowerwetstage >= 3)
+		visibleClothes.push(V.worn.lower);
+	if (V.worn.upper.exposed >= 2 || V.upperwetstage >= 3)
+		visibleClothes.push(V.worn.under_upper);
+	if (V.worn.lower.exposed >= 2 || V.lowerwetstage >= 3)
+		visibleClothes.push(V.worn.under_lower);
+	if (V.worn.under_lower.exposed >= 2 || V.underlowerwetstage >= 3)
+		visibleClothes.push(V.worn.genitals);
+	return visibleClothes;
+}
+window.getVisibleClothesList = getVisibleClothesList;
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 1ec3dd90e9..ec1c4dbbf1 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -3119,37 +3119,11 @@ It
 	<<set $tipreaction to "mid">>
 <</if>>
 
-<<set _temp_tip to $tip>>/*Remembers base tip value*/
-
-	<<if _args[0] is "serving">>
-		<<if $worn.upper.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>/*20% increase on base value*/
-		<</if>>
-		<<if $worn.lower.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.under_upper.type.includes("serving") and $worn.upper.exposed gte 2>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.under_lower.type.includes("serving") and $worn.lower.exposed gte 2>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.head.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.face.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.neck.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.legs.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-		<<if $worn.feet.type.includes("serving")>>
-		<<set $tip += ((_temp_tip * 1.2) - _temp_tip)>>
-		<</if>>
-	<</if>>
+<<if _args[0] is "serving">>
+	<!-- +20% for every visible clothing item with 'serving' tag -->
+	<<set $_servingClothesCount to getVisibleClothesList().countWith(item => item.type.includes("serving"))>>
+	<<set $tip += $tip * 0.2 * $_servingClothesCount>>
+<</if>>
 
 <<set $tip to $tipmod * $tip>>
 <<set $tip *= (1 + ($attractiveness / 10000))>>
diff --git a/game/overworld-town/loc-cafe/main.twee b/game/overworld-town/loc-cafe/main.twee
index bc9c1d6666..f2d416a6ff 100644
--- a/game/overworld-town/loc-cafe/main.twee
+++ b/game/overworld-town/loc-cafe/main.twee
@@ -119,10 +119,10 @@ You are in the Ocean Breeze Cafe.
 
 	<<if $openinghours is 1 and $exposed lt 1 and $oceanbreezejob isnot 1>>
 		<<if $oceanbreezejoboffer is 1>>
-			<<link [[Ask for work|Ocean Breeze Ask Again]]>><</link>>
+			<<ind>><<link [[Ask for work|Ocean Breeze Ask Again]]>><</link>>
 			<br>
 		<<else>>
-			<<link [[Ask for work|Ocean Breeze Ask]]>><</link>>
+			<<ind>><<link [[Ask for work|Ocean Breeze Ask]]>><</link>>
 			<br>
 		<</if>>
 	<</if>>
@@ -140,10 +140,10 @@ You are in the Ocean Breeze Cafe.
 			<br>
 		<</if>>
 		<<if $player.gender_appearance is "m">>
-			<<link [[Work as a waiter (1:00)|Ocean Breeze Work]]>><<set $tablesservedstat += random(10,30)>><</link>>
+			<<ind>><<link [[Work as a waiter (1:00)|Ocean Breeze Work]]>><<set $tablesservedstat += random(10,30)>><</link>>
 			<br>
 		<<else>>
-			<<link [[Work as a waitress (1:00)|Ocean Breeze Work]]>><<set $tablesservedstat += random(10,30)>><</link>>
+			<<ind>><<link [[Work as a waitress (1:00)|Ocean Breeze Work]]>><<set $tablesservedstat += random(10,30)>><</link>>
 			<br>
 		<</if>>
 	<</if>>
-- 
GitLab


From 46b802ba6826b73ada9af9f512cd6338724d61c8 Mon Sep 17 00:00:00 2001
From: hwp <you@example.com>
Date: Tue, 20 Sep 2022 00:29:13 -0400
Subject: [PATCH 40/50] gwylan forest rescue cleanup

---
 game/base-clothing/shop.twee                  | 109 +--
 game/overworld-forest/loc-cabin/main.twee     |  19 +-
 .../loc-cabin/punishment.twee                 |  23 +-
 game/overworld-forest/loc-forest/events.twee  | 831 +++---------------
 game/overworld-forest/loc-forest/widgets.twee | 150 ++++
 .../loc-lake/ivory/widgets.twee               |  24 +-
 game/overworld-town/special-robin/walk.twee   |  90 +-
 7 files changed, 371 insertions(+), 875 deletions(-)

diff --git a/game/base-clothing/shop.twee b/game/base-clothing/shop.twee
index 6635f8c306..0e07481aa9 100644
--- a/game/base-clothing/shop.twee
+++ b/game/base-clothing/shop.twee
@@ -1,15 +1,43 @@
 :: Forest Shop [exitCheckBypass]
-<<if $forestShop isnot 1>>
-	<<npc Gwylan>><<person1>>
-	<<set $forestShop to 1>>
-<</if>>
-
 <div id="clothingShop-div" class="main-shop-div">
 	<<forestShop-main>>
 </div>
 
 :: Forest Shop Widgets [widget]
 
+<<widget "forestShop-intro">>
+	<<npc Gwylan>><<person1>>
+	You enter the strange building. The interior is dark and crowded by tall shelves, holding all manner of items.
+	<br><br>
+
+	The quiet is broken by a scraping, then a thud. A mousy <<personsimple>> holding a stepladder appears at the end of the closest aisle.
+	<<if $gwylan_rescue is 1>>
+		It's Gwylan.
+		<br><br>
+		"You came!"
+	<<else>>
+		<br><br>
+		"A customer!"
+	<</if>>
+	<<he>> says, dropping the ladder and walking over. <<He>> wipes <<his>> hands on <<his>> apron. "Welcome to my shop."
+	
+	<<if $gwylan_rescue is 1 and $gwylan_aborted gte 1>>
+		<br><br>
+		<<gwylanRescueApologyShop "Intro">>
+		<<set $gwylan_aborted to 0>>
+	<<elseif $gwylan_rescue isnot 1>>
+		<br><br>
+
+		<<He>> looks about your age, with mousy hair and a hint of freckles. "I'm older than I look," <<he>> says, as if reading your mind. "I'm Gwylan." <<He>> reaches forward, lifts your hand, and shakes it in both <<his>> own. "Pleased to meet you. I sell-" <<he>> pauses. "My grand<<father>> sells-" another pause. "I sell knick-knacks here. Things you won't find in normal shops. Even I don't know what I have in stock!" <<He>> sounds proud.
+		<br><br>
+
+		"I hope you find something you like," <<he>> says, picking the ladder back up. "But don't worry if you don't. My grand<<father>> would say the objects here hide from people they don't want to be bought by." <<He>> laughs. "I could believe it."
+	<</if>>
+	<br><br>
+	<<link [[Next|Forest Shop]]>><<endevent>><</link>>
+	<br>
+<</widget>>
+
 <<widget "forestShop-main">>
 	<<set $outside to 0>><<set $location to "forest_shop">><<effects>>
 	<<set $shopName = "forest">>
@@ -17,73 +45,13 @@
 	<<specialClothesUpdate>>
 	<<if $forest_shop_intro isnot 1>>
 		<<set $forest_shop_intro to 1>>
-		<<if $gwylan_rescue is 1>>
-			You enter the strange building. The interior is dark and crowded by tall shelves, holding all manner of items.
-			<br><br>
-
-			The quiet is broken by a scraping, then a thud. A mousy <<personsimple>> holding a stepladder appears at the end of the closest aisle. It's Gwylan.
-			<br><br>
-
-			"You came!" <<he>> says, dropping the ladder and walking over. <<He>> wipes <<his>> hands on <<his>> apron. "Welcome to my shop."
-
-			<<if $gwylan_aborted is 1>>
-				<<set $gwylan_aborted to 0>>
-				<br><br>
-				<<if $gwylan_eden_coop gte 1>>
-					<<He>> rubs the back of <<his>> neck. "By the way, sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<He>> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-				<<else>>
-					<<He>> rubs the back of <<his>> neck. "By the way, sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-				<</if>>
-
-			<<elseif $gwylan_aborted is 2>>
-				<<set $gwylan_aborted to 0>>
-				<br><br>
-				<<He>> rubs the back of <<his>> neck. "By the way, sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-
-			<<elseif $gwylan_aborted is 3>>
-				<<set $gwylan_aborted to 0>>
-				<br><br>
-				<<He>> looks you over with concern. "Are you feeling okay? You look a little pale, and I thought I heard you screaming the other night..."
-			<</if>>
-
-		<<else>>
-			You enter the strange building. The interior is dark and crowded by tall shelves, holding all manner of items. The quiet is broken by a scraping, then a thud. A <<personsimple>> holding a stepladder appears at the end of the closest aisle.
-			<br><br>
-
-			"A customer!" <<he>> says, dropping the ladder and walking over. <<He>> wipes <<his>> hands on <<his>> apron. "Welcome to my shop."
-			<br><br>
-
-			<<He>> looks about your age, with mousy hair and a hint of freckles. "I'm older than I look," <<he>> says, as if reading your mind. "I'm Gwylan." <<He>> reaches forward, lifts your hand, and shakes it in both <<his>> own. "Pleased to meet you. I sell-" <<he>> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks here. Things you won't find in normal shops. Even I don't know what I have in stock!" <<He>> sounds proud.
-			<br><br>
-
-			"I hope you find something you like," <<he>> says, picking the ladder back up. "But don't worry if you don't. My grand<<if $pronoun is "m">>father<<else>>mother<</if>> would say the objects here hide from people they don't want to be bought by." <<He>> laughs. "I could believe it."
-		<</if>>
-		<br><br>
-		<<link [[Next|Forest Shop]]>><<endevent>><</link>>
-		<br>
-
+		<<forestShop-intro>>
 	<<else>>
 		You are in the forest shop. The interior is dark and crowded by tall shelves, holding all manner of items. Most are useless knick-knacks, but some interest you.
 		<br><br>
-		<<if $gwylan_aborted is 1>>
-			<<set $gwylan_aborted to 0>>
-			<<if $gwylan_eden_coop gte 1>>
-				"Hey," Gwylan says as you walk in. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<He>> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				"Hey," Gwylan says as you walk in. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<set $gwylan_aborted to 0>>
-			"Hey," Gwylan says as you walk in. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-
-		<<elseif $gwylan_aborted is 3>>
+		<<if $gwylan_aborted gte 1>>
+			<<gwylanRescueApologyShop>>
 			<<set $gwylan_aborted to 0>>
-			<br><br>
-			"Hey," Gwylan says as you walk in. <<nnpc_He "Gwylan">> looks concerned. "Are you feeling okay? You look a little pale, and I thought I heard you screaming the other night..."
-
 		<<else>>
 			You hear Gwylan shuffling somewhere in the gloom.
 		<</if>>
@@ -160,7 +128,10 @@
 			<</link>>
 			<br>
 		<<elseif $tryOn.value is 0>>
-			<<link [[Leave|Forest]]>><<shopClothingFilterReset>><<endnpc>><<unset $clothes_choice>><<ShowUnderEquip "normal">><<ShowUnderEquip "over">><<set $tryOn.autoReset to true>><<set $eventskip to 1>><<unset $tempDisable>><<unset $forestShop>><</link>>
+			<<link [[Leave|Forest]]>>
+				<<shopClothingFilterReset>><<endnpc>><<unset $clothes_choice>><<ShowUnderEquip "normal">><<ShowUnderEquip "over">>
+				<<set $tryOn.autoReset to true>><<set $eventskip to 1>><<unset $tempDisable>>
+			<</link>>
 		<</if>>
 	<</if>>
 <</widget>>
diff --git a/game/overworld-forest/loc-cabin/main.twee b/game/overworld-forest/loc-cabin/main.twee
index 5780fc1a76..bd38591188 100644
--- a/game/overworld-forest/loc-cabin/main.twee
+++ b/game/overworld-forest/loc-cabin/main.twee
@@ -2274,13 +2274,9 @@ You search the clearing for wild flowers, and find a number of poppies growing a
 <<if $alarm is 1 and $rescue is 0 and $forest lte 20 and $gwylan_aborted isnot 1>>
 	<<set $alarm to 0>>
 	<<set $gwylan_aborted to 1>>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		You see a <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<<else>>
-		You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<</if>>
+	You see <<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>a <<nnpc_gendery "Gwylan">><<else>>Gwylan<</if>> burst through the treeline, alarmed by your shout.
+	<<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
+	<br><br>
 <<elseif $alarm is 1 and $rescue is 0 and $forest gte 21>>
 	<<if $gwylan_rescue is 1>>
 		<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
@@ -2345,16 +2341,13 @@ You search the clearing for wild flowers, and find a number of poppies growing a
 
 <<effects>>
 <<effectsman>>
+
 <<if $alarm is 1 and $rescue is 0 and $forest lte 20 and $gwylan_aborted isnot 1>>
 	<<set $alarm to 0>>
 	<<set $gwylan_aborted to 1>>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		You see a <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<<else>>
-		You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
+	You see <<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>a <<nnpc_gendery "Gwylan">><<else>>Gwylan<</if>> burst through the treeline, alarmed by your shout.
+	<<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
 	<br><br>
-	<</if>>
 <<elseif $alarm is 1 and $rescue is 0 and $forest gte 21>>
 	<<if $gwylan_rescue is 1>>
 		<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
diff --git a/game/overworld-forest/loc-cabin/punishment.twee b/game/overworld-forest/loc-cabin/punishment.twee
index 1e08dfb54b..36a824c3d2 100644
--- a/game/overworld-forest/loc-cabin/punishment.twee
+++ b/game/overworld-forest/loc-cabin/punishment.twee
@@ -194,23 +194,18 @@ Fearing whatever Eden has in store for you, you pull hard.
 <<effectsman>>
 
 <<if $location is "forest">>
-	<<if $alarm is 1 and $rescue is 0 and $forest lte 20 and $gwylan_aborted isnot 1>>
-		<<set $alarm to 0>>
-		<<set $gwylan_aborted to 1>>
-		<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-			You see a <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
+	<<if $alarm is 1 and $rescue is 0>>
+		<<if $forest lte 20 and $gwylan_aborted isnot 1>>
+			<<set $alarm to 0>>
+			<<set $gwylan_aborted to 1>>
+			
+			You see <<if $forest_shop_intro is 1 or $gwylan_rescue is 1>>Gwylan<<else>>a <<nnpc_gendery "Gwylan">><</if>> burst through the treeline, alarmed by your shout.
+			<<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
 			<br><br>
-		<<else>>
-			You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
+		<<elseif $forest gt 20>>
+			<<forestRescueFail "hunter">>
 			<br><br>
 		<</if>>
-	<<elseif $alarm is 1 and $rescue is 0 and $forest gte 21>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from town for anyone to hear you.</span>
-		<</if>>
-		<br><br>
 	<</if>>
 <</if>>
 
diff --git a/game/overworld-forest/loc-forest/events.twee b/game/overworld-forest/loc-forest/events.twee
index a8d5cdc8ef..235bd4919b 100644
--- a/game/overworld-forest/loc-forest/events.twee
+++ b/game/overworld-forest/loc-forest/events.twee
@@ -1,22 +1,22 @@
 :: Forest Clearing
 <<location "forest">><<effects>>
+<!-- Make sure $phase is non-zero when you write a link here -->
 
 <<if $foresthunt gte 1>>
-<<set $foresthunt += 1>>
+	<<set $foresthunt += 1>>
 <</if>>
-<<if $phase is 1>>
-<<set $phase to 0>>
-You search for plants long and sturdy enough to build an improvised garment. You find some suitable specimens and tie them together around your chest. It's fragile and revealing, and you don't think you could take it off without breaking it, but it's better than nothing.
-<<plantupper>>
-<br><br>
-
+You search for plants long and sturdy enough to build an improvised garment. You find some suitable specimens and tie them together around your
+<<if $phase is 1>>	
+	chest.
+	<<plantupper>>
 <<elseif $phase is 2>>
-<<set $phase to 0>>
-You search for plants long and sturdy enough to build an improvised garment. You find some suitable specimens and tie them together around your waist. It's fragile and revealing, and you don't think you could take it off without breaking it, but it's better than nothing.
-<<plantlower>>
-<br><br>
+	waist.
+	<<plantlower>>
 <</if>>
+It's fragile and revealing, and you don't think you could take it off without breaking it, but it's better than nothing.
+<br><br>
 
+<<set $phase to 0>>
 <<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
 <br>
 
@@ -45,18 +45,13 @@ You drop to your knees, and search beneath the decaying roots.
 <<if $tendingSuccess>>
 	<span class="green">You find some tasty <<icon "tending/mushroom.png">> mushrooms that should fetch a price at market.</span>
 	<<tending_pick mushroom>>
-	<br><br>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
-	<br>
 <<else>>
 	<span class="red">None of the mushrooms look any good.</span><<gtending>><<tending 2>>
-	<br><br>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
-	<br>
 <</if>>
+<br><br>
 
+<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+<br>
 
 :: Forest Mushrooms2 Pick
 <<effects>>
@@ -67,17 +62,13 @@ You drop to your knees, and search beneath the decaying roots.
 <<if $tendingSuccess>>
 	<span class="green">You find some fat <<icon "tending/wolfshroom.png">> mushrooms that should fetch a good price.</span>
 	<<tending_pick wolfshroom>>
-	<br><br>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
-	<br>
 <<else>>
 	<span class="red">None of the mushrooms look any good.</span><<gtending>><<tending 2>>
-	<br><br>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
-	<br>
 <</if>>
+<br><br>
+
+<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+<br>
 
 
 
@@ -96,30 +87,8 @@ You drop to your knees, and search beneath the decaying roots.
 <<effects>>
 <<effectsman>>
 
-<<if $alarm is 1 and $forest lte 20 and $gwylan_aborted isnot 2>>
-	<<set $gwylan_aborted to 2>>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		You see a mousy <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the wolf, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<<else>>
-		You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the wolf, <span class="red">then turns and runs away.</span>
-	<br><br>
-	<</if>>
-<<elseif $alarm is 1 and $forest gte 21>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
-	<br><br>
+<<if $alarm is 1>>
+	<<gwylanRescueFail "wolf">>
 <</if>>
 
 <br>
@@ -141,53 +110,53 @@ You drop to your knees, and search beneath the decaying roots.
 
 <<if $enemyarousal gte $enemyarousalmax>>
 
-<<beastejaculation>>
+	<<beastejaculation>>
+
+	<<if $syndromewolves gte 1>>
+		<<if $monster is 1>>
+			<<bHe>> grabs you by the scruff of your neck with little effort, before hauling you over one shoulder. You feel like a helpless puppy as you're being carried away.
+		<<else>>
+			<<bHe>> grabs you by the scruff of your neck like you're an errant puppy.
+		<</if>>
+
+		<br><br>
+		<<link [[Let it happen|Wolf Cave Returned]]>><<endcombat>><</link>>
+		<br>
+		<<link [[Struggle|Forest Wolf Molestation Resist]]>><<endcombat>><<set $molestationstart to 1>><</link>>
+		<br>
 
-<<if $syndromewolves gte 1>>
-	<<if $monster is 1>>
-		<<bHe>> grabs you by the scruff of your neck with little effort, before hauling you over one shoulder. You feel like a helpless puppy as you're being carried away.
 	<<else>>
-		<<bHe>> grabs you by the scruff of your neck like you're an errant puppy.
-	<</if>>
+		The Black Wolf seems satisfied, but it isn't over.
+		<<if $monster is 1>>
+			"You. With me," <<bhe>> barks. You're not sure if you have any choice. With a display of force, <<bhe>> hauls you over one shoulder.
+		<<else>>
+			<<bHe>> grabs you by the scruff of your neck.
+		<</if>>
+		<<bHe>> wants to take you somewhere.
+		<br><br>
 
-	<br><br>
-	<<link [[Let it happen|Wolf Cave Returned]]>><<endcombat>><</link>>
-	<br>
-	<<link [[Struggle|Forest Wolf Molestation Resist]]>><<endcombat>><<set $molestationstart to 1>><</link>>
-	<br>
+		<<link [[Let it happen|Forest Wolf Cave Intro]]>><<endcombat>><</link>>
+		<br>
+		<<link [[Struggle|Forest Wolf Molestation Resist]]>><<endcombat>><<set $molestationstart to 1>><</link>>
+		<br>
+	<</if>>
+<<elseif $enemyhealth lte 0>><<set $foresthunt to 0>>
 
-<<else>>
-	The Black Wolf seems satisfied, but it isn't over.
 	<<if $monster is 1>>
-		"You. With me," <<bhe>> barks. You're not sure if you have any choice. With a display of force, <<bhe>> hauls you over one shoulder.
+		Despite <<bhis>> show of force, you manage to overcome it. You wrestle free from the Black Wolf's grasp. "Trouble," <<bhe>> growls. "Weren't easy prey." <<bHe>> flees into the forest, tail between <<bhis>> legs. You feel proud, realising it was no easy feat defeating something nearly twice your size.
 	<<else>>
-		<<bHe>> grabs you by the scruff of your neck.
+		Despite <<bhis>> power, you manage to defeat the Black Wolf. <<bHe>> flees into the forest, tail between <<bhis>> legs.
 	<</if>>
-	<<bHe>> wants to take you somewhere.
 	<br><br>
 
-	<<link [[Let it happen|Forest Wolf Cave Intro]]>><<endcombat>><</link>>
-	<br>
-	<<link [[Struggle|Forest Wolf Molestation Resist]]>><<endcombat>><<set $molestationstart to 1>><</link>>
-	<br>
-<</if>>
-<<elseif $enemyhealth lte 0>><<set $foresthunt to 0>>
-
-<<if $monster is 1>>
-	Despite <<bhis>> show of force, you manage to overcome it. You wrestle free from the Black Wolf's grasp. "Trouble," <<bhe>> growls. "Weren't easy prey." <<bHe>> flees into the forest, tail between <<bhis>> legs. You feel proud, realising it was no easy feat defeating something nearly twice your size.
-<<else>>
-	Despite <<bhis>> power, you manage to defeat the Black Wolf. <<bHe>> flees into the forest, tail between <<bhis>> legs.
-<</if>>
-<br><br>
-
-<<clotheson>>
-<<endcombat>>
+	<<clotheson>>
+	<<endcombat>>
 
-<<tearful>> you gather yourself.
-<br><br>
+	<<tearful>> you gather yourself.
+	<br><br>
 
-<<link [[Next|Forest]]>><<set $stress -= 1000>><<set $eventskip to 1>><<set $eventskip to 1>><</link>>
-<br>
+	<<link [[Next|Forest]]>><<set $stress -= 1000>><<set $eventskip to 1>><<set $eventskip to 1>><</link>>
+	<br>
 <</if>>
 
 :: Forest Wolf Cave Intro
@@ -220,22 +189,8 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 <<effects>>
 <<effectsman>>
 
-<<if $alarm is 1 and $forest lte 20 and $gwylan_aborted isnot 1>>
-	<<set $gwylan_aborted to 1>>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		You see a mousy <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<<else>>
-		You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-	<br><br>
-	<</if>>
-<<elseif $alarm is 1 and $forest gte 21>>
-	<<if $gwylan_rescue is 1>>
-		<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-	<<else>>
-		<span class="red">You're too far from the town for anyone to hear you.</span>
-	<</if>>
-	<br><br>
+<<if $alarm is 1>>
+	<<gwylanRescueFail "hunter">>
 <</if>>
 
 <<man>>
@@ -258,13 +213,12 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 		Eden <<if $enemyanger gte ($enemyangermax / 5) * 2>>glares at you and growls,<<else>>smirks at you and says,<</if>> "I knew I'd be able to catch you again. Come on, I'm taking you home."
 	<<else>>
 		<<if $enemyanger gte 20>>
-		The hunter smirks. "You're a feisty one. I like that."
+			The hunter smirks. "You're a feisty one. I like that."
 		<<else>>
-		The hunter smiles. "You're a gentle creature, aren't you? I'd best take you with me, it wouldn't do to leave you alone out here."
+			The hunter smiles. "You're a gentle creature, aren't you? I'd best take you with me, it wouldn't do to leave you alone out here."
 		<</if>>
 	<</if>>
 	<<He>> produces a length of rope from <<his>> bag. You're going to be tied up!
-
 	<br><br>
 
 	<<link [[Don't struggle|Forest Hunter Intro]]>><<clotheson>><<endcombat>><</link>>
@@ -303,7 +257,8 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 <<He>> drops you on the hard floor and places a collar around your neck. It shuts with a click. <<He>> stands over you, and attaches a leash to your collar. <<He>> then unties the rope, freeing your arms and legs.
 <br><br>
 
-<<if $hunterintro isnot 1>><<set $hunterintro to 1>>
+<<if $hunterintro isnot 1>>
+	<<set $hunterintro to 1>>
 	"You're lucky I found you," <<he>> says. "The woods are dangerous, you'd have gotten hurt. My name is Eden." <<He>> pauses, as if unsure about something. <<He>> seems different to when <<he>> captured you, softer, despite you now being bound and collared at <<his>> feet.
 	<br><br>
 
@@ -333,22 +288,8 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 
 <<effectsman>>
 
-<<if $alarm is 1 and $forest lte 20 and $gwylan_aborted isnot 1>>
-	<<set $gwylan_aborted to 1>>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		You see a mousy <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<<else>>
-		You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-	<br><br>
-	<</if>>
-<<elseif $alarm is 1 and $forest gte 21>>
-	<<if $gwylan_rescue is 1>>
-		<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-	<<else>>
-		<span class="red">You're too far from the town for anyone to hear you.</span>
-	<</if>>
-	<br><br>
+<<if $alarm is 1>>
+	<<gwylanRescueFail "hunter">>
 <</if>>
 
 <<man>>
@@ -405,30 +346,8 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 <<effects>>
 <<effectsman>>
 
-<<if $alarm is 1 and $forest lte 20 and $gwylan_aborted isnot 2>>
-	<<set $gwylan_aborted to 2>>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		You see a mousy <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the wolf, <span class="red">then turns and runs away.</span>
-		<br><br>
-	<<else>>
-		You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> takes one look at the wolf, <span class="red">then turns and runs away.</span>
-	<br><br>
-	<</if>>
-<<elseif $alarm is 1 and $forest gte 21>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
-	<br><br>
+<<if $alarm is 1>>
+	<<gwylanRescueFail "wolf">>
 <</if>>
 
 <br>
@@ -535,11 +454,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 	<<generate1>><<generate2>><<maninit>>
 	A <<fullGroup>> walk into view. <<person1>>As they walk by, they reach out and grab you!
 	<br><br>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 <</if>>
 
 <<effects>>
@@ -547,19 +462,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -603,56 +506,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
 	<br>
 <<elseif $rescue is 1 and $forest lte 20>>
-	The <<person1>><<person>> charges you, but is interrupted when a flying ?gwylanItem smacks <<him>> in the face. The <<person2>><<person>> looks over, only for a ?gwylanItem to fly into <<his>> face as well.
-
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Get away from <<phim>>. I have more." As if to demonstrate, <<nnpc_he "Gwylan">> throws a ?gwylanItem, hitting the <<person1>><<person>> in the face again. The pair glance at each other, then turn and run.
-		<br><br>
-
-		"I hope they weren't customers," the <<nnpc_gendery "Gwylan">> mutters. "Well, I wouldn't want their money anyway." <<nnpc_He "Gwylan">> steps out from the treeline, walking toward you. "You okay? Good thing I was in the area."
-		<br><br>
-
-		<<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you."
-		<br><br>
-
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud.
-
-	<<else>>
-		"Hey!" Gwylan shouts from beyond the treeline. "Get away from <<phim>>. I have more." As if to demonstrate, <<nnpc_he "Gwylan">> throws a ?gwylanItem, hitting the <<person1>><<person>> in the face again. The pair glance at each other, then turn and run.
-		<br><br>
-
-		"I hope they weren't customers," Gwylan mutters. "Well, I wouldn't want their money anyway." <<nnpc_He "Gwylan">> steps out from the treeline, walking toward you. "You okay? Good thing I was in the area."
-		<<if $gwylan_aborted is 1>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<nnpc_He "Gwylan">> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-		<</if>>
-	<</if>>
-	<br><br>
-
-	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted isnot 1>>
-		<<nnpc_He "Gwylan">> looks around for a moment, as if waiting for something. "Strange," <<nnpc_he "Gwylan">> says to <<nnpc_himself "Gwylan">>. "Usually the <<nnpc_title "Eden">> is here too. Must be busy."
-	<br><br>
-	<</if>>
-
-	<<if $gwylan_rescue isnot 1>>
-		<<set $gwylan_rescue to 1>>
-		<<nnpc_He "Gwylan">> starts to walk away, but stops and turns around. "By the way," <<nnpc_he "Gwylan">> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
-		<br><br>
-	<</if>>
-	<<nnpc_He "Gwylan">> gathers <<nnpc_his "Gwylan">> items, then walks off in the direction of <<nnpc_his "Gwylan">> shop.
-	<br><br>
-
-	<<clotheson>><<set $gwylan_aborted to 0>>
-	<<endcombat>>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+	<<gwylanForestRescue "man">>
 
 <<elseif $rescue is 1 and $forest gte 21>>
 	You hear a gun fire close by, and a bullet lands at the pair's feet. They back off in fear and flee into the forest.
@@ -694,11 +548,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 	<<neutral 1>>
 	<<molested>>
 	<<beastCombatInit>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 	<<set $enemytrust -= 40>>
 <</if>>
 
@@ -707,19 +557,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -760,19 +598,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -821,60 +647,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
 	<br>
 <<elseif $rescue is 1 and $forest lte 20>>
-	The <<beasttype>> growls, but is hit in the face by a flying ?gwylanItem. <<bHe>> yelps and looks around, alarmed.
-	<<if $monster is 1>>
-		"Human attack! Where human?!"
-	<</if>>
-	<br><br>
-
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
-		<br><br>
-
-		"I swear they get more aggressive every day," the <<nnpc_gendery "Gwylan">> mutters. <<nnpc_He "Gwylan">> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area."
-		<br><br>
-
-		<<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
-		<br><br>
-
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud.
-
-	<<else>>
-		"Hey!" Gwylan shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
-			<br><br>
-
-		"I swear they get more aggressive every day," Gwylan mutters. <<nnpc_He "Gwylan">> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area."
-		<<if $gwylan_aborted is 1>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<nnpc_He "Gwylan">> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the whole pack breaking my door down."
-		<</if>>
-	<</if>>
-	<br><br>
-
-	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted isnot 1>>
-		<<nnpc_He "Gwylan">> glances around. "Strange," <<nnpc_he "Gwylan">> says to <<nnpc_himself "Gwylan">>. "I thought the <<nnpc_title "Eden">> would be here too. Must be busy. Ah well."
-	<br><br>
-	<</if>>
-
-	<<if $gwylan_rescue isnot 1>>
-		<<set $gwylan_rescue to 1>>
-		<<nnpc_He "Gwylan">> starts to walk away, but stops and turns around. "By the way," <<nnpc_he "Gwylan">> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
-		<br><br>
-	<</if>>
-	<<nnpc_He "Gwylan">> gathers <<nnpc_his "Gwylan">> items, then walks off in the direction of <<nnpc_his "Gwylan">> shop.
-	<br><br>
-
-	<<clotheson>><<set $gwylan_aborted to 0>>
-	<<endcombat>>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+	<<gwylanForestRescue "beast">>
 
 <<elseif $rescue is 1 and $forest gte 21>>
 	You hear a gun fire close by, and a bullet lands near the <<beasttype>>. <<bHe>> backs off in fear and flees into the forest.
@@ -1091,30 +864,14 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 	<<neutral 1>>
 	<<molested>>
 	<<beastCombatInit>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 <</if>>
 <<effects>>
 <<effectsman>>
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -1166,57 +923,7 @@ Six pairs of eyes stare at you through the dim light. The pack advances on you.
 	<<link [[Next|Forest Swim]]>><<set $eventskip to 1>><</link>>
 	<br>
 <<elseif $rescue is 1 and $forest lte 20>>
-	The <<beasttype>> hisses, but is hit in the face by a flying ?gwylanItem. <<bHe>> looks around, alarmed.
-	<br><br>
-
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> dives back into the churning water.
-		<br><br>
-
-		"The rivers keep getting more dangerous," the <<nnpc_gendery "Gwylan">> mutters. <<nnpc_He "Gwylan">> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area." <<nnpc_He "Gwylan">> grasps your arm and pulls you out of the water.
-		<br><br>
-
-		<<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
-		<br><br>
-
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud.
-
-	<<else>>
-		"Hey!" Gwylan shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> dives back into the churning water.
-			<br><br>
-
-		"The rivers keep getting more dangerous," the <<nnpc_gendery "Gwylan">> mutters. <<nnpc_He "Gwylan">> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area." <<nnpc_He "Gwylan">> grasps your arm and pulls you out of the water.
-		<<if $gwylan_aborted is 1>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<nnpc_He "Gwylan">> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-		<</if>>
-	<</if>>
-	<br><br>
-
-	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted isnot 1>>
-		<<nnpc_He "Gwylan">> looks around for a moment. "Strange," <<nnpc_he "Gwylan">> says to <<nnpc_himself "Gwylan">>. "I thought the <<nnpc_title "Eden">> would be here. Must be busy. Ah well."
-	<br><br>
-	<</if>>
-
-	<<if $gwylan_rescue isnot 1>>
-		<<set $gwylan_rescue to 1>>
-		<<nnpc_He "Gwylan">> starts to walk away, but stops and turns around. "By the way," <<nnpc_he "Gwylan">> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
-		<br><br>
-	<</if>>
-	<<nnpc_He "Gwylan">> gathers <<nnpc_his "Gwylan">> items, then walks off in the direction of <<nnpc_his "Gwylan">> shop.
-	<br><br>
-
-	<<clotheson>><<set $gwylan_aborted to 0>>
-	<<endcombat>>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+	<<gwylanForestRescue "river">>
 
 <<elseif $rescue is 1 and $forest gte 21>>
 	You hear a gun fire close by, and a bullet lands near the <<beasttype>>. <<bHe>> backs off in fear and flees into the forest.
@@ -1411,19 +1118,7 @@ The snakes slither off of you, escaping through nooks and crannies all around th
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -1609,19 +1304,7 @@ You throw your head back and howl into the canopy. The <<if $phase is 1>><<beast
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -1650,11 +1333,7 @@ You throw your head back and howl into the canopy. The <<if $phase is 1>><<beast
 	<<set $consensual to 1>>
 	<<neutral 1>>
 	<<beastCombatInit>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 
 	<<set $NPCList[0].stance to "top">><<set $enemytrust -= 20>><<deviancy2>>
 <</if>>
@@ -1664,19 +1343,7 @@ You throw your head back and howl into the canopy. The <<if $phase is 1>><<beast
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -1758,60 +1425,7 @@ You throw your head back and howl into the canopy. The <<if $phase is 1>><<beast
 	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
 	<br>
 <<elseif $rescue is 1 and $forest lte 20>>
-	The <<beasttype>> growls, but is hit in the face by a flying ?gwylanItem. <<bHe>> yelps and looks around, alarmed.
-	<<if $monster is 1>>
-		"Human attack! Where human?!"
-	<</if>>
-	<br><br>
-
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
-		<br><br>
-
-		"I swear they get more aggressive every day," the <<nnpc_gendery "Gwylan">> mutters. <<nnpc_He "Gwylan">> steps out from the treeline, walking toward you. "You okay? Good thing I was in the area!"
-		<br><br>
-
-		<<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
-		<br><br>
-
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud.
-
-	<<else>>
-		"Hey!" Gwylan shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
-		<br><br>
-
-		"I swear they get more aggressive every day," Gwylan mutters. <<nnpc_He "Gwylan">> steps out from the treeline, walking toward you. "You okay? Good thing I was in the area!"
-		<<if $gwylan_aborted is 1>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<nnpc_He "Gwylan">> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-		<</if>>
-	<</if>>
-	<br><br>
-
-	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted isnot 1>>
-		<<nnpc_He "Gwylan">> looks around for a moment. "Strange," <<nnpc_he "Gwylan">> says to <<nnpc_himself "Gwylan">>. "I thought the <<nnpc_title "Eden">> would be here. Must be busy. Ah well."
-		<br><br>
-	<</if>>
-
-	<<if $gwylan_rescue isnot 1>>
-		<<set $gwylan_rescue to 1>>
-		<<nnpc_He "Gwylan">> starts to walk away, but stops and turns around. "By the way," <<nnpc_he "Gwylan">> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
-		<br><br>
-	<</if>>
-	<<nnpc_He "Gwylan">> gathers <<nnpc_his "Gwylan">> items, then walks off in the direction of <<nnpc_his "Gwylan">> shop.
-	<br><br>
-
-	<<clotheson>><<set $gwylan_aborted to 0>>
-	<<endcombat>>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+	<<gwylanForestRescue "beast">>
 
 <<elseif $rescue is 1 and $forest gte 21>>
 	You hear a gun fire close by, and a bullet lands near the <<beasttype>>. <<bHe>> backs off in fear and flees into the forest.
@@ -2072,19 +1686,7 @@ You give <<him>> a slow twirl while walking towards <<him>>, making sure <<he>>
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -2288,11 +1890,7 @@ The pair share a grin. "We'll be happy to oblige," <<he>> says, stepping closer.
 	<<molested>>
 	<<set $noFinish to 1>>
 	<<maninit>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 <<elseif $sexstart is 1>>
 	<<set $sexstart to 0>>
 	<<consensual>>
@@ -2300,11 +1898,7 @@ The pair share a grin. "We'll be happy to oblige," <<he>> says, stepping closer.
 	<<neutral 1>>
 	<<set $noFinish to 1>>
 	<<maninit>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 <</if>>
 
 <<effects>>
@@ -2312,19 +1906,7 @@ The pair share a grin. "We'll be happy to oblige," <<he>> says, stepping closer.
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -2359,61 +1941,7 @@ The pair share a grin. "We'll be happy to oblige," <<he>> says, stepping closer.
 	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
 
 <<elseif $rescue is 1 and $forest lte 20>>
-	The <<person1>><<person>> charges you, but a flying ?gwylanItem smacks <<him>> in the face. The <<person2>><<person>> looks over. A ?gwylanItem hits <<him>> as well.
-
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Get away from <<phim>>. I have more." As if to demonstrate, <<nnpc_he "Gwylan">> throws a ?gwylanItem, hitting the <<person1>><<person>> in the face again. The pair glance at each other, then turn and run.
-		<br><br>
-
-		"I hope they weren't customers," the <<nnpc_gendery "Gwylan">> mutters. "Well, I don't want their money anyway." <<nnpc_He "Gwylan">> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area."
-		<br><br>
-
-		<<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
-		<br><br>
-
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud.
-
-	<<else>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Get away from <<phim>>. I have more." As if to demonstrate, <<nnpc_he "Gwylan">> throws a ?gwylanItem, hitting the <<person1>><<person>> in the face again. The pair glance at each other, then turn and run.
-		<br><br>
-
-		"I hope they weren't customers," the <<nnpc_gendery "Gwylan">> mutters. "Well, I don't want their money anyway." <<nnpc_He "Gwylan">> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area."
-		<<if $gwylan_aborted is 1>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<nnpc_He "Gwylan">> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-		<</if>>
-	<</if>>
-	<br><br>
-
-	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted isnot 1>>
-		<<nnpc_He "Gwylan">> looks around for a moment. "Strange," <<nnpc_he "Gwylan">> says to <<nnpc_himself "Gwylan">>. "I thought the <<nnpc_title "Eden">> would be here. Must be busy. Ah well."
-		<br><br>
-	<</if>>
-
-	<<if $gwylan_rescue isnot 1>>
-		<<set $gwylan_rescue to 1>>
-		<<nnpc_He "Gwylan">> starts to walk away, but stops and turns around. "By the way," <<nnpc_he "Gwylan">> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
-		<br><br>
-	<</if>>
-
-	<<nnpc_He "Gwylan">> gathers <<nnpc_his "Gwylan">> items, then walks off in the direction of <<nnpc_his "Gwylan">> shop.
-	<br><br>
-
-	<<clotheson>><<set $gwylan_aborted to 0>>
-	<<endcombat>>
-
-	You feel a jolt of pain as the slime punishes you for defiance.
-	<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
-	<br><br>
-
-	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+	<<gwylanForestRescue "man" "slime">>
 
 <<elseif $rescue is 1 and $forest gte 21>>
 	You hear a gun fire close by, and a bullet lands at the pair's feet. They back off in fear and flee into the forest.
@@ -2423,8 +1951,7 @@ The pair share a grin. "We'll be happy to oblige," <<he>> says, stepping closer.
 		<<clotheson>>
 		<<endcombat>>
 
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 		<br><br>
 
 		<<edenCagedSave>>
@@ -2435,10 +1962,7 @@ The pair share a grin. "We'll be happy to oblige," <<he>> says, stepping closer.
 		<<clotheson>>
 		<<endcombat>>
 
-		<br><br>
-
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 		<br><br>
 
 		<<if $gwylan_eden_coop gte 1>>
@@ -2542,11 +2066,7 @@ A <<beasttype>> steps out from the forest, sniffs you, then mounts.
 	<<molested>>
 	<<beastCombatInit>>
 	<<set $noFinish to 1>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 
 	<<set $NPCList[0].stance to "top">>
 <<elseif $sexstart is 1>>
@@ -2556,11 +2076,7 @@ A <<beasttype>> steps out from the forest, sniffs you, then mounts.
 	<<neutral 1>>
 	<<beastCombatInit>>
 	<<set $noFinish to 1>>
-	<<if isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1) and $forest lte 20>>
-		<<set $rescue to 2>>
-	<<elseif (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1)) or $forest lte 20>>
-		<<enable_rescue>>
-	<</if>>
+	<<forestRescueSetup>>
 
 	<<set $NPCList[0].stance to "top">>
 <</if>>
@@ -2570,19 +2086,7 @@ A <<beasttype>> steps out from the forest, sniffs you, then mounts.
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -2616,63 +2120,7 @@ A <<beasttype>> steps out from the forest, sniffs you, then mounts.
 	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
 
 <<elseif $rescue is 1 and $forest lte 20>>
-	The <<beasttype>> growls, but is hit in the face by a flying ?gwylanItem. <<bHe>> yelps and looks around, alarmed.
-	<<if $monster is 1>>
-		"Human attack! Where?!"
-	<</if>>
-	<br><br>
-
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		"Hey!" a <<nnpc_gendery "Gwylan">> shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
-		<br><br>
-
-		"I swear they get more aggressive every day," the <<nnpc_gendery "Gwylan">> mutters. <<nnpc_He "Gwylan">> steps out from the treeline, walking toward you. "You okay? Good thing I was in the area!"
-		<br><br>
-
-		<<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
-		<br><br>
-
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud.
-
-	<<else>>
-		"Hey!" Gwylan shouts from beyond the treeline. "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
-		<br><br>
-
-		"I swear they get more aggressive every day," Gwylan mutters. <<nnpc_He "Gwylan">> steps out from the treeline, walking toward you. "You okay? Good thing I was in the area!"
-		<<if $gwylan_aborted is 1>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." <<nnpc_He "Gwylan">> frowns. "Why were you two fighting anyway? Did you fall out?"
-
-			<<else>>
-				<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
-			<</if>>
-
-		<<elseif $gwylan_aborted is 2>>
-			<<nnpc_He "Gwylan">> can't meet your gaze. "Sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down."
-		<</if>>
-	<</if>>
-	<br><br>
-
-	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted isnot 1>>
-		<<nnpc_He "Gwylan">> looks around for a moment. "Strange," <<nnpc_he "Gwylan">> says to <<nnpc_himself "Gwylan">>. "I thought the <<nnpc_title "Eden">> would be here. Must be busy. Ah well."
-		<br><br>
-	<</if>>
-
-	<<if $gwylan_rescue isnot 1>>
-		<<set $gwylan_rescue to 1>>
-		<<nnpc_He "Gwylan">> starts to walk away, but stops and turns around. "By the way," <<nnpc_he "Gwylan">> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
-		<br><br>
-	<</if>>
-
-	<<nnpc_He "Gwylan">> gathers <<nnpc_his "Gwylan">> items, then walks off in the direction of <<nnpc_his "Gwylan">> shop.
-	You feel a jolt of pain as the slime punishes you for defiance.
-	<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
-	<br><br>
-
-	<<clotheson>><<set $gwylan_aborted to 0>>
-	<<endcombat>>
-
-	<<link [[Next|Forest]]>><<endevent>><</link>>
+	<<gwylanForestRescue "beast" "slime">>
 
 <<elseif $rescue is 1 and $forest gte 21>>
 	You hear a gun fire close by, and a bullet lands at the pair's feet. They back off in fear and flee into the forest.
@@ -2682,8 +2130,7 @@ A <<beasttype>> steps out from the forest, sniffs you, then mounts.
 		<<clotheson>>
 		<<endcombat>>
 
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 		<br><br>
 
 		<<edenCagedSave>>
@@ -2694,8 +2141,7 @@ A <<beasttype>> steps out from the forest, sniffs you, then mounts.
 		<<clotheson>>
 		<<endcombat>>
 
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 		<br><br>
 
 		<<if $gwylan_eden_coop gte 1>>
@@ -3355,7 +2801,7 @@ You escape into the forest.
 <<effects>><<set $rescued++>>
 <<if $phase is 0 or $phase is 2>>
 	You hear a gun fire close by, and a bullet lands at the pair's feet. At the same time, a ?gwylanItem crashes into the <<person1>><<persons>> face. They back off in fear and flee into the forest.
-	<<elseif $phase is 1 or $phase is 3>>
+<<elseif $phase is 1 or $phase is 3>>
 	You hear a gun fire close by, and a bullet lands near the <<beasttype>>. At the same time, a ?gwylanItem crashes into the <<beasttype>>'s side. <<bHe>> backs off in fear and flees into the forest.
 <<else>>
 	You hear a gun fire close by, and a bullet splashes by the <<beasttype>>. At the same time, a ?gwylanItem crashes into the <<beasttype>>'s side. <<bHe>> backs off in fear and flees into the water.
@@ -3402,8 +2848,7 @@ You escape into the forest.
 	"Well, bye," Gwylan says,<<if $phase isnot 4>> gathering <<nnpc_his "Gwylan">> items and<</if>> walking off in the direction of <<nnpc_his "Gwylan">> shop. Eden stays, checking to make sure you're alright.
 	<<if $phase is 2 or $phase is 3>>
 		<br>
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 	<</if>>
 	<br><br>
 
@@ -3441,8 +2886,7 @@ You escape into the forest.
 
 	<<if $phase is 2 or $phase is 3>>
 		<br>
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 	<</if>>
 	<br><br>
 
@@ -3455,45 +2899,43 @@ You escape into the forest.
 
 <<else>>
 	<<set $gwylan_aborted to 0>><<set $gwylan_eden_coop to 1>>
+	<<set _gwylanKnown to ($forest_shop_intro is 1 or $gwylan_rescue is 1)>>
 
 	Eden emerges from the treeline. "You okay?" <<nnpc_he "Eden">> asks. "Good thing I was here to-"
 	<br><br>
-	<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-		<<nnpc_Hes "Eden">> cut off by a mousy <<nnpc_gendery "Gwylan">> bursting through the treeline. Eden unslings <<nnpc_his "Eden">> rifle and points at the <<nnpc_gendery "Gwylan">>.
-		<br><br>
+	<<if !_gwylanKnown>>
+		<<nnpc_Hes "Eden">> cut off by a mousy <<nnpc_gendery "Gwylan">> bursting through the treeline.
+	<<else>>
+		<<nnpc_Hes "Eden">> cut off by Gwylan bursting through the treeline.
+	<</if>>
+	Eden unslings <<nnpc_his "Eden">> rifle and points at the <<nnpc_gendery "Gwylan">>.
+	<<set $_Theboy to (_gwylanKnown ? "Gwylan" : "The " + _text_output)>> <!-- This _text_output comes from the nnpc_gendery call one line above. Do not move this line without accounting for that. -->
+	<br><br>
 
-		"W-wait!" The <<nnpc_gendery "Gwylan">> raises <<nnpc_his "Gwylan">> arms, dropping a ?gwylanItem <<nnpc_he "Gwylan">> was carrying. "I'm on your side! I was coming to save <<phim>>."
-		<br><br>
+	"W-wait!" $_Theboy raises <<nnpc_his "Gwylan">> arms, dropping a ?gwylanItem <<nnpc_he "Gwylan">> was carrying. "I'm on your side! I was coming to save <<phim>>!"
+	<br><br>
 
-		Eden doesn't lower <<nnpc_his "Eden">> gun. "Why should I believe you?" <<nnpc_He "Eden">> rests <<nnpc_his "Eden">> finger on the trigger.
-		<<stress 3>><<gstress>>
-		<br><br>
+	Eden doesn't lower <<nnpc_his "Eden">> gun. "Why should I believe you?" <<nnpc_He "Eden">> rests <<nnpc_his "Eden">> finger on the trigger.
+	<<stress 3>><<gstress>>
+	<br><br>
 
-		"It's true, really!" Gwylan glances in your direction, then back to Eden. "I run a shop by the entrance to town, and I was taking stock when I heard <<phim>> scream. I wanted to save <<phim>>."
-		<br><br>
+	"It's true, really!" $_Theboy glances in your direction, then back to Eden. "I run a shop by the entrance to town, and I was taking stock when I heard <<phim>> scream.
+	<<if $gwylan_rescue is 1>>I've saved <<phim>> before, <<pshes>> my friend.<<else>><<if $forest_shop_intro is 1>><<pShes>> one of my customers.<</if>> I wanted to save <<phim>>.<</if>>"
+	<br><br>
 
-		Eden frowns, then <span class="green">lowers <<nnpc_his "Eden">> gun</span>. "Fine. But don't try anything."
+	<<if !_gwylanKnown>>
+		Eden frowns, then <span class="green">lowers <<nnpc_his "Eden">> gun</span>.
+		"Fine. But don't try anything."
 		<br><br>
 
-		The <<nnpc_gendery "Gwylan">> sighs in relief, and lowers <<nnpc_his "Gwylan"> arms as well. <<nnpc_He "Gwylan">> turns to you. <<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
+		The <<nnpc_gendery "Gwylan">> sighs in relief, and lowers <<nnpc_his "Gwylan">> arms as well. <<nnpc_He "Gwylan">> turns to you. <<nnpc_He "Gwylan">> looks about your age, with mousy hair and freckles. "I'm older than I look," <<nnpc_he "Gwylan">> says, as if reading your mind. "I'm Gwylan. Nice to meet you!"
 		<br><br>
 
-		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud. Eden snorts.
+		"I have a shop right by the outskirts of the forest," <<nnpc_he "Gwylan">> says. "You can't miss it. I sell-" <<nnpc_he "Gwylan">> pauses. "My grand<<father>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<nnpc_He "Gwylan">> sounds proud. Eden snorts.
 		<br><br>
 	<<else>>
-		<<nnpc_Hes "Eden">> cut off by Gwylan bursting through the treeline. Eden unslings <<nnpc_his "Eden">> rifle and points at the <<nnpc_gendery "Gwylan">>.
-
-		"W-wait!" Gwylan raises <<nnpc_his "Gwylan">> arms, dropping a ?gwylanItem <<nnpc_he "Gwylan">> was carrying. "I'm on your side! I was coming to save <<phim>>!"
-		<br><br>
-
-		Eden doesn't lower <<nnpc_his "Eden">> gun. "Why should I believe you?" <<nnpc_He "Eden">> rests <<nnpc_his "Eden">> finger on the trigger.
-		<<stress 3>><<gstress>>
-		<br><br>
-
-		"It's true, really!" Gwylan glances in your direction, then looks back at Eden. "I run a shop by the entrance to town, and was taking stock when I heard <<phim>> scream. <<if $gwylan_rescue is 1>>I've saved <<phim>> before, <<pshes>> my friend.<<else>><<pShes>> one of my customers. I wanted to save <<phim>>.<</if>>"
-		<br><br>
-
-		Eden looks at you for confirmation. You nod, and <span class="green"><<nnpc_he "Eden">> lowers <<nnpc_his "Eden">> gun</span>. "Fine. But don't try anything."
+		Eden looks at you for confirmation. You nod, and <span class="green"><<nnpc_he "Eden">> lowers <<nnpc_his "Eden">> gun</span>.
+		"Fine. But don't try anything."
 		<br><br>
 
 		"I won't," Gwylan says. "I gotta get back to the shop anyway, now that I know <<pshes>> safe."
@@ -3519,8 +2961,7 @@ You escape into the forest.
 
 	<<if $phase is 2 or $phase is 3>>
 		<br>
-		You feel a jolt of pain as the slime punishes you for defiance.
-		<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+		<<slimePunishmentForest>>
 	<</if>>
 	<br><br>
 
@@ -3625,19 +3066,7 @@ The slimes disappear into the river. <<tearful>> you look around frantically.
 
 <<if $alarm is 1 and $rescue is 0>>
 	<<set $alarm to 0>>
-	<<if isLoveInterest("Eden")>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-		<</if>>
-	<<else>>
-		<<if $gwylan_rescue is 1>>
-			<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-		<<else>>
-			<span class="red">You're too far from the town for anyone to hear you.</span>
-		<</if>>
-	<</if>>
+	<<forestRescueFail>>
 	<br><br>
 <</if>>
 
@@ -3779,11 +3208,12 @@ The slimes disappear into the river. <<tearful>> you look around frantically.
 :: Forest Plant Kiss Refuse
 <<location "forest">><<effects>>
 
-<<if $rng gte 51>>
-	"Huh?" The <<persons "normal">> face scrunches up. "But why not?"
-	<br><br>
+"Huh?" The <<persons "normal">> face scrunches up. "But why not?"
+<br><br>
 
-	<<He>> thinks for a few seconds, before gasping. "Oh, I get it! You just want to skip the foreplay! I like your style."
+<<He>> thinks for a few seconds,
+<<if $rng gte 51>>
+	before gasping. "Oh, I get it! You just want to skip the foreplay! I like your style."
 	<<stress 6>><<gstress>>
 	<br><br>
 
@@ -3792,10 +3222,7 @@ The slimes disappear into the river. <<tearful>> you look around frantically.
 
 	<<link [[Next|Forest Plant Sex]]>><<set $molestationstart to 1>><<set $phase to 0>><</link>>
 <<else>>
-	"Huh?" The <<persons "normal">> face scrunches up. "But why not?"
-	<br><br>
-
-	<<He>> thinks for a few seconds, before shrugging. "Well, whatever. I'm sure someone in this forest is willing to smooch a cute <<personsimple>>." <span class="purple">The vines behind <<him>> writhe to life, slithering behind <<him>>.</span> "Later!"
+	before shrugging. "Well, whatever. I'm sure someone in this forest is willing to smooch a cute <<personsimple>>." <span class="purple">The vines behind <<him>> writhe to life, slithering behind <<him>>.</span> "Later!"
 	<br><br>
 
 	<<link [[Next|Forest]]>><<endevent>><<set $eventskip to 1>><</link>>
diff --git a/game/overworld-forest/loc-forest/widgets.twee b/game/overworld-forest/loc-forest/widgets.twee
index bd2ba4bb84..b01237e069 100644
--- a/game/overworld-forest/loc-forest/widgets.twee
+++ b/game/overworld-forest/loc-forest/widgets.twee
@@ -1210,3 +1210,153 @@ or $lowerwetstage gte 3 and $underlowerwetstage gte 3>>
 <<widget "gwylanitem">>
 	<<print either("trophy","baseball","baseball bat","snow globe","magic 8-ball","ping-pong paddle","chess set","piggy bank","mug","cookie tin","frying pan","backscratcher","pencil case","lunch box","lava lamp","flashlight","cuckoo clock","Rubix cube","globe","water gun","dictionary","hand mirror","novelty camera","ziplock bag filled with seashells","miniature stepladder","knick-knack of unknown purpose")>>
 <</widget>>
+
+<<widget "slimePunishmentForest">>
+	You feel a jolt of pain as the slime punishes you for defiance.
+	<<corruption -1>><<pain 8>><<stress 6>><<trauma 6>><<def 1>><<lcorruption>><<ggpain>><<ggtrauma>><<ggstress>>
+<</widget>>
+
+<<widget "forestRescueSetup">>
+	<<set $_eden_available to (isLoveInterest("Eden") and (random(1, 2) is 2 or $eden_rescue isnot 1))>>
+	<<if $_eden_available or $forest lte 20>>
+		<<if $_eden_available and $forest lte 20>>
+			<<set $rescue to 2>>
+		<<else>>
+			<<enable_rescue>>
+		<</if>>
+	<</if>>
+<</widget>>
+
+<<widget "forestRescueFail">>
+	<<if $gwylan_rescue is 1>>
+		<span class="red">You're too deep into the forest for Gwylan to hear you<<if _args[0] isnot "hunter" and isLoveInterest("Eden")>>, and Eden must not be in the area<</if>>.</span>
+	<<else>>
+		<span class="red">You're too far from the town for anyone to hear you<<if _args[0] isnot "hunter" and isLoveInterest("Eden")>>, and Eden must not be in the area<</if>>.</span>
+	<</if>>
+<</widget>>
+
+<<widget "gwylanRescueFail">>
+	<!-- Note: This widget was initially designed to expect ONE argument which is ONLY either "wolf" or "hunter"; If you want to use it for other animals, you will need to edit this widget. -->
+	<<set $_gwylan_abort_value to (_args[0] is "wolf" ? 2 : 1)>>
+	
+	<<if $forest lte 20 and $gwylan_aborted isnot $_gwylan_abort_value>>
+		<<set $gwylan_aborted to $_gwylan_abort_value>>
+		<<set $_assailant to (_args[0] is "wolf" ? "assailant" : "wolf")>> <!-- If you want to use this widget for other animals, change this -->
+		You see <<if $forest_shop_intro is 1 or $gwylan_rescue is 1>>Gwylan<<else>>a mousy <<nnpc_gendery "Gwylan">><</if>> burst through the treeline, alarmed by your shout.
+		<<nnpc_He "Gwylan">> takes one look at the $_assailant, <span class="red">then turns and runs away.</span>
+		<br><br>
+	<<elseif $forest gt 20>>
+		<<forestRescueFail _args[0]>>
+		<br><br>
+	<</if>>
+<</widget>>
+
+<<widget "gwylanRescueApology">>
+	<<if $gwylan_aborted is 3>>
+		<<nnpc_He "Gwylan">> looks you over with concern. "Are you feeling okay? You look a little pale, and I thought I heard you screaming the other night..."
+	<<else>>
+		<<nnpc_He "Gwylan">> can't meet your gaze. <<gwylanRescueApologySpeech>>
+	<</if>>
+<</widget>>
+
+<<widget "gwylanRescueApologyShop">>
+	<<if $gwylan_aborted is 3>>
+		<<if _args[0] is "Intro">>
+			<<nnpc_He "Gwylan">> looks you over with concern.
+		<<else>>
+			"Hey," Gwylan says as you walk in. <<nnpc_He "Gwylan">> looks concerned.
+		<</if>>
+		"Are you feeling okay? You look a little pale, and I thought I heard you screaming the other night..."
+	<<else>>
+		<<if _args[0] is "Robin">>
+			<<nnpc_He "Gwylan">> turns to you with an apologetic smile. <<gwylanRescueApologySpeech "btw">>
+		<<elseif _args[0] is "Intro">>
+			<<nnpc_He "Gwylan">> rubs the back of <<nnpc_his "Gwylan">> neck. <<gwylanRescueApologySpeech "btw">>
+		<<else>>
+			"Hey," Gwylan says as you walk in. <<gwylanRescueApologySpeech>>
+		<</if>>
+	<</if>>
+
+	<<if _args[0] is "Robin">>
+		Robin blinks, but doesn't question it.
+	<</if>>
+<</widget>>
+
+<<widget "gwylanRescueApologySpeech">>
+	<<if _args[0] is "btw">>
+		"By the way, sorry for not saving you before, but I'm not messing with
+	<<else>>
+		"Sorry for not saving you before, but I'm not messing with
+	<</if>>
+	<<if $gwylan_aborted is 1 and $gwylan_eden_coop gte 1>>
+		Eden. <<nnpc_He "Eden">> still scares me."
+	<<elseif $gwylan_aborted is 1>>
+		the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest."
+	<<elseif $gwylan_aborted is 2>>
+		the alpha. I don't want the entire pack breaking my door down."
+	<</if>>
+<</widget>>
+
+<<widget "gwylanForestRescue">>
+	<<set _gwylanKnown to ($forest_shop_intro is 1 or $gwylan_rescue is 1)>>
+	
+	<<switch _args[0]>>
+		<<case "beast">> The <<beasttype>> growls, but is hit in the face by a flying ?gwylanItem. <<bHe>> yelps and looks around, alarmed. <<if $monster is 1>>"Human attack! Where human?!"<</if>>
+		<<case "river">> The <<beasttype>> hisses, but is hit in the face by a flying ?gwylanItem. <<bHe>> looks around, alarmed.
+		<<case "man">> The <<person1>><<person>> charges you, but is interrupted when a flying ?gwylanItem smacks <<him>> in the face. The <<person2>><<person>> looks over, only for a ?gwylanItem to fly into <<his>> face as well.
+	<</switch>>
+	<br><br>
+
+	"Hey!" <<if _gwylanKnown>>Gwylan<<else>>a <<nnpc_gendery "Gwylan">><</if>> shouts from beyond the treeline.
+	<<set $_theboy to (_gwylanKnown ? "Gwylan" : "the " + _text_output)>> <!-- This _text_output comes from the nnpc_gendery call one line above. Do not move this line without accounting for that. -->
+	<<switch _args[0]>>
+		<<case "beast">> "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> scurries away, <<bhis>> tail between <<bhis>> legs.
+		<<case "river">> "Shoo!" <<nnpc_He "Gwylan">> throws a ?gwylanItem, hitting the <<beasttype>> in the side. <<bHe>> dives back into the churning water.
+		<<case "man">> "Get away from <<phim>>. I have more." As if to demonstrate, <<nnpc_he "Gwylan">> throws a ?gwylanItem, hitting the <<person1>><<person>> in the face again. The pair glance at each other, then turn and run.
+	<</switch>>
+	<br><br>
+
+	<<set $pronoun to $NPCName[$NPCNameList.indexOf("Gwylan")].pronoun>>
+	<<switch _args[0]>>
+		<<case "beast">> "I swear they get more aggressive every day," $_theboy mutters.
+		<<case "river">> "The rivers keep getting more dangerous," $_theboy mutters.
+		<<case "man">> "I hope they weren't customers," $_theboy mutters. "Well, I wouldn't want their money anyway."
+	<</switch>>
+	<<He>> steps out from the treeline, and walks toward you. "You okay? Good thing I was in the area."
+	<<if _args[0] is "river">><<He>> grasps your arm and pulls you out of the water.<</if>>
+
+	<<if !_gwylanKnown>>
+		<br><br>
+
+		<<He>> looks about your age, with mousy hair and freckles. "I'm older than I look," <<he>> says, as if reading your mind. "I'm Gwylan. Nice to meet you."
+		<br><br>
+
+		"I have a shop right by the outskirts of the forest," <<he>> says. "You can't miss it. I sell-" <<he>> pauses. "My grand<<father>> sells-" another pause. "I sell knick-knacks there. Things you won't find in normal shops. Even I don't know what I have in stock!" <<He>> sounds proud.
+	<<elseif $gwylan_aborted gte 1>>
+		<<gwylanRescueApology>>
+	<</if>>
+	<br><br>
+
+	<<if $gwylan_eden_coop gte 1 and $gwylan_aborted is 0>>
+		<<He>> looks around for a moment, as if waiting for something. "Strange," <<he>> says to <<himself>>. "I thought the <<nnpc_title "Eden">> would be here. Must be busy. Ah well."
+		<br><br>
+	<</if>>
+
+	<<if $gwylan_rescue isnot 1>>
+		<<set $gwylan_rescue to 1>>
+		<<He>> starts to walk away, but stops and turns around. "By the way," <<he>> says. "I was able to save you because you're close enough to my shop. <span class="gold">If you go any further than the start of the lake, I won't be able to hear you.</span> Keep it in mind."
+		<br><br>
+	<</if>>
+	<<He>> gathers <<his>> items, then walks off in the direction of <<his>> shop.
+	<br><br>
+
+	<<clotheson>><<set $gwylan_aborted to 0>>
+	<<endcombat>>
+
+	<<if _args[1] is "slime">>
+		<<slimePunishmentForest>>
+		<br><br>
+	<</if>>
+
+	<<link [[Next|Forest]]>><<set $eventskip to 1>><</link>>
+<</widget>>
diff --git a/game/overworld-forest/loc-lake/ivory/widgets.twee b/game/overworld-forest/loc-lake/ivory/widgets.twee
index f633878920..e55c18edac 100644
--- a/game/overworld-forest/loc-lake/ivory/widgets.twee
+++ b/game/overworld-forest/loc-lake/ivory/widgets.twee
@@ -979,28 +979,16 @@
 <<widget "rescueWraith">>
 <<if $location is "forest">>
 	<<if $alarm is 1 and $forest lte 20 and $gwylan_aborted isnot 3>>
-		<<set $gwylan_aborted to 3>>
+	<<set $gwylan_aborted to 3>>
 		<<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>
-			You see a mousy <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> looks around, puzzled. <<nnpc_His "Gwylan">> gaze passes right over you, as if you weren't there, <span class="red">then turns and walks away.</span>
-			<br><br>
+			You see a mousy <<nnpc_gendery "Gwylan">> burst through the treeline, alarmed by your shout.
 		<<else>>
-			You see Gwylan burst through the treeline, alarmed by your shout. <<nnpc_He "Gwylan">> looks around, puzzled. <<nnpc_His "Gwylan">> gaze passes right over you, as if you weren't there, <span class="red">then turns and walks away.</span>
-		<br><br>
+			You see Gwylan burst through the treeline, alarmed by your shout.
 		<</if>>
+		<<nnpc_He "Gwylan">> looks around, puzzled. <<nnpc_His "Gwylan">> gaze passes right over you, as if you weren't there, <span class="red">then turns and walks away.</span>
+		<br><br>
 	<<elseif $alarm is 1 and $forest gte 21>>
-		<<if isLoveInterest("Eden")>>
-			<<if $gwylan_rescue is 1>>
-				<span class="red">You're too deep into the forest for Gwylan to hear you, and Eden must not be in the area.</span>
-			<<else>>
-				<span class="red">You're too far from the town for anyone to hear you, and Eden must not be in the area.</span>
-			<</if>>
-		<<else>>
-			<<if $gwylan_rescue is 1>>
-				<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-			<<else>>
-				<span class="red">You're too far from the town for anyone to hear you.</span>
-			<</if>>
-		<</if>>
+		<<forestRescueFail>>
 		<br><br>
 	<</if>>
 <</if>>
diff --git a/game/overworld-town/special-robin/walk.twee b/game/overworld-town/special-robin/walk.twee
index 29ca8e8ed4..82c40d7f78 100644
--- a/game/overworld-town/special-robin/walk.twee
+++ b/game/overworld-town/special-robin/walk.twee
@@ -1385,95 +1385,67 @@ You arrive at Wolf Street just in time to see the <<nnpc_gendery "Gwylan">> disa
 :: Robin Forest Shop 4
 
 <<set $outside to 0>><<set $location to "forest_shop">><<effects>>
-<<if !$robin_forest_visited>><<set $robin_forest_visited to 1>>
+<<if !$robin_forest_visited>>
+	<<set $robin_forest_visited to 1>>
+	You catch occasional glimpses of the <<nnpc_gendery "Gwylan">> through the trees, until at last you come to a strange building.
 	<<if $forest_shop_intro isnot 1>>
-		<<set $forest_shop_intro to 1>>
-		<<if $gwylan_rescue is 1>>
-			You catch occasional glimpses of the <<nnpc_gendery "Gwylan">> through the trees, until at last you come to a strange building. Gwylan's shop, you assume.
-			<br><br>
-
-			"It's okay," you say to a nervous Robin. "I know who works here. It's a shop." All apprehension leaves the orphan, and <<he>> enters.
-			<br><br>
-			<<endevent>><<npc Gwylan>><<person1>>
-			The interior is dark and crowded by tall shelves holding all manner of items. The quiet is broken by a scraping, then a thud. A <<person1>><<personsimple>> holding a stepladder appears at the end of the closest aisle. It's Gwylan.
-			<br><br>
-
-			"You brought a friend!" <<he>> says, rushing over and grasping Robin's hand in both <<his>> own. "I'm Gwylan. Welcome to my shop."
-			<<if $gwylan_aborted is 1>>
-				<<set $gwylan_aborted to 0>>
-				<<if $gwylan_eden_coop gte 1>>
-					<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." Robin blinks, but doesn't question it.
-
-				<<else>>
-					<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest." Robin blinks, but doesn't question it.
-				<</if>>
-
-			<<elseif $gwylan_aborted is 2>>
-				<<set $gwylan_aborted to 0>>
-				<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down." Robin blinks, but doesn't question it.
-			<</if>>
-
-		<<else>>
-			You catch occasional glimpses of the <<nnpc_gendery "Gwylan">> through the trees, until at last you come to a strange building. You hear shuffling inside. A sign on the door says "Open."
+		<<if $gwylan_rescue isnot 1>>
+			You hear shuffling inside. A sign on the door says "Open."
 			<br><br>
 
 			Robin hesitates again, but steels <<himself>> and enters.
+		<<else>>
+			Gwylan's shop, you assume.
 			<br><br>
 
-			<<endevent>><<npc Gwylan>><<person1>>
-			The interior is dark and crowded by tall shelves holding all manner of items. The quiet is broken by a scraping, then a thud. A <<person1>><<personsimple>> holding a stepladder appears at the end of the closest aisle.
-			<br><br>
-
+			"It's okay," you say to a nervous Robin. "I know who works here. It's a shop." All apprehension leaves the orphan, and <<he>> enters.
+		<</if>>
+		<br><br>
+		
+		<<npc "Gwylan" 2>><<person2>>
+		The interior is dark and crowded by tall shelves holding all manner of items. The quiet is broken by a scraping, then a thud. A <<personsimple>> holding a stepladder appears at the end of the closest aisle.
+		<<if $gwylan_rescue isnot 1>>
 			"Customers!" <<he>> says, dropping the ladder and walking over. <<He>> wipes <<his>> hands on <<his>> apron. "Welcome to my shop."
 			<br><br>
 
-			<<He>> looks about your age, with mousy hair and a hint of freckles. "I'm older than I look," <<he>> says, as if reading your mind. "I'm Gwylan," <<he>> reaches forward and shakes both your and Robin's hand. "Pleased to meet you. I sell-" <<he>> pauses. "My grand<<if $pronoun is "m">>father<<else>>mother<</if>> sells-" another pause. "I sell knick-knacks here. Things you won't find in normal shops. Even I don't know what I have in stock!" <<He>> sounds proud.
+			<<He>> looks about your age, with mousy hair and a hint of freckles. "I'm older than I look," <<he>> says, as if reading your mind. "I'm Gwylan," <<he>> reaches forward and shakes both your and Robin's hand. "Pleased to meet you. I sell-" <<he>> pauses. "My grand<<father>> sells-" another pause. "I sell knick-knacks here. Things you won't find in normal shops. Even I don't know what I have in stock!" <<He>> sounds proud.
+		<<else>>
+			It's Gwylan.
 		<</if>>
-
 	<<else>>
-		You catch occasional glimpses of the through the trees, until at last you come to a strange building. Gwylan's shop.
+		Gwylan's shop.
 		<br><br>
 
 		"It's okay," you say to a nervous Robin. "I've been here before. It's a shop." All apprehension leaves the orphan, and <<he>> enters.
 		<br><br>
 
-		<<endevent>><<npc Gwylan>><<person1>>
-		You follow Robin into the shop. Your eyes adjust to the gloom just as Gwylan appears at the end of an aisle. "You brought a friend!" <<he>> says, rushing over and grasping Robin's hand in both <<his>> own. "I'm Gwylan. Welcome to my shop."
+		<<npc "Gwylan" 2>><<person2>>
+		You follow Robin into the shop. Your eyes adjust to the gloom just as Gwylan appears at the end of an aisle.
+	<</if>>
 
-		<<if $gwylan_aborted is 1>>
-			<<set $gwylan_aborted to 0>>
-			<<if $gwylan_eden_coop gte 1>>
-				<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." Robin blinks, but doesn't question it.
-			<<else>>
-				<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest." Robin blinks, but doesn't question it.
-			<</if>>
+	<<if $forest_shop_intro is 1 or $gwylan_rescue is 1>>
+		<br><br>
 
-		<<elseif $gwylan_aborted is 2>>
+		"You brought a friend!" <<he>> says, rushing over and grasping Robin's hand in both <<his>> own. "I'm Gwylan. Welcome to my shop."
+		<<if $gwylan_aborted gte 1>>
+			<<gwylanRescueApologyShop "Robin">>
 			<<set $gwylan_aborted to 0>>
-			<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down." Robin blinks, but doesn't question it.
 		<</if>>
 	<</if>>
+	<<set $forest_shop_intro to 1>>
 	<br><br>
 	<<link [[Next|Robin Forest Shop 5]]>><</link>>
 
 <<else>>
-	<<endevent>><<npc Gwylan>><<person1>>Gwylan greets you as you enter. "I'm glad to see you again," <<he>> says, shaking both your and Robin's hand. "Let me know if you need anything."
-
-	<<if $gwylan_aborted is 1>>
-		<<set $gwylan_aborted to 0>>
-		<<if $gwylan_eden_coop gte 1>>
-			<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with Eden. <<nnpc_He "Eden">> still scares me." Robin blinks, but doesn't question it.
-		<<else>>
-			<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with the <<nnpc_title "Eden">>. <<nnpc_Hes "Eden">> the scariest thing in the forest." Robin blinks, but doesn't question it.
-		<</if>>
+	<<npc "Gwylan" 2>><<person2>>Gwylan greets you as you enter. "I'm glad to see you again," <<he>> says, shaking both your and Robin's hand. "Let me know if you need anything."
 
-	<<elseif $gwylan_aborted is 2>>
+	<<if $gwylan_aborted gte 1>>
+		<<gwylanRescueApologyShop "Robin">>
 		<<set $gwylan_aborted to 0>>
-		<<He>> turns to you with an apologetic smile. "By the way, sorry for not saving you before, but I'm not messing with the alpha. I don't want the entire pack breaking my door down." Robin blinks, but doesn't question it.
 	<</if>>
 	<br><br>
 
-	<<endevent>><<npc Robin>><<person1>>Robin beelines towards the dark screen. You catch up and find <<him>> admiring the outfits.
+	<<person1>>Robin beelines towards the dark screen. You catch up and find <<him>> admiring the outfits.
 	<br><br>
 
 	<<link [[Ask Robin to try on the girl's witch costume|Robin Forest Witch]]>><</link>>
-- 
GitLab


From 711b43796f02f077209c81cd165ad7347f0ae7a2 Mon Sep 17 00:00:00 2001
From: hwp <you@example.com>
Date: Tue, 20 Sep 2022 16:46:47 -0400
Subject: [PATCH 41/50] adding gwylan rescue widgets to more places

---
 game/overworld-forest/loc-cabin/main.twee     | 30 +++----------------
 game/overworld-forest/loc-forest/widgets.twee |  3 +-
 2 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/game/overworld-forest/loc-cabin/main.twee b/game/overworld-forest/loc-cabin/main.twee
index bd38591188..06104b41e5 100644
--- a/game/overworld-forest/loc-cabin/main.twee
+++ b/game/overworld-forest/loc-cabin/main.twee
@@ -2271,19 +2271,8 @@ You search the clearing for wild flowers, and find a number of poppies growing a
 <<effects>>
 <<effectsman>>
 
-<<if $alarm is 1 and $rescue is 0 and $forest lte 20 and $gwylan_aborted isnot 1>>
-	<<set $alarm to 0>>
-	<<set $gwylan_aborted to 1>>
-	You see <<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>a <<nnpc_gendery "Gwylan">><<else>>Gwylan<</if>> burst through the treeline, alarmed by your shout.
-	<<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-	<br><br>
-<<elseif $alarm is 1 and $rescue is 0 and $forest gte 21>>
-	<<if $gwylan_rescue is 1>>
-		<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-	<<else>>
-		<span class="red">You're too far from town for anyone to hear you.</span>
-	<</if>>
-	<br><br>
+<<if $alarm is 1>>
+	<<gwylanRescueFail "hunter">>
 <</if>>
 
 <<man>>
@@ -2342,19 +2331,8 @@ You search the clearing for wild flowers, and find a number of poppies growing a
 <<effects>>
 <<effectsman>>
 
-<<if $alarm is 1 and $rescue is 0 and $forest lte 20 and $gwylan_aborted isnot 1>>
-	<<set $alarm to 0>>
-	<<set $gwylan_aborted to 1>>
-	You see <<if $forest_shop_intro isnot 1 and $gwylan_rescue isnot 1>>a <<nnpc_gendery "Gwylan">><<else>>Gwylan<</if>> burst through the treeline, alarmed by your shout.
-	<<nnpc_He "Gwylan">> takes one look at the assailant, <span class="red">then turns and runs away.</span>
-	<br><br>
-<<elseif $alarm is 1 and $rescue is 0 and $forest gte 21>>
-	<<if $gwylan_rescue is 1>>
-		<span class="red">You're too deep into the forest for Gwylan to hear you.</span>
-	<<else>>
-		<span class="red">You're too far from the town for anyone to hear you.</span>
-	<</if>>
-	<br><br>
+<<if $alarm is 1>>
+	<<gwylanRescueFail "hunter">>
 <</if>>
 
 <<man>>
diff --git a/game/overworld-forest/loc-forest/widgets.twee b/game/overworld-forest/loc-forest/widgets.twee
index b01237e069..be510aa62b 100644
--- a/game/overworld-forest/loc-forest/widgets.twee
+++ b/game/overworld-forest/loc-forest/widgets.twee
@@ -1231,7 +1231,7 @@ or $lowerwetstage gte 3 and $underlowerwetstage gte 3>>
 	<<if $gwylan_rescue is 1>>
 		<span class="red">You're too deep into the forest for Gwylan to hear you<<if _args[0] isnot "hunter" and isLoveInterest("Eden")>>, and Eden must not be in the area<</if>>.</span>
 	<<else>>
-		<span class="red">You're too far from the town for anyone to hear you<<if _args[0] isnot "hunter" and isLoveInterest("Eden")>>, and Eden must not be in the area<</if>>.</span>
+		<span class="red">You're too far from town for anyone to hear you<<if _args[0] isnot "hunter" and isLoveInterest("Eden")>>, and Eden must not be in the area<</if>>.</span>
 	<</if>>
 <</widget>>
 
@@ -1241,6 +1241,7 @@ or $lowerwetstage gte 3 and $underlowerwetstage gte 3>>
 	
 	<<if $forest lte 20 and $gwylan_aborted isnot $_gwylan_abort_value>>
 		<<set $gwylan_aborted to $_gwylan_abort_value>>
+		<<set $rescue to 0>>
 		<<set $_assailant to (_args[0] is "wolf" ? "assailant" : "wolf")>> <!-- If you want to use this widget for other animals, change this -->
 		You see <<if $forest_shop_intro is 1 or $gwylan_rescue is 1>>Gwylan<<else>>a mousy <<nnpc_gendery "Gwylan">><</if>> burst through the treeline, alarmed by your shout.
 		<<nnpc_He "Gwylan">> takes one look at the $_assailant, <span class="red">then turns and runs away.</span>
-- 
GitLab


From 0e5a7d5289ca89a3df52777086f7414bfe710f4d Mon Sep 17 00:00:00 2001
From: hwp <you@example.com>
Date: Tue, 20 Sep 2022 21:16:35 -0400
Subject: [PATCH 42/50] Robin hot chocolate refactor

---
 game/01-config/sugarcubeConfig.js       |   5 +
 game/overworld-town/loc-park/robin.twee | 571 ++++++++----------------
 2 files changed, 193 insertions(+), 383 deletions(-)

diff --git a/game/01-config/sugarcubeConfig.js b/game/01-config/sugarcubeConfig.js
index 29560c8fff..d6d73a2528 100644
--- a/game/01-config/sugarcubeConfig.js
+++ b/game/01-config/sugarcubeConfig.js
@@ -236,6 +236,11 @@ Config.navigation.override = function (dest) {
 		case "Kylar Abduction Hawk":
 			return "Kylar Abduction Event Response";
 
+		case "Robin's Chocolate Help":
+			return "Robin Chocolate Help";
+		case "Robin Chocolate Cover 2":
+				return "Robin Chocolate Cover";
+
 		default:
 			return false;
 	}
diff --git a/game/overworld-town/loc-park/robin.twee b/game/overworld-town/loc-park/robin.twee
index a13a54deda..4919c6e095 100644
--- a/game/overworld-town/loc-park/robin.twee
+++ b/game/overworld-town/loc-park/robin.twee
@@ -1,3 +1,13 @@
+:: Robin Chocolate Widgets [widget]
+
+<<widget "robinChocolateOfferHelp">>
+	<!-- Note: Don't try to move the <<endevent>> outside these links, that would make this widget less portable. -->
+	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<endevent>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
+	<br>
+	<<link [[Leave|Park]]>><<endevent>><</link>>
+	<br>
+<</widget>>
+
 :: Robin Chocolate
 <<set $outside to 0>><<set $location to "park">><<effects>>
 <<npc Robin>><<person1>>
@@ -5,20 +15,12 @@
 	<<set $robinchocolateintro to 1>>
 
 	Robin waves when <<he>> sees you. <<He>> stirs a steaming pot with <<his>> other hand. "Hey," <<he>> says. "People don't buy much lemonade when it's so cold. I'm selling hot chocolate instead. Here." <<He>> mixes warm milk from the pot with cocoa powder and sugar, then hands you the mug. It's very sweet.<<lstress>><<stress -6>>
-	<br><br>
-
 <<else>>
 	You see Robin stood behind <<his>> hot chocolate stand, wrapped up warm against the cold. <<He>> waves when <<he>> sees you.
-	<br><br>
-
 <</if>>
+<br><br>
 
-
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Help
 <<npc Robin>><<person1>>
@@ -37,6 +39,13 @@
 	<br><br>
 	You walk with Robin back to the orphanage.
 	<br><br>
+
+	<<if $arousal gte $arousalmax>>
+		You're almost back when your body finally betrays you.
+		<<orgasm>>
+		Robin politely looks away, but can't help but be affected.<<npcincr Robin lust 1>>
+		<br>
+	<</if>>
 	<<endevent>>
 	<<link [[Next|Orphanage]]>><</link>>
 	<br>
@@ -53,43 +62,31 @@
 		<<npcincr Robin love 1>><<glove>><<ltrauma>><<lstress>><<trauma -3>><<stress -6>>
 		<br><br>
 
-		<<if $NPCName[$NPCNameList.indexOf("Robin")].dom gte 60>>
-			<<generate2>><<person2>>
-			<<if _robin.trauma gte 40>>
-				"Hi," Robin says, looking down. "T-two pounds for chocolate if that's okay."
-			<<else>>
-				A <<person>> approaches the stand. "Welcome," Robin says. "Two pounds for a warm mug of chocolate."
-			<</if>>
-			<br><br>
-			"Sure, sweetie," the <<person>> says before turning to you. They sprout a lecherous, crooked smile. "I remember you. From the farm. Why don't you come with me? I'll bring you home." They hold their hand out.
-			<br><br>
-			You feel conflicted. Memories of your abuse conflict with pleasant thoughts of open fields. You hesitate, then bring your hand to theirs.
+		<<generate2>><<person2>>
+		A <<person>> approaches the stand. 
+		<<if _robin.trauma gte 40>>
+			"Hi," Robin says, looking down. "T-two pounds for chocolate if that's okay."
+		<<else>>
+			"Welcome," Robin says. "Two pounds for a warm mug of chocolate."
+		<</if>>
+		<br><br>
+		"Sure, sweetie," the <<person>> says before turning to you. They sprout a lecherous, crooked smile. "I remember you. From the farm. Why don't you come with me? I'll bring you home." They hold their hand out.
+		<br><br>
+		You feel conflicted. Memories of your abuse conflict with pleasant thoughts of open fields. You hesitate, then bring your hand to theirs.
+		<<if _robin.dom gte 60>>
 			<br><br>
 			<<link [[Next|Robin Chocolate Cow]]>><</link>>
 			<br>
 
 		<<else>>
-			<<generate2>><<person2>>
-			<<if _robin.trauma gte 40>>
-				"Hi," Robin says, looking down. "T-two pounds for chocolate if that's okay."
-			<<else>>
-				A <<person>> approaches the stand. "Welcome," Robin says. "Two pounds for a warm mug of chocolate."
-			<</if>>
-			<br><br>
-			"Sure, sweetie," the <<person>> says before turning to you. They sprout a lecherous, crooked smile. "I remember you. From the farm. Why don't you come with me? I'll bring you home." They hold their hand out.
-			<br><br>
-			You feel conflicted. Memories of your abuse conflict with pleasant thoughts of open fields. You hesitate, then bring your hand to theirs. Robin interrupts. "E-Excuse me, <<sir>>," Robin interrupts. "Your hot chocolate."
+			Robin interrupts. "E-Excuse me, <<sir>>," Robin interrupts. "Your hot chocolate."
 			<br><br>
 			The <<person>> looks surprised, but their smile doesn't fade. "Thanks, sweetheart," <<he>> says, taking the proffered mug. "Keep a close eye on your friend." <<He>> walks away.
 			<br><br>
 			The other customers are less creepy, but Robin seems shaken.
 			<br><br>
 
-			<<endevent>>
-			<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-			<br>
-			<<link [[Leave|Park]]>><</link>>
-			<br>
+			<<robinChocolateOfferHelp>>
 		<</if>>
 	<<elseif $rng gte 61>>
 		"I'd like to give out free samples. Could you take this tray around the park, and offer them to anyone who looks cold? I hope it's not too heavy."
@@ -109,7 +106,7 @@
 			<<elseif $worn.lower.set isnot $worn.upper.set>>
 				<span class="purple">and grasps the hem of your $worn.lower.name.</span>
 			<<else>>
-				<span class="purple">and grasps your <<breasts>></span>
+				<span class="purple">and grasps your <<breasts>>.</span>
 			<</if>>
 			<<gstress>><<stress 6>>
 			<br><br>
@@ -123,18 +120,14 @@
 			<br>
 		<<else>>
 			<<famebusiness 1>>
-			<<rng>>
-			<<if $rng gte 81>>
-				Passing a bus stop is enough to empty half the tray.
-			<<elseif $rng gte 61>>
-				A red-nosed <<if $pronoun is "m">>father<<else>>mother<</if>> is particularly grateful for two mugs, which <<he>> uses to coax <<his>> children down from a tree.
-			<<elseif $rng gte 41>>
-				A homeless <<personsimple>> takes one, and warms <<his>> hands against the mug.
-			<<elseif $rng gte 21>>
-				A <<person>> grabs one as <<he>> jogs past, and drinks it without slowing.
-			<<else>>
-				A lot of people weren't prepared for the cold.
-			<</if>>
+			<<rng 5>>
+			<<switch $rng>>
+				<<case 1>> Passing a bus stop is enough to empty half the tray.
+				<<case 2>> A red-nosed <<father>> is particularly grateful for two mugs, which <<he>> uses to coax <<his>> children down from a tree.
+				<<case 3>> A homeless <<personsimple>> takes one, and warms <<his>> hands against the mug.
+				<<case 4>> A <<person>> grabs one as <<he>> jogs past, and drinks it without slowing.
+				<<case 5>> A lot of people weren't prepared for the cold.
+			<</switch>>
 			<br><br>
 			<<person1>>
 			Robin smiles when you return to <<him>>.
@@ -144,11 +137,7 @@
 				"Business has improved a lot," <<he>> says. "Thank you."
 			<</if>>
 			<br><br>
-			<<endevent>>
-			<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-			<br>
-			<<link [[Leave|Park]]>><</link>>
-			<br>
+			<<robinChocolateOfferHelp>>
 		<</if>>
 	<<elseif $rng gte 21>>
 		<<if _robin.trauma gte 40>>
@@ -188,11 +177,10 @@
 		<br><br>
 		<<set $danger to random(1, 10000)>><<set $dangerevent to 0>>
 		<<if $danger gte (9900 - $allure)>>
-			<<generatey2>><<generatey3>><<generatey4>><<generatey5>>
 			<<set $robinparksnow to 1>>
 			A snowball hurtles through the air.
 			<<if _robin.trauma gte 40>>
-				Robin sees the snowball but freezes, only managing to flinch before <<he>>'s hit with a faceful of snow. You duck and pull <<him>> down.
+				Robin sees the snowball but freezes, only managing to flinch before <<hes>> hit with a faceful of snow. You duck and pull <<him>> down.
 				<br><br>
 				Robin wipes the snow from <<his>> face and shivers. "Let's just w-wait," <<he>> says. "They'll leave us alone eventually."
 			<<else>>
@@ -214,11 +202,7 @@
 		<<else>>
 			"Thank you for spending time with me," <<he>> says after a while.
 			<br><br>
-			<<endevent>>
-			<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-			<br>
-			<<link [[Leave|Park]]>><</link>>
-			<br>
+			<<robinChocolateOfferHelp>>
 		<</if>>
 	<</if>>
 <</if>>
@@ -236,11 +220,7 @@ You help Robin carry <<his>> equipment to the park. "Thank you for the help," <<
 <</if>>
 <<He>> lights <<his>> portable stove.
 <br><br>
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Set Tutorial
 <<set $outside to 1>><<set $location to "town">><<effects>>
@@ -256,11 +236,7 @@ Robin spots you exiting the alley. "A-Are you okay?" <<he>> asks, with a worried
 <br><br>
 You nod, pick up <<his>> dropped equipment and continue to walk to the park with Robin. The rest of the trip is uneventful.
 <br><br>
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Cow
 <<effects>>
@@ -269,101 +245,70 @@ You nod, pick up <<his>> dropped equipment and continue to walk to the park with
 Before your hand meets the <<persons>>, someone pulls your arm back. Robin pushes you behind <<person1>><<him>>.
 <<if _robin.trauma gte 40>>
 	"Y-you're not taking <<phim>>!" <<he>> says, handing the <<person2>><<person>> <<his>> cup with a shaky hand.
-	<br><br>
-
-	"Careful, <<person1>><<nnpc_gendery "Robin">>," the <<person2>><<person>> says. "Your friend is worth a lot. I'd hate to see you wind up like them."
-	<br><br>
-
-	Robin flinches, but holds <<person1>><<his>> ground. "Leave before I call the police."
-	<br><br>
-
-	The <<person>> laughs and pours the chocolate into the snow. "Keep the money. Better keep an eye on your friend." <<He>> leaves.
-	<br><br><<person1>>
-
-	You turn to Robin, tilt your head, and give a worried moo.
-	<br><br>
-
-	"Everything's okay," Robin says. "Here." <<He>> mixes another mug of hot chocolate, and hands it to you.
-	<br><br>
-
-	"This should make you feel better." <<Hes>> right.<<gdom>><<npcincr Robin dom 1>><<lstress>><<stress -6>>
 <<else>>
 	"I need to ask you to leave," <<He>> says, handing the <<person2>><<person>> <<his>> cup.
-	<br><br>
+<</if>>
+<br><br>
 
-	"Careful, <<person1>><<nnpc_gendery "Robin">>," the <<person2>><<person>> says. "Your friend is worth a lot. I'd hate to see you wind up like them."
-	<br><br>
+"Careful, <<nnpc_gendery "Robin">>," the <<person2>><<person>> says. "Your friend is worth a lot. I'd hate to see you wind up like <<phim>>."
+<br><br>
 
+<<if _robin.trauma gte 40>>
+	Robin flinches, but holds <<nnpc_his "Robin">> ground. "Leave before I call the police."
+<<else>>
 	Robin frowns. "I'm asking you to leave one last time before I call the police."
-	<br><br>
-
-	The <<person>> laughs and pours the chocolate into the snow. "Keep the money. Better keep an eye on your friend." <<He>> leaves.
-	<br><br><<person1>>
+<</if>>
+<br><br>
 
-	You turn to Robin, tilt your head, and give a worried moo.
-	<br><br>
+The <<person>> laughs and pours the chocolate into the snow. "Keep the money. Better keep an eye on your friend." <<He>> leaves.
+<br><br>
 
-	"It's okay," Robin says. "Here." <<He>> mixes another mug of hot chocolate, and hands it to you.
-	<br><br>
+You turn to Robin, tilt your head, and give a worried moo.
+<br><br>
 
-	"This should make you feel better." <<Hes>> right.<<gdom>><<npcincr Robin dom 1>><<lstress>><<stress -6>>
+<<if _robin.trauma gte 40>>
+	"Everything's okay," Robin says. "Here."
+<<else>>
+	"It's okay," Robin says. "Here."
 <</if>>
+<<person1>><<He>> mixes another mug of hot chocolate, and hands it to you.
+<br><br>
+
+"This should make you feel better." <<Hes>> right.<<gdom>><<npcincr Robin dom 1>><<lstress>><<stress -6>>
 <br><br>
 
 The other customers are less creepy.
 <br><br>
 
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Slap
 <<effects>>
 <<set _robin to statusCheck("Robin")>>
 
+You throw the tray in the air, spin, and smack the <<person>> across the face. <<He>> skids on the icy ground, and falls on <<his>> ass.<<ltrauma>><<trauma -6>>
+<br><br>
 <<if $danceSuccess>>
-	You throw the tray in the air, spin, and smack the <<person>> across the face. <<He>> skids on the icy ground, and falls on <<his>> ass.<<ltrauma>><<trauma -6>>
-	<br><br>
 	You whirl around, <span class="green">and catch the tray,</span> the mugs unspilled.<<lstress>><<stress -6>>
-	<br><br>
-	<<person1>>
-	Robin smiles when you return to <<him>>.
-	<<if _robin.trauma gte 40>>
-		<<He>> hugs you the moment you place the tray down. "Thank you."
-	<<else>>
-		"Business has improved a lot," <<he>> says. "Thank you."
-	<</if>>
-	<br><br>
-	<<endevent>>
-	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-	<br>
-	<<link [[Leave|Park]]>><</link>>
-	<br>
 <<else>>
-	You throw the tray in the air, spin, and smack the <<person>> across the face. <<He>> skids on the icy ground, and falls on <<his>> ass.<<ltrauma>><<trauma -6>>
-	<br><br>
 	You try to catch the tray, <span class="red">but you're too slow.</span> It clatters to the ground, spilling hot chocolate over the snow.<<gstress>><<stress 6>>
-	<br><br>
-	<<person1>>
-	Robin smiles when you return to <<him>>.
-	<<if _robin.trauma gte 40>>
-		<<He>> hugs you the moment you place the tray down. "Thank you."
-	<<else>>
-		"Business has improved a lot," <<he>> says. "Thank you."
-	<</if>>
-	<br><br>
+<</if>>
+<br><br>
+
+<<person1>>
+Robin smiles when you return to <<him>>.
+<<if _robin.trauma gte 40>>
+	<<He>> hugs you the moment you place the tray down. "Thank you."
+<<else>>
+	"Business has improved a lot," <<he>> says. "Thank you."
+<</if>>
+<br><br>
 
+<<if !$danceSuccess>>
 	<<link [[Confess about spilling the chocolate|Robin Chocolate Confess]]>><<npcincr Robin dom 1>><</link>><<gdom>>
 	<br>
-	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<endevent>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-	<br>
-	<<link [[Leave|Park]]>><<endevent>><</link>>
-	<br>
-
 <</if>>
-
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Confess
 <<effects>>
@@ -386,77 +331,52 @@ The other customers are less creepy.
 <</if>>
 <br><br>
 
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<endevent>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><<endevent>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Endure
 <<effects>>
 <<set _robin to statusCheck("Robin")>>
 
-<<if setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1>>
+<<set _wearingSkirt to (setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt is 1)>>
+<<set _notWearingSet to ($worn.lower.set isnot $worn.upper.set)>>
+
+<<if _wearingSkirt or _notWearingSet>>
+	The <<person>> <<if _wearingSkirt>>lifts<<else>>tugs down<</if>> your $worn.lower.name,
+	<span class="lewd">exposing your <<undies>> in the middle of the park.</span>
+	<br><br>
+
 	<<if $worn.under_lower.type.includes("naked")>>
 		<<if $worn.genitals.type.includes("chastity")>>
-			The <<person>> lifts your $worn.lower.name, <span class="lewd">exposing your $worn.genitals.name in the middle of the park.</span>
-			<br><br>
-
-			"Someone's locked you up," <<he>> laughs. "A shame." <<He>> holds your skirt against your waist. Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
-			<br><br>
-			<<fameexhibitionism 10>>
+			"Someone's locked you up," <<he>> laughs. "A shame."
 		<<else>>
-			The <<person>> lifts your $worn.lower.name, <span class="lewd">exposing your <<genitals 1>> in the middle of the park.</span>
-			<br><br>
-
-			"No underwear?" <<he>> laughs. "I had you pegged as a <<slut>>." <<He>> holds your skirt against your waist. Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
-			<br><br>
-			<<fameexhibitionism 10>>
+			"No underwear?" <<he>> laughs. "I had you pegged as a <<slut>>."
 		<</if>>
-
+		<<set _exhib to 10>>
 	<<else>>
-		The <<person>> lifts your $worn.lower.name, <span class="lewd">exposing your $worn.under_lower.name in the middle of the park.</span>
-		<br><br>
-
-		"Nice underwear," <<he>> says. "I thought a <<slut>> like you wouldn't be wearing any." <<He>> holds your skirt against your waist. Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
-		<br><br>
-		<<fameexhibitionism 5>>
+		"Nice underwear," <<he>> says. "I thought a <<slut>> like you wouldn't be wearing any."
+		<<set _exhib to 5>>
 	<</if>>
-	At last, <<he>> lets your skirt fall. <<He>> takes a mug of hot chocolate, thanks you, and walks away.
+	<<if _wearingSkirt>>
+		<<He>> holds your skirt against your waist.
+	<<else>>
+		<<He>> steps back to admire your <<bottom>>.
+	<</if>>
+	Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
 	<br><br>
-<<elseif $worn.lower.set isnot $worn.upper.set>>
-	<<if $worn.under_lower.type.includes("naked")>>
-		<<if $worn.genitals.type.includes("chastity")>>
-			The <<person>> tugs down your $worn.lower.name, <span class="lewd">exposing your $worn.genitals.name in the middle of the park.</span>
-			<br><br>
-
-			"Someone's locked you up," <<he>> laughs. "A shame." <<He>> steps back to admire your <<bottom>>. Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
-			<br><br>
-			<<fameexhibitionism 10>>
-		<<else>>
-			The <<person>> tugs down your $worn.lower.name, <span class="lewd">exposing your <<genitals 1>> in the middle of the park.</span>
-			<br><br>
 
-			"No underwear?" <<he>> laughs. "I had you pegged as a <<slut>>." <<He>> steps back to admire your <<bottom>>. Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
-			<br><br>
-			<<fameexhibitionism 10>>
-		<</if>>
+	<<fameexhibitionism _exhib>>
+	<<if _wearingSkirt>>
+		At last, <<he>> lets your skirt fall.
 	<<else>>
-		The <<person>> tugs down your $worn.lower.name, <span class="lewd">exposing your $worn.under_lower.name in the middle of the park.</span>
-		<br><br>
-
-		"Nice underwear," <<he>> says. "I thought a <<slut>> like you wouldn't be wearing any." <<He>> steps back to admire your <<bottom>>. Your hands remain glued to the tray. People point in your direction. A breeze makes you shiver.
-		<br><br>
-		<<fameexhibitionism 5>>
+		At last, <<he>> pulls your $worn.lower.name back up.
 	<</if>>
-	At last, <<he>> pulls your $worn.lower.name back up. <<He>> takes a mug of hot chocolate, thanks you, and walks away.
-	<br><br>
 <<else>>
 	<<if $player.breastsize gte 3>>
-		The <<person2>> squeezes your <<breasts>>,
+		The <<person>> squeezes your <<breasts>>,
 	<<else>>
-		The <<person2>> runs <<his>> fingers over your <<breasts>>,
+		The <<person>> runs <<his>> fingers over your <<breasts>>,
 	<</if>>
-	<<if $worn.upper.type.includes("naked") and $worn.lower.type.includes("naked")>>
+	<<if $worn.upper.type.includes("naked") and $worn.under_upper.type.includes("naked")>>
 		and pinches your exposed nipples.
 	<<else>>
 		and pinches your nipples through the fabric.
@@ -464,9 +384,11 @@ The other customers are less creepy.
 	"I knew you were the sort of <<slut>> to get off on something like this," <<he>> says. Your hands remain glued to the tray. You shiver.
 	<br><br>
 
-	At last, the <<person>> pulls away. <<He>> takes a mug of hot chocolate, thanks you, and walks away.
-	<br><br>
+	At last, the <<person>> pulls away.
 <</if>>
+<<He>> takes a mug of hot chocolate, thanks you, and walks away.
+<br><br>
+
 <<set $robinmoney += 5>>
 <<person1>>
 Robin smiles when you return to <<him>>.
@@ -477,10 +399,7 @@ Robin smiles when you return to <<him>>.
 <</if>>
 <br><br>
 
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<endevent>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><<endevent>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 
 :: Robin Milk Masturbation
@@ -492,7 +411,7 @@ Robin smiles when you return to <<him>>.
 	<<masturbationstart>>
 	<<set $timer to 40>>
 	<<set $masturbation_bowl to 1>>
-	<<set $mouth to "disabled">>
+	<<set $mouth to "disabled">>	
 	You enter a cubicle, where you're unlikely to be disturbed.
 	<<promiscuity3>>
 <</if>>
@@ -501,12 +420,7 @@ Robin smiles when you return to <<him>>.
 <<masturbationbowl>>
 <br><br>
 
-<<if $timer lte 1>>
-	<<link [[Continue|Robin Milk Masturbation Finish]]>><</link>><<nexttext>>
-	<br>
-	<<link [[Stop|Robin Milk Masturbation Finish]]>><<set $finish to 1>><</link>>
-	<br>
-<<elseif $masturbation_fluid gte 500>>
+<<if $timer lte 1 or $masturbation_fluid gte 500>>
 	<<link [[Continue|Robin Milk Masturbation Finish]]>><</link>><<nexttext>>
 	<br>
 	<<link [[Stop|Robin Milk Masturbation Finish]]>><<set $finish to 1>><</link>>
@@ -547,10 +461,9 @@ Robin smiles when you return to <<him>>.
 
 <<else>>
 
-	<<if $finish is 1>>
-		You stop masturbating.
-	<<else>>
-		You stop masturbating. You've been trying a while, and Robin is waiting.
+	You stop masturbating.
+	<<if $finish isnot 1>>
+		You've been trying a while, and Robin is waiting.
 	<</if>>
 
 	<<if $masturbation_fluid gte 400>>
@@ -570,6 +483,9 @@ Robin smiles when you return to <<him>>.
 	<</if>>
 	<br><br>
 
+	<<set _moneySaved to Math.round($masturbation_fluid / 100)>>
+	<<set $robinmoney += _moneySaved>>
+
 	You walk to Harvest street, to a rustic shop advertising fresh farm produce. They sell milk by the millilitre, and the proprietor is willing to top up your bottle.
 	<br><br>
 
@@ -581,12 +497,7 @@ Robin smiles when you return to <<him>>.
 	<br><br>
 <</if>>
 
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
-
+<<robinChocolateOfferHelp>>
 
 
 :: Robin Milk Seduction
@@ -616,55 +527,34 @@ You arrive at Harvest Street, and enter a rustic shop. The proprietor, a <<perso
 	<<if $pronoun is "m">>
 		You slip behind the counter, and push your <<bottom>> against <<his>> crotch, just as another customer enters.
 		<br><br>
-		<<if $NPCList[0].penis isnot "none">>
-			The customer, a <<person2>><<person>>, frowns a little when <<he>> sees how close you and the <<person1>><<person>> are standing. The proprietor manages to serve the customer, but stammers as you grind against <<his>> <<print $NPCList[0].penisdesc>>.
-		<<else>>
-			The customer, a <<person2>><<person>>, frowns a little when <<he>> sees how close you and the <<person1>><<person>> are standing. The proprietor manages to serve the customer, but stammers as you grind against <<his>> pussy.
-		<</if>>
+		The customer, a <<person2>><<person>>, frowns a little when <<he>> sees how close you and the <<person1>><<person>> are standing.
+		The proprietor manages to serve the customer, but stammers as you grind against <<his>> <<if $NPCList[0].penis isnot "none">>$NPCList[0].penisdesc<<else>>pussy<</if>>.
 		<br><br>
 		You lift the full bottle, and leave the <<person1>><<person>> panting.
 		<br><br>
 
 	<<else>>
-		You slip behind the counter, and push your <<genitals>> against <<his>> ass, just as another customer enters.
-		<<if $NPCList[0].penis isnot "none">>
-			You reach around <<his>> waist and grope <<his>> <<print $NPCList[0].penisdesc>>.
-			<br><br>
-			The customer, a <<person2>><<person>>, frowns a little when <<he>> sees how close you and the <<person1>><<person>> are standing. The proprietor manages to serve the customer, but stammers as you tease <<him>>.
-		<<else>>
-			You reach around <<his>> waist and grope <<his>> pussy.
-			<br><br>
-			The customer, a <<person2>><<person>>, frowns a little when <<he>> sees how close you and the <<person1>><<person>> are standing. The proprietor manages to serve the customer, but stammers as you tease <<him>>.
-		<</if>>
+		You slip behind the counter, and push your <<if $player.penisExist>><<penis>><<else>><<pussy>><</if>> against <<his>> ass, just as another customer enters.
+		You reach around <<his>> waist and grope <<his>> <<if $NPCList[0].penis isnot "none">>$NPCList[0].penisdesc<<else>>pussy<</if>>.
+		<br><br>
+		The customer, a <<person2>><<person>>, frowns a little when <<he>> sees how close you and the <<person1>><<person>> are standing.
+		The proprietor manages to serve the customer, but stammers as you tease <<him>>.
 		<br><br>
 		You leave the <<person1>><<person>> panting as you walk from the shop, a full bottle of milk in hand.
 		<br><br>
 	<</if>>
 
-	<<endevent>><<npc Robin>><<person1>>
+	<<npc Robin 3>><<person3>>
 	You return to Robin. <<He>> smiles when <<he>> sees you, and takes the milk. <<He>> pours it into a pot while you quietly leave <<his>> £5 on the counter.<<glove>><<npcincr Robin love 1>>
-	<br><br>
-
-	<<endevent>>
-	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-	<br>
-	<<link [[Leave|Park]]>><</link>>
-	<br>
 <<else>>
 
 	<span class="red">"You're not my type,"</span> the <<person>> says without looking away from the milk.
 	<br><br>
-	<<endevent>><<npc Robin>><<person1>>
+	<<npc Robin 3>><<person3>>
 	You return to Robin. <<He>> smiles when <<he>> sees you. <<He>> takes the milk and pours it into a pot.
-	<br><br>
-	<<endevent>>
-	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-	<br>
-	<<link [[Leave|Park]]>><</link>>
-	<br>
-
-
 <</if>>
+<br><br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Milk Steal
 <<effects>>
@@ -672,27 +562,17 @@ You arrive at Harvest Street, and enter a rustic shop. The proprietor, a <<perso
 Milk from the surrounding farms is processed in a factory on the corner of Harvest Street. No one will notice a few missing litres. You haul yourself over a brick wall, and enter the plant through a metal-framed door.
 <br><br>
 
+You enter a large room, full of tall metal tanks. You hear a low hum from deeper within.
 <<skulduggerycheck>>
 <<if $skulduggerysuccess is 1>>
-
-	You enter a large room, full of tall metal tanks. You hear a low hum from deeper within. There's no one around, so you open a tap, and fill your bottle with milk. <span class="green">Nobody notices you.</span> This should be fresh enough for Robin.
+	There's no one around, so you open a tap, and fill your bottle with milk. <span class="green">Nobody notices you.</span> This should be fresh enough for Robin.
 	<br><br>
 
 	<<skulduggeryuse>>
 
 	<<endevent>><<npc Robin>><<person1>>
 	You return to Robin. <<He>> smiles when <<he>> sees you, and takes the milk. <<He>> pours it into a pot while you quietly leave <<his>> £5 on the counter.<<glove>><<npcincr Robin love 1>>
-	<br><br>
-
-	<<endevent>>
-	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-	<br>
-	<<link [[Leave|Park]]>><</link>>
-	<br>
-
 <<else>>
-
-	You enter a large room, full of tall metal tanks. You hear a low hum from deeper within.
 	<br><br>
 	<span class="red">"Oi," shouts a voice from above.</span> "Where do you think you're going? Security!" You turn and run the way you came, hauling yourself over the wall before anyone arrives.
 	<br><br>
@@ -703,15 +583,10 @@ Milk from the surrounding farms is processed in a factory on the corner of Harve
 
 	<<endevent>><<npc Robin>><<person1>>
 	You return to Robin. <<He>> smiles when <<he>> sees you, and pours the milk into a pot.
-	<br><br>
-
-	<<endevent>>
-	<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-	<br>
-	<<link [[Leave|Park]]>><</link>>
-	<br>
-
 <</if>>
+<br><br>
+
+<<robinChocolateOfferHelp>>
 
 :: Robin Milk Buy
 <<effects>>
@@ -722,12 +597,7 @@ You arrive at Harvest street, and enter a rustic shop. The proprietor fills your
 You return to the park. Robin smiles when <<he>> sees you, and pours the milk into a pot.
 <br><br>
 
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
-
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Wait
 <<effects>>
@@ -735,12 +605,7 @@ You return to the park. Robin smiles when <<he>> sees you, and pours the milk in
 You wait behind the stand until the deliquents find someone else to harass.
 <br><br>
 
-
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Challenge
 <<effects>>
@@ -748,6 +613,7 @@ You wait behind the stand until the deliquents find someone else to harass.
 You stand, and walk into the open. Robin grasps your leg to stop you, but you shake <<him>> off.
 <br><br>
 
+<<generatey2>><<generatey3>><<generatey4>><!--<<generatey5>>-->
 There are four of them, each armed with a snowball. They're about to pelt you when you speak.
 
 <<if $submissive gte 1150>>
@@ -766,36 +632,22 @@ They hold fire as a <<person2>><<person>> steps forward. "You don't know what yo
 <br>
 <<link [[Bide your time|Robin Chocolate Challenge Bide]]>><</link>><<dancedifficulty 1 800>>
 <br>
-<<link [[This is a bad idea|Robin Chocolate Cover]]>><</link>>
+<<link [[This is a bad idea|Robin Chocolate Cover]]>><<set $phase to 0>><</link>>
 <br>
 
 
 :: Robin Chocolate Cover
 <<effects>>
 
-
-"...Three!" You dive behind the stand as the snowball sails overhead. More snowballs follow. You wait with Robin until the delinquents find someone else to harass.
-<br><br>
-
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
-
-
-
-:: Robin Chocolate Cover 2
-<<effects>>
-
-You dive behind the stand as a volley of snowballs sail overhead. More snowballs follow. You wait with Robin until the delinquents find someone else to harass.
+<<if $phase is 0>>
+	"...Three!" You dive behind the stand as the snowball sails overhead.
+<<else>>
+	You dive behind the stand as a volley of snowballs sail overhead.
+<</if>>
+More snowballs follow. You wait with Robin until the delinquents find someone else to harass.
 <br><br>
 
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 
 :: Robin Chocolate Challenge Attack
@@ -815,7 +667,6 @@ You finish first. You hurl the snowball at your opponent. <<He>> flinches, cover
 	Robin gasps. Your opponent's friends laugh. You return to a grateful Robin's side, the honour of the hot chocolate stand defended.<<person1>><<npcincr Robin love 1>><<glove>>
 	<br><br>
 	<<earnFeat "Flurry">>
-
 <<else>>
 	<span class="red">but the snowball sails over <<his>> shoulder.</span> <<He>> grins, and returns fire. The snowball smashes into your face.<<gstress>><<stress 6>><<gpain>><<pain 4>>
 	<br><br>
@@ -827,12 +678,7 @@ You finish first. You hurl the snowball at your opponent. <<He>> flinches, cover
 	<br><br>
 <</if>>
 
-
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 
 :: Robin Chocolate Challenge Bide
@@ -857,12 +703,7 @@ You focus on making the snowball as sturdy as possible, until the <<person2>><<p
 	<br><br>
 <</if>>
 
-
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Take
 <<effects>>
@@ -870,39 +711,26 @@ You focus on making the snowball as sturdy as possible, until the <<person2>><<p
 
 You start preparing your ammunition.
 
-<<if $NPCName[$NPCNameList.indexOf("Robin")].dom gte 60 and _robin.trauma lte 39>>
-	Robin watches, <span class="green">then joins in.</span> Together you soon have enough snowballs.<<note "+ Preparedness" "green">>
-	<br><br>
-	You need to draw fire away from Robin's apparatus, so you bundle them in an arm, and spring from your hiding place.
-	<br><br>
-	How do you fight?
-	<br><br>
-	<<link [[Audaciously|Robin Chocolate Audacious]]>><<set $phase to 0>><</link>><<skill_difficulty "$handskill" "Hand Skill" 1 1200>>
-	<br>
-	<<link [[Patiently|Robin Chocolate Patient]]>><<set $phase to 0>><</link>><<dancedifficulty 1 1200>>
-	<br>
-<<elseif $NPCName[$NPCNameList.indexOf("Robin")].dom gte 20 and _robin.trauma lte 39>>
+<<if _robin.dom gte 20 and _robin.trauma lt 40>>
+	<<if _robin.dom gte 60>><<set $phase to 0>><<else>><<set $phase to 1>><</if>>
 	Robin watches, <span class="green">then joins in.</span> Together you soon have enough snowballs.<<note "+ Preparedness" "green">>
-	<br><br>
-	You need to draw fire away from Robin's apparatus, so you bundle them in an arm, and spring from your hiding place.
-	<br><br>
-	How do you fight?
-	<br><br>
-	<<link [[Audaciously|Robin Chocolate Audacious]]>><<set $phase to 1>><</link>><<skill_difficulty "$handskill" "Hand Skill" 1 1200>>
-	<br>
-	<<link [[Patiently|Robin Chocolate Patient]]>><<set $phase to 1>><</link>><<dancedifficulty 1 1200>>
-	<br>
 <<else>>
-	Robin watches with a frightened expression. You think you have enough snowballs. You need to draw fire away from Robin's apparatus, so you bundle them in an arm, and spring from your hiding place.
-	<br><br>
-	How do you fight?
-	<br><br>
-	<<link [[Audaciously|Robin Chocolate Audacious]]>><<set $phase to 2>><</link>><<skill_difficulty "$handskill" "Hand Skill" 1 2000>>
-	<br>
-	<<link [[Patiently|Robin Chocolate Patient]]>><<set $phase to 2>><</link>><<dancedifficulty 1 1200>>
-	<br>
+	<<set $phase to 2>>
+	Robin watches with a frightened expression. You think you have enough snowballs.
 <</if>>
-<<link [[This is a bad idea|Robin Chocolate Cover 2]]>><</link>>
+<br><br>
+You need to draw fire away from Robin's apparatus, so you bundle them in an arm, and spring from your hiding place.
+<br><br>
+How do you fight?
+<br><br>
+
+<<generatey2>><<generatey3>><<generatey4>><!--<<generatey5>>-->
+<<set _handMaxDifficulty to ($phase is 2 ? 2000 : 1200)>>
+<<link [[Audaciously|Robin Chocolate Audacious]]>><</link>><<skill_difficulty "$handskill" "Hand Skill" 1 _handMaxDifficulty>>
+<br>
+<<link [[Patiently|Robin Chocolate Patient]]>><</link>><<dancedifficulty 1 1200>>
+<br>
+<<link [[This is a bad idea|Robin Chocolate Cover]]>><<set $phase to 1>><</link>>
 <br>
 
 
@@ -911,7 +739,8 @@ You start preparing your ammunition.
 
 The delinquents are surprised by your sally. They're stood together in the open. A <<person2>><<person>> is the first to go down, slipping on the ice as the snowball smashes into <<his>> face. <<His>> friends scatter.
 <br><br>
-<<if $handskill gte random(1, 1200) and ($phase is 0 or $phase is 1) or $handskill gte random(1, 2000) and $phase is 2>>
+<<set _handMaxDifficulty to ($phase is 2 ? 2000 : 1200)>>
+<<if $handskill gte random(1, _handMaxDifficulty)>>
 	<<if $phase is 2>>
 		You don't have much ammunition, <span class="green">but you make every shot count.</span>
 	<<else>>
@@ -921,10 +750,10 @@ The delinquents are surprised by your sally. They're stood together in the open.
 	<br><br>
 	<<earnFeat "Flurry">>
 	You return to a grateful Robin's side, the honour of the hot chocolate stand defended.<<gglove>><<npcincr Robin love 1>>
-	<br><br>
 <<else>>
+	You pelt them as they struggle to put together their own snowballs, <span class="red">but your ammo is limited.</span> Snowballs exhausted, you are forced to scramble for more snow like your adversaries.
 	<<if $phase is 0>>
-		You pelt them as they struggle to put together their own snowballs, <span class="red">but your ammo is limited.</span> Snowballs exhausted, you are forced to scramble for more snow like your adversaries. You finish preparing another shot as they do. They take aim.
+		You finish preparing another shot as they do. They take aim.
 		<br><br>
 
 		The snowballs will come from several angles. You brace yourself. <span class="green">Then a snowball sails over your shoulder from behind</span>, smashing against a <<person3>><<persons>> face. You look behind you. Robin stands there, feet planted, an armful of snowballs and raw determination on <<his>> face.
@@ -934,25 +763,19 @@ The delinquents are surprised by your sally. They're stood together in the open.
 		<br><br>
 		<<earnFeat "Flurry">>
 		The honour of the hot chocolate stand defended, you return to your posts. <<gdom>><<npcincr Robin dom 1>>
-		<br><br>
 	<<else>>
-		You pelt them as they struggle to put together their own snowballs, <span class="red">but your ammo is limited.</span> Snowballs exhausted, you are forced to scramble for more snow like your adversaries. Outnumbered, you're knocked to the ground by a volley.<<gstress>><<stress 6>><<gpain>><<pain 4>>
+		Outnumbered, you're knocked to the ground by a volley.<<gstress>><<stress 6>><<gpain>><<pain 4>>
 		<br><br>
 		<<person1>>
 		Robin gasps and rushes over. Shielding you with <<his>> coat, <<he>> helps you to your feet, and pulls you back behind the stand.<<gdom>><<npcincr Robin dom 1>>
 		<br><br>
 
 		You wait for the delinquents to lose interest, and leave to harass someone else.
-		<br><br>
 	<</if>>
 <</if>>
+<br><br>
 
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
-
+<<robinChocolateOfferHelp>>
 
 
 :: Robin Chocolate Patient
@@ -975,9 +798,6 @@ The element of surprise gone, you slip behind a hedge while your adversaries are
 	<</if>>
 	<<earnFeat "Flurry">>
 	A final volley sends them running to the safety of the trees. The honour of the stand defended, you return to a grateful Robin.<<glove>><<npcincr Robin love 1>><<ltrauma>><<trauma -6>>
-	<br><br>
-
-
 <<else>>
 	You dodge, <span class="red">but slip on the ice,</span> landing on your back in the snow.
 	<br><br>
@@ -989,22 +809,19 @@ The element of surprise gone, you slip behind a hedge while your adversaries are
 		<br><br>
 		<<earnFeat "Flurry">>
 		The honour of the hot chocolate stand defended, you return to your posts.<<gdom>><<npcincr Robin dom 1>>
-		<br><br>
 	<<else>>
-		The delinquents pelt you with another volley. Robin gasps and rushes over. <<He>> shields you with <<his>> coat as <<he>> helps you to <<his>> feet, and together you return to the safety of the stand.<<gdom>><<gstress>><<gpain>><<npcincr Robin dom 1>><<stress 6>><<pain 4>>
+		The delinquents pelt you with another volley.<<gstress>><<stress 6>><<gpain>><<pain 4>>
+		<br><br>
+		<<person1>>
+		Robin gasps and rushes over. Shielding you with <<his>> coat, <<he>> helps you to your feet, and pulls you back behind the stand.<<gdom>><<npcincr Robin dom 1>>
 		<br><br>
 
-
+		You wait for the delinquents to lose interest, and leave to harass someone else.
+		<br><br>
 	<</if>>
 <</if>>
-
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
-
-
+<br><br>
+<<robinChocolateOfferHelp>>
 
 :: Robin Chocolate Kiss
 <<effects>>
@@ -1021,20 +838,8 @@ The delinquents find someone else to harass as predicated. Robin and you are too
 <br><br>
 <<person1>>
 You let Robin stand, surprising the customer with <<his>> sudden appearance. You decide to hide until the customer departs.
-<<if _robin.trauma lte 39>>
+<<if _robin.trauma lt 40>>
 	<<person2>><<He>> would work out what you were up to, and Robin would be terribly embarrassed.
 <</if>>
 <br><br>
-<<endevent>>
-<<link [[Offer help (0:30)|Robin Chocolate Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
-<br>
-<<link [[Leave|Park]]>><</link>>
-<br>
-
-:: Robin's Chocolate Help
-<<effects>>
-
-/*Just so players who saved here can escape*/
-
-<<link [[Next|Park]]>><<endevent>><</link>>
-<br>
+<<robinChocolateOfferHelp>>
-- 
GitLab


From 336479132e6bcd360e22171d1f80c1bd0be5f5cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=B6st?= <35009-Host@users.noreply.gitgud.io>
Date: Thu, 22 Sep 2022 00:29:19 +0000
Subject: [PATCH 43/50] Fixes for multiple issues and some new stuff for
 clothes

---
 game/03-JavaScript/base.js                    |  10 ++++
 game/base-clothing/clothing-under-upper.twee  |  54 ++++++++++++++++--
 game/base-clothing/clothing-under.twee        |   9 ++-
 game/base-system/time.twee                    |  14 ++++-
 game/base-system/widgets.js                   |  23 ++++----
 .../seasonal-events.twee                      |   2 +-
 game/overworld-plains/loc-estate/cards.twee   |   2 +-
 game/overworld-town/loc-shop/widgets.twee     |   3 +
 img/clothes/under_lower/thong/frayed.png      | Bin 203 -> 285 bytes
 img/clothes/under_lower/thong/frayed_gray.png | Bin 464 -> 285 bytes
 img/clothes/under_lower/thong/full.png        | Bin 203 -> 285 bytes
 img/clothes/under_lower/thong/full_gray.png   | Bin 464 -> 285 bytes
 img/clothes/under_lower/thong/penis.png       | Bin 277 -> 290 bytes
 img/clothes/under_lower/thong/penis_gray.png  | Bin 482 -> 290 bytes
 img/clothes/under_lower/thong/tattered.png    | Bin 203 -> 285 bytes
 .../under_lower/thong/tattered_gray.png       | Bin 464 -> 285 bytes
 img/clothes/under_lower/thong/torn.png        | Bin 203 -> 285 bytes
 img/clothes/under_lower/thong/torn_gray.png   | Bin 464 -> 285 bytes
 img/clothes/under_upper/pushupbra/0.png       | Bin 0 -> 223 bytes
 img/clothes/under_upper/pushupbra/0_gray.png  | Bin 0 -> 223 bytes
 img/clothes/under_upper/pushupbra/1.png       | Bin 0 -> 223 bytes
 img/clothes/under_upper/pushupbra/1_gray.png  | Bin 0 -> 223 bytes
 img/clothes/under_upper/pushupbra/2.png       | Bin 0 -> 229 bytes
 img/clothes/under_upper/pushupbra/2_gray.png  | Bin 0 -> 229 bytes
 img/clothes/under_upper/pushupbra/3.png       | Bin 0 -> 244 bytes
 img/clothes/under_upper/pushupbra/3_gray.png  | Bin 0 -> 244 bytes
 img/clothes/under_upper/pushupbra/4.png       | Bin 0 -> 249 bytes
 img/clothes/under_upper/pushupbra/4_gray.png  | Bin 0 -> 249 bytes
 img/clothes/under_upper/pushupbra/5.png       | Bin 0 -> 249 bytes
 img/clothes/under_upper/pushupbra/5_gray.png  | Bin 0 -> 249 bytes
 img/clothes/under_upper/pushupbra/frayed.png  | Bin 0 -> 124 bytes
 .../under_upper/pushupbra/frayed_gray.png     | Bin 0 -> 124 bytes
 img/clothes/under_upper/pushupbra/full.png    | Bin 0 -> 124 bytes
 .../under_upper/pushupbra/full_gray.png       | Bin 0 -> 124 bytes
 .../under_upper/pushupbra/tattered.png        | Bin 0 -> 124 bytes
 .../under_upper/pushupbra/tattered_gray.png   | Bin 0 -> 124 bytes
 img/clothes/under_upper/pushupbra/torn.png    | Bin 0 -> 124 bytes
 .../under_upper/pushupbra/torn_gray.png       | Bin 0 -> 124 bytes
 img/misc/icon/clothes/pushup_bra.png          | Bin 0 -> 287 bytes
 img/misc/icon/clothes/traits/pushup.png       | Bin 0 -> 254 bytes
 .../traits/{tanlines.png => tanLines.png}     | Bin
 41 files changed, 94 insertions(+), 23 deletions(-)
 create mode 100644 img/clothes/under_upper/pushupbra/0.png
 create mode 100644 img/clothes/under_upper/pushupbra/0_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/1.png
 create mode 100644 img/clothes/under_upper/pushupbra/1_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/2.png
 create mode 100644 img/clothes/under_upper/pushupbra/2_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/3.png
 create mode 100644 img/clothes/under_upper/pushupbra/3_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/4.png
 create mode 100644 img/clothes/under_upper/pushupbra/4_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/5.png
 create mode 100644 img/clothes/under_upper/pushupbra/5_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/frayed.png
 create mode 100644 img/clothes/under_upper/pushupbra/frayed_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/full.png
 create mode 100644 img/clothes/under_upper/pushupbra/full_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/tattered.png
 create mode 100644 img/clothes/under_upper/pushupbra/tattered_gray.png
 create mode 100644 img/clothes/under_upper/pushupbra/torn.png
 create mode 100644 img/clothes/under_upper/pushupbra/torn_gray.png
 create mode 100644 img/misc/icon/clothes/pushup_bra.png
 create mode 100644 img/misc/icon/clothes/traits/pushup.png
 rename img/misc/icon/clothes/traits/{tanlines.png => tanLines.png} (100%)

diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index c25dc2d24c..d526b61cf1 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -611,3 +611,13 @@ function pickRandom(list) {
 	return list[Math.floor(Math.random() * list.length)];
 }
 window.pickRandom = pickRandom;
+
+/**
+ * @returns 30 for November, 31 for December, 28 for February (29 if leap year), et cetera 
+ * Uses current in-game month and year when no arguments provided
+ */
+function getLastDayOfMonth(month, year) {
+    let monthNumber = new Date(Date.parse((month || V.month) + ' 1 ' + (year || V.year))).getMonth() + 1;
+    return new Date((year || V.year), monthNumber, 0).getDate();
+}
+window.getLastDayOfMonth = getLastDayOfMonth;
diff --git a/game/base-clothing/clothing-under-upper.twee b/game/base-clothing/clothing-under-upper.twee
index d0b3b27342..6ed1724d53 100644
--- a/game/base-clothing/clothing-under-upper.twee
+++ b/game/base-clothing/clothing-under-upper.twee
@@ -662,7 +662,7 @@
 	colour_sidebar: 1,
 	exposed: 1,
 	exposed_base: 1,
-	type: ["fetish", "naked"],
+	type: ["fetish", "naked", "pushup"],
 	set: "under_upper",
 	gender: "n",
 	warmth: 20,
@@ -687,7 +687,7 @@
 	integrity: 100,
 	integrity_max: 100,
 	fabric_strength: 15,
-	reveal: 900,
+	reveal: 500,
 	bustresize: 0,
 	word: "a",
 	one_piece: 0,
@@ -732,7 +732,7 @@
 	integrity_max: 200,
 	fabric_strength: 15,
 	reveal: 300,
-	bustresize: -3,
+	bustresize: -5,
 	word: "a",
 	one_piece: 0,
 	strap: 0,
@@ -901,7 +901,7 @@
 	integrity_max: 100,
 	fabric_strength: 20,
 	reveal: 200,
-	bustresize: 0,
+	bustresize: -5,
 	word: "a",
 	one_piece: 0,
 	strap: 0,
@@ -1069,7 +1069,7 @@
 	integrity: 10,
 	integrity_max: 10,
 	fabric_strength: 30,
-	reveal: 1000,
+	reveal: 990,
 	bustresize: 0,
 	word: "n",
 	one_piece: 0,
@@ -1153,7 +1153,7 @@
 	integrity_max: 200,
 	fabric_strength: 30,
 	reveal: 100,
-	bustresize: -4,
+	bustresize: -7,
 	word: "a",
 	one_piece: 0,
 	strap: 1,
@@ -1272,6 +1272,48 @@
 	iconFile: "see-through_swimsuit.png",
 	accIcon: 0,
 	outfitPrimary:{under_lower:"see-through swim bottoms"}
+},
+
+	{index: 30,
+	name: "push up bra",
+	name_cap: "Push up bra",
+	variable: "pushupbra",
+	integrity: 100,
+	integrity_max: 100,
+	fabric_strength: 30,
+	reveal: 600,
+	bustresize: 2,
+	word: "a",
+	one_piece: 0,
+	strap: 1,
+	open: 1,
+	state: "midriff",
+	state_base: "midriff",
+	state_top: "chest",
+	state_top_base: "chest",
+	plural: 0,
+	colour: 0,
+	colour_options: ["black", "blue", "brown", "green", "pink", "purple", "red", "pale tangerine", "teal", "pale white", "pale yellow", "custom"],
+	colour_sidebar: 1,
+	exposed: 0,
+	exposed_base: 0,
+	type: ["normal", "pushup"],
+	set: "under_upper",
+	gender: "f",
+	femininity: 300,
+	warmth: 10,
+	cost: 2000,
+	description: "Makes your breasts appear bigger.",
+	shop: ["clothing"],
+	accessory: 0,
+	accessory_colour: 0,
+	accessory_colour_options: [],
+	sleeve_img: 0,
+	breast_img: 1,
+	cursed: 0,
+	location: 0,
+	iconFile: "pushup_bra.png",
+	accIcon: 0
 }
 
 ]>>
diff --git a/game/base-clothing/clothing-under.twee b/game/base-clothing/clothing-under.twee
index 330820e20d..46b8fb14d7 100644
--- a/game/base-clothing/clothing-under.twee
+++ b/game/base-clothing/clothing-under.twee
@@ -968,7 +968,7 @@
 	integrity: 40,
 	integrity_max: 40,
 	fabric_strength: 20,
-	reveal: 900,
+	reveal: 700,
 	rearresize: 0,
 	word: "a",
 	one_piece: 0,
@@ -1288,6 +1288,7 @@
 	vagina_exposed_base: 0,
 	anus_exposed: 0,
 	anus_exposed_base: 0,
+	no_aside: 1,
 	type: ["normal"],
 	anal_shield: 0,
 	set: "under_lower",
@@ -1331,6 +1332,7 @@
 	vagina_exposed_base: 0,
 	anus_exposed: 0,
 	anus_exposed_base: 0,
+	no_aside: 1,
 	type: ["normal"],
 	anal_shield: 0,
 	set: "under_lower",
@@ -1366,7 +1368,7 @@
 	state_base: "waist",
 	plural: 1,
 	colour: 0,
-	colour_options: ["black", "blue", "brown", "green", "pink", "purple", "red", "tangerine", "teal", "white", "yellow", "custom"],
+	colour_options: ["black", "blue", "brown", "green", "pink", "purple", "red", "tangerine", "teal", "pale white", "pale yellow", "custom"],
 	colour_sidebar: 1,
 	exposed: 0,
 	exposed_base: 0,
@@ -1377,7 +1379,7 @@
 	type: ["swim", "school"],
 	anal_shield: 0,
 	set: "under_lower",
-	warmth: 30,
+	warmth: 10,
 	gender: "f",
 	femininity: 300,
 	cost: 3000,
@@ -1635,6 +1637,7 @@
 	vagina_exposed_base: 0,
 	anus_exposed: 0,
 	anus_exposed_base: 0,
+	no_aside: 0,
 	type: ["swim"],
 	anal_shield: 0,
 	set: "under_lower",
diff --git a/game/base-system/time.twee b/game/base-system/time.twee
index 01c0fff0ce..f904105ba0 100644
--- a/game/base-system/time.twee
+++ b/game/base-system/time.twee
@@ -663,7 +663,19 @@
 			<</if>>
 		<</if>>
 	<<case "april" "july" "december">>
-		<<if $weekday is 7 or $weekday is 1 or $weekday is 2>>
+		<<if $weekday is 1>>
+            <!-- If it's the last day of the Holidays and a Sunday, then tomorrow is a school day -->
+            <<if $monthday is getLastDayOfMonth()>>
+                <<set $schoolterm to 1>>
+            <<else>>
+                <<set $schoolterm to 0>>
+            <</if>>
+        <<elseif $weekday is 7 or $weekday is 2>>
+            <<set $schoolterm to 0>>
+        <</if>>
+    <<case "march" "june" "november">>
+        <<if $weekday is 1 and $monthday is getLastDayOfMonth()>>
+            <!-- If it's the last day before the Holidays and a Sunday, then tomorrow is not a school day -->
 			<<set $schoolterm to 0>>
 		<</if>>
 	<</switch>>
diff --git a/game/base-system/widgets.js b/game/base-system/widgets.js
index 80e1b34e5d..6859097d79 100644
--- a/game/base-system/widgets.js
+++ b/game/base-system/widgets.js
@@ -168,7 +168,7 @@ function genderappearancecheck() {
 		addfemininityfromfactor(V.player.vaginaExist * 100000 - V.player.penisExist * 100000, "Genitals exposed", "noow");
 	}
 	/* plain breasts factor */
-	addfemininityfromfactor((V.player.breastsize - 0.5) * 100, "Exposed breasts", "noow");
+	addfemininityfromfactor((V.player.perceived_breastsize - 0.5) * 100, "Exposed breasts", "noow");
 	/* Lower clothing, bulge, and genitals */
 	addfemininityofclothingarticle("over_lower", V.worn.over_lower);
 	if (!T.over_lower_protected) {
@@ -225,14 +225,14 @@ function genderappearancecheck() {
 		if (V.worn.under_upper.exposed >= 1) {
 			/* Exposed breasts */
 			T.breast_indicator = 1;
-			addfemininityfromfactor((V.player.breastsize - 0.5) * 100, "Exposed breasts");
-		} else if (!V.worn.under_upper.type.includes("chest_bind")) {
+			addfemininityfromfactor((V.player.perceived_breastsize - 0.5) * 100, "Exposed breasts");
+		} else {
 			/* Breasts covered by only underwear */
-			addfemininityfromfactor(Math.clamp((V.player.breastsize - 2) * 100, 0, Infinity), "Breast size visible through underwear");
+			addfemininityfromfactor(Math.clamp((V.player.perceived_breastsize - 2) * 100, 0, Infinity), "Breast size visible through underwear");
 		}
-	} else if (!V.worn.under_upper.type.includes("chest_bind")) {
+	} else {
 		/* Breast fully covered */
-		addfemininityfromfactor(Math.clamp((V.player.breastsize - 4) * 100, 0, Infinity), "Breast size visible through clothing");
+		addfemininityfromfactor(Math.clamp((V.player.perceived_breastsize - 4) * 100, 0, Infinity), "Breast size visible through clothing");
 	}
 	/* Pregnant Belly */
 	if (V.sexStats === undefined) {
@@ -318,21 +318,22 @@ function apparentbottomsizecheck() {
 
 function exposedcheck() {
 	if (!V.combat || V.args[0] === true) {
+		apparentbreastsizecheck();
+		apparentbottomsizecheck();
 		genderappearancecheck();
+		
 		V.player.gender_appearance = T.gender_appearance;
 		T.gender_appearance_factors.sort((a, b) => a.femininity > b.femininity);
 		V.player.gender_appearance_factors = T.gender_appearance_factors;
 		V.player.femininity = T.apparent_femininity;
-
+		
 		V.player.gender_appearance_without_overwear = T.gender_appearance_noow;
 		T.gender_appearance_factors_noow.sort((a, b) => a.femininity > b.femininity);
 		V.player.gender_appearance_without_overwear_factors = T.gender_appearance_factors_noow;
 		V.player.femininity_without_overwear = T.apparent_femininity_noow;
-
+		
 		V.breastindicator = T.breast_indicator;
-
-		apparentbreastsizecheck();
-		apparentbottomsizecheck();
+		
 	}
 }
 DefineMacro("exposedcheck", exposedcheck);
diff --git a/game/flavour-text-generators/seasonal-events.twee b/game/flavour-text-generators/seasonal-events.twee
index 34a55afcec..9014be4ba4 100644
--- a/game/flavour-text-generators/seasonal-events.twee
+++ b/game/flavour-text-generators/seasonal-events.twee
@@ -400,7 +400,7 @@
 			A surge of wind sends leaves swirling in a circle around you. You feel a sense of calm as you stand in the eye of the storm, before the wind dies down again. <<stress -3>><<lstress>>
 		<</addinlineevent>>
 		<<addinlineevent "autumn_anywhere_2">>
-			The wind kicks up some leaves in your face, leaving you sputtering. <<stress 1>><<gstress>>
+			The wind kicks up some leaves in your face<<if !$worn.face.type.includes("covered")>>, leaving you sputtering<</if>>. <<stress 1>><<gstress>>
 		<</addinlineevent>>
 		<<addinlineevent "autumn_anywhere_3" 0.33>>
 			<<dancedifficulty 1 500 true>>
diff --git a/game/overworld-plains/loc-estate/cards.twee b/game/overworld-plains/loc-estate/cards.twee
index 8e551962d4..845df60e83 100644
--- a/game/overworld-plains/loc-estate/cards.twee
+++ b/game/overworld-plains/loc-estate/cards.twee
@@ -1862,7 +1862,7 @@ Before <<he>> can say anything, you continue.
 		<<elseif $rng gte 21>>
 			"I love the anticipation," Wren says.
 		<<else>>
-			<<if $player.breastsize gte 7 and !$worn.under_upper.type.includes("chest_bind") and !$worn.upper.type.includes("chest_bind") and !$worn.over_upper.type.includes("chest_bind")>>
+			<<if $player.perceived_breastsize gte 7>>
 				"Think <<pher>> breasts are as big as they look?" Wren laughs.
 			<<else>>
 				"I bet you look good without a top on," Wren smirks.
diff --git a/game/overworld-town/loc-shop/widgets.twee b/game/overworld-town/loc-shop/widgets.twee
index 951e86443e..3f6b7ab5c1 100644
--- a/game/overworld-town/loc-shop/widgets.twee
+++ b/game/overworld-town/loc-shop/widgets.twee
@@ -506,6 +506,9 @@ Forth argument - item index*/
 			<<set _clothesDesc to "A convenient handle to yank you around with.">>
 		<<case "event">>
 			<<set _clothesDesc to "A special outfit for a special occasion.">>
+		<<case "pushup">>
+			<<set _clothesTrait to "Push up">>
+			<<set _clothesDesc to "Makes your breasts appear bigger.">>
 		<<default>>
 			<<set $noTraitDescription to 1>>
 	<</switch>>
diff --git a/img/clothes/under_lower/thong/frayed.png b/img/clothes/under_lower/thong/frayed.png
index 3775a4b26339e988d34f6c97364722f30c7e2a0d..2b4b87a39cc1104904b42590f54615f35e3390ef 100644
GIT binary patch
literal 285
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838CaNsl=;5PAwWtfz$e5NNN1axo=izuWo-PQ
zpkRA+^uEJ|??Gxyg8YIR9G=}s19EnHx;TbZ+<J3iqac$Zk4xb81!7m2ba%AA-Y=@~
zNkG=c`o??LQ~&zdfJ*Uz|7+}erEh<I%zWwZ$BNy%(!YP*b*%U8uaAr;{{`7Te<Kxt
zYn{COgxBj?)4xAv4zpj%_x?D0$REb*{><B6A7@`vck1Qe9}QACEwH)W%q#?wb^IUy
eT^Zy<1`AHzH&RzC)^lwK@jPAqT-G@yGywqpCR*(P

literal 203
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkUo);l5J{wG9`s&
zrr81@pQ$9sFPLFd@E`dZKwgfgi(^Q|t+(eC#TpEFTn@g7o3#3BLXw3n+tJsI0ixP7
z1Pf<>Uky}<41QeM`)<a{TDye3FZ|wpW-PsTv)1l`)i=2}K+fZnK*IEJHRDfY9YFR2
Z_Bgd|x+l55o<9SU@pScbS?83{1OQT|K}rAs

diff --git a/img/clothes/under_lower/thong/frayed_gray.png b/img/clothes/under_lower/thong/frayed_gray.png
index 90ec6dea045bf578ee671911b2a78ac058bb70ea..ec9bf58d693606036e613ff2059a308b7a07a02f 100644
GIT binary patch
delta 221
zcmcb>JeO&LL_7;K0|SHkzRMv%N+`f5#1%*f1O!Z*HZ3nNZ^eogot>SMoh6+>QO1%W
zzhDN3XE)M-oSmL7jv*Dd-dxxy$YjXl61aVV*cB$-9j&kTiz<8)kae-X@!s{+zdp8!
zfpTvD*Vy$+-~RfT`O@Ey6}xw(fB(AcSnu0k9~n>n3$lIwMk@Z+I(hjCuh+Ate}Bvz
zX1|p0{c-k?KaAJ?nYX<@&c3GZ)XTp=8l)x$N^08NZe|t&+RotkKmNNi$jJ;AoVstM
Uu2!t)+79A*y85}Sb4q9e0K*Mjng9R*

literal 464
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388}#gRQ^o1H$cvGPZ!6Kid%1Q9^`5Y5MaF!
z{U!Gui@j;V^Yb^Ci7jn${Bp@MU0tImX2-e1AYB6j67v1lvj5nYShsIqUd7?##?kMd
z?mzk8`1v(vhPN{NKF96n$ksBe7yVR!o{gb(>dSqJe!C1k=co8A+gJ8ET={>g8H2`~
zOH~c?cWtl#b*=eA%OCL^hJc8b!50kFV<%~zs~0_4f0B*iis6~)e>}w@pX$??8xDyu
jh%6fr&jKxNxVww-)E4FUbKmYf0&;_=tDnm{r-UW|a}8i}

diff --git a/img/clothes/under_lower/thong/full.png b/img/clothes/under_lower/thong/full.png
index 3775a4b26339e988d34f6c97364722f30c7e2a0d..2b4b87a39cc1104904b42590f54615f35e3390ef 100644
GIT binary patch
literal 285
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838CaNsl=;5PAwWtfz$e5NNN1axo=izuWo-PQ
zpkRA+^uEJ|??Gxyg8YIR9G=}s19EnHx;TbZ+<J3iqac$Zk4xb81!7m2ba%AA-Y=@~
zNkG=c`o??LQ~&zdfJ*Uz|7+}erEh<I%zWwZ$BNy%(!YP*b*%U8uaAr;{{`7Te<Kxt
zYn{COgxBj?)4xAv4zpj%_x?D0$REb*{><B6A7@`vck1Qe9}QACEwH)W%q#?wb^IUy
eT^Zy<1`AHzH&RzC)^lwK@jPAqT-G@yGywqpCR*(P

literal 203
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkUo);l5J{wG9`s&
zrr81@pQ$9sFPLFd@E`dZKwgfgi(^Q|t+(eC#TpEFTn@g7o3#3BLXw3n+tJsI0ixP7
z1Pf<>Uky}<41QeM`)<a{TDye3FZ|wpW-PsTv)1l`)i=2}K+fZnK*IEJHRDfY9YFR2
Z_Bgd|x+l55o<9SU@pScbS?83{1OQT|K}rAs

diff --git a/img/clothes/under_lower/thong/full_gray.png b/img/clothes/under_lower/thong/full_gray.png
index 90ec6dea045bf578ee671911b2a78ac058bb70ea..ec9bf58d693606036e613ff2059a308b7a07a02f 100644
GIT binary patch
delta 221
zcmcb>JeO&LL_7;K0|SHkzRMv%N+`f5#1%*f1O!Z*HZ3nNZ^eogot>SMoh6+>QO1%W
zzhDN3XE)M-oSmL7jv*Dd-dxxy$YjXl61aVV*cB$-9j&kTiz<8)kae-X@!s{+zdp8!
zfpTvD*Vy$+-~RfT`O@Ey6}xw(fB(AcSnu0k9~n>n3$lIwMk@Z+I(hjCuh+Ate}Bvz
zX1|p0{c-k?KaAJ?nYX<@&c3GZ)XTp=8l)x$N^08NZe|t&+RotkKmNNi$jJ;AoVstM
Uu2!t)+79A*y85}Sb4q9e0K*Mjng9R*

literal 464
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388}#gRQ^o1H$cvGPZ!6Kid%1Q9^`5Y5MaF!
z{U!Gui@j;V^Yb^Ci7jn${Bp@MU0tImX2-e1AYB6j67v1lvj5nYShsIqUd7?##?kMd
z?mzk8`1v(vhPN{NKF96n$ksBe7yVR!o{gb(>dSqJe!C1k=co8A+gJ8ET={>g8H2`~
zOH~c?cWtl#b*=eA%OCL^hJc8b!50kFV<%~zs~0_4f0B*iis6~)e>}w@pX$??8xDyu
jh%6fr&jKxNxVww-)E4FUbKmYf0&;_=tDnm{r-UW|a}8i}

diff --git a/img/clothes/under_lower/thong/penis.png b/img/clothes/under_lower/thong/penis.png
index 38ea929808761fbec9b9067e6850ef79ae88c134..016569b59612e089117e98813c9d9689eeedc425 100644
GIT binary patch
delta 215
zcmbQrw1{bfO0ZCXPlzi614Fi{=_+I62L%NuQ&P4^M@wv%X#<KfmIV0)GdMiEkp|@K
z^K@|xskrs#ilOLX0|A$Vixs#Q0a3!gkVhd^D`moe>zog{{&(%Vi4SFc7%Db>TdkLK
zy`SIX`|5hx;y%m%&#Sm^e|^k6>F?6BhR1TgE`R&$Bjf7%m(DTfzdO#prp`-#Z{Ce{
z^70ejh422}wCy!W?9}bw9~sw9Y?Rdev4x#o1?UEbrhoh2xvv1R3WRp;l3v(wWA14X
N&(qb<Wt~$(69Ce>U_t-@

delta 203
zcmZ3)G?i(BN|b1TPlzi61H;Lblvkyt*`}tC3JX_+gaElKB9{mNC74Ts{DK)SUYy)`
z=@5{+#?!?yq~g}wONPA6h9azv!4_N#6S&+JMGnb3)tuFQsk~O{e95|RFHa{=d?+#T
z1DorI<Ig^Qys>UR|BBz=JAQ6WSzl+j;9b0M-)F&RpFzz2pEl>dFcjL$2YkQYbp77n
z8i%{_^#*nhch0k4`MWg%tcDq6)&y4Z{a@KKk4a7R|H|V7bP9u~tDnm{r-UW|1Ls`)

diff --git a/img/clothes/under_lower/thong/penis_gray.png b/img/clothes/under_lower/thong/penis_gray.png
index 0958497fda35c6a8648bd090c134ee4add9a7da2..42fd705f564c4af8ccef974d25e4a24ef8c1962f 100644
GIT binary patch
delta 226
zcmaFFyohOnL_7;K0|SHkzRMv%N+`f5#1%*f1O(*e<*it;V%oH6ot>S{_pkc^MHx$i
z{DK)Ap4~_Ta`t(;IEGZ*dUM54^ss?|%fZD8T#JAx;a|w3kgAn3;lFjxhg|==cHP88
zIq!;1-&X78T<_=i_`bScwz$u-|MM#D+g~3uPx`y`tl_bougl;5`pCF?{-tw_`R|Ui
zuc`Br-<x-1oxJ>ncj3FgH*I?j5<7MK_eaLH6B8vhe{5lAR{=VKq3PfLckU}dtOB83
WyQCL3+?abB#Pf9Zb6Mw<&;$SlaAXqz

literal 482
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388}#gRQ^o1H$cuxPZ!6Kid%1Q9ppUZAi#QI
zeFyIi_fsF{h`l|qIduu==?-yQmu44%@VVdf8d=n8X3UK>V+86R5b(ov^)=Q#(e{4x
z`?>#p_;z+u`Omyh^=EgLGCEk--~aqByv0(~x?c2C{W%tf)~PRR|IT>Ro^oCFwxVUp
zR_l7xPxI568V;GQ<^Hjxc>0rFTmk)m<YzK0*buaPL7mSxPrr@-S9|>H_hAT#SZUm#
zV!2(fVc8S=R3?U3FOI90AN~>kX}-~bdENdslZT~x>HhiFi$Fo|>FVdQ&MBb@00Zo2
AWB>pF

diff --git a/img/clothes/under_lower/thong/tattered.png b/img/clothes/under_lower/thong/tattered.png
index 3775a4b26339e988d34f6c97364722f30c7e2a0d..2b4b87a39cc1104904b42590f54615f35e3390ef 100644
GIT binary patch
literal 285
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838CaNsl=;5PAwWtfz$e5NNN1axo=izuWo-PQ
zpkRA+^uEJ|??Gxyg8YIR9G=}s19EnHx;TbZ+<J3iqac$Zk4xb81!7m2ba%AA-Y=@~
zNkG=c`o??LQ~&zdfJ*Uz|7+}erEh<I%zWwZ$BNy%(!YP*b*%U8uaAr;{{`7Te<Kxt
zYn{COgxBj?)4xAv4zpj%_x?D0$REb*{><B6A7@`vck1Qe9}QACEwH)W%q#?wb^IUy
eT^Zy<1`AHzH&RzC)^lwK@jPAqT-G@yGywqpCR*(P

literal 203
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkUo);l5J{wG9`s&
zrr81@pQ$9sFPLFd@E`dZKwgfgi(^Q|t+(eC#TpEFTn@g7o3#3BLXw3n+tJsI0ixP7
z1Pf<>Uky}<41QeM`)<a{TDye3FZ|wpW-PsTv)1l`)i=2}K+fZnK*IEJHRDfY9YFR2
Z_Bgd|x+l55o<9SU@pScbS?83{1OQT|K}rAs

diff --git a/img/clothes/under_lower/thong/tattered_gray.png b/img/clothes/under_lower/thong/tattered_gray.png
index 90ec6dea045bf578ee671911b2a78ac058bb70ea..ec9bf58d693606036e613ff2059a308b7a07a02f 100644
GIT binary patch
delta 221
zcmcb>JeO&LL_7;K0|SHkzRMv%N+`f5#1%*f1O!Z*HZ3nNZ^eogot>SMoh6+>QO1%W
zzhDN3XE)M-oSmL7jv*Dd-dxxy$YjXl61aVV*cB$-9j&kTiz<8)kae-X@!s{+zdp8!
zfpTvD*Vy$+-~RfT`O@Ey6}xw(fB(AcSnu0k9~n>n3$lIwMk@Z+I(hjCuh+Ate}Bvz
zX1|p0{c-k?KaAJ?nYX<@&c3GZ)XTp=8l)x$N^08NZe|t&+RotkKmNNi$jJ;AoVstM
Uu2!t)+79A*y85}Sb4q9e0K*Mjng9R*

literal 464
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388}#gRQ^o1H$cvGPZ!6Kid%1Q9^`5Y5MaF!
z{U!Gui@j;V^Yb^Ci7jn${Bp@MU0tImX2-e1AYB6j67v1lvj5nYShsIqUd7?##?kMd
z?mzk8`1v(vhPN{NKF96n$ksBe7yVR!o{gb(>dSqJe!C1k=co8A+gJ8ET={>g8H2`~
zOH~c?cWtl#b*=eA%OCL^hJc8b!50kFV<%~zs~0_4f0B*iis6~)e>}w@pX$??8xDyu
jh%6fr&jKxNxVww-)E4FUbKmYf0&;_=tDnm{r-UW|a}8i}

diff --git a/img/clothes/under_lower/thong/torn.png b/img/clothes/under_lower/thong/torn.png
index 3775a4b26339e988d34f6c97364722f30c7e2a0d..2b4b87a39cc1104904b42590f54615f35e3390ef 100644
GIT binary patch
literal 285
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838CaNsl=;5PAwWtfz$e5NNN1axo=izuWo-PQ
zpkRA+^uEJ|??Gxyg8YIR9G=}s19EnHx;TbZ+<J3iqac$Zk4xb81!7m2ba%AA-Y=@~
zNkG=c`o??LQ~&zdfJ*Uz|7+}erEh<I%zWwZ$BNy%(!YP*b*%U8uaAr;{{`7Te<Kxt
zYn{COgxBj?)4xAv4zpj%_x?D0$REb*{><B6A7@`vck1Qe9}QACEwH)W%q#?wb^IUy
eT^Zy<1`AHzH&RzC)^lwK@jPAqT-G@yGywqpCR*(P

literal 203
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkUo);l5J{wG9`s&
zrr81@pQ$9sFPLFd@E`dZKwgfgi(^Q|t+(eC#TpEFTn@g7o3#3BLXw3n+tJsI0ixP7
z1Pf<>Uky}<41QeM`)<a{TDye3FZ|wpW-PsTv)1l`)i=2}K+fZnK*IEJHRDfY9YFR2
Z_Bgd|x+l55o<9SU@pScbS?83{1OQT|K}rAs

diff --git a/img/clothes/under_lower/thong/torn_gray.png b/img/clothes/under_lower/thong/torn_gray.png
index 90ec6dea045bf578ee671911b2a78ac058bb70ea..ec9bf58d693606036e613ff2059a308b7a07a02f 100644
GIT binary patch
delta 221
zcmcb>JeO&LL_7;K0|SHkzRMv%N+`f5#1%*f1O!Z*HZ3nNZ^eogot>SMoh6+>QO1%W
zzhDN3XE)M-oSmL7jv*Dd-dxxy$YjXl61aVV*cB$-9j&kTiz<8)kae-X@!s{+zdp8!
zfpTvD*Vy$+-~RfT`O@Ey6}xw(fB(AcSnu0k9~n>n3$lIwMk@Z+I(hjCuh+Ate}Bvz
zX1|p0{c-k?KaAJ?nYX<@&c3GZ)XTp=8l)x$N^08NZe|t&+RotkKmNNi$jJ;AoVstM
Uu2!t)+79A*y85}Sb4q9e0K*Mjng9R*

literal 464
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388}#gRQ^o1H$cvGPZ!6Kid%1Q9^`5Y5MaF!
z{U!Gui@j;V^Yb^Ci7jn${Bp@MU0tImX2-e1AYB6j67v1lvj5nYShsIqUd7?##?kMd
z?mzk8`1v(vhPN{NKF96n$ksBe7yVR!o{gb(>dSqJe!C1k=co8A+gJ8ET={>g8H2`~
zOH~c?cWtl#b*=eA%OCL^hJc8b!50kFV<%~zs~0_4f0B*iis6~)e>}w@pX$??8xDyu
jh%6fr&jKxNxVww-)E4FUbKmYf0&;_=tDnm{r-UW|a}8i}

diff --git a/img/clothes/under_upper/pushupbra/0.png b/img/clothes/under_upper/pushupbra/0.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d724fe90601dd0fa9d8566108ff962536f3ae29
GIT binary patch
literal 223
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkj^$WT^}C)prF9+
z(t=4KRV6`w!3+-1ZlnP@jh-%!Ar-gYo>LTRF%WP)DB<HL-W<6({P2+@1y(#<MT}=w
zG`?FkvHq1PP%#uVu;1SEBF^DegH%mGykNlM-&YvDXN%uW=lk*fw`2c1VRoJ0H&4Cq
xcxTMsbMgAc#lMd*rp}EjnQsZxk3{c#$P~TL^5^pD^Y4K~Jzf1=);T3K0RYrMO1A(2

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/0_gray.png b/img/clothes/under_upper/pushupbra/0_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..6cceaca036b2783830343a9b4aa464d1f972bac8
GIT binary patch
literal 223
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkPZk4Xl`y^v0}x^
zx)YN@s!D?Vf*Bm1-ADs+8a-VcLn>~)J*OztVj$ppP{PMgyg71n_~9c*3aogziWtwV
zXneP7V*M*opkgR!V86ZRMV!N{2C15Wc)@_hzppTQ&lbO%&iCW{Z^!<3!t6S~Z=QPJ
x@y?jN=i>E?i+>+sOr0B5GT#!WABo=gkSThf<<I5Q=idW~db;|#taD0e0sv`@OO^lt

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/1.png b/img/clothes/under_upper/pushupbra/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d724fe90601dd0fa9d8566108ff962536f3ae29
GIT binary patch
literal 223
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkj^$WT^}C)prF9+
z(t=4KRV6`w!3+-1ZlnP@jh-%!Ar-gYo>LTRF%WP)DB<HL-W<6({P2+@1y(#<MT}=w
zG`?FkvHq1PP%#uVu;1SEBF^DegH%mGykNlM-&YvDXN%uW=lk*fw`2c1VRoJ0H&4Cq
xcxTMsbMgAc#lMd*rp}EjnQsZxk3{c#$P~TL^5^pD^Y4K~Jzf1=);T3K0RYrMO1A(2

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/1_gray.png b/img/clothes/under_upper/pushupbra/1_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..6cceaca036b2783830343a9b4aa464d1f972bac8
GIT binary patch
literal 223
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkPZk4Xl`y^v0}x^
zx)YN@s!D?Vf*Bm1-ADs+8a-VcLn>~)J*OztVj$ppP{PMgyg71n_~9c*3aogziWtwV
zXneP7V*M*opkgR!V86ZRMV!N{2C15Wc)@_hzppTQ&lbO%&iCW{Z^!<3!t6S~Z=QPJ
x@y?jN=i>E?i+>+sOr0B5GT#!WABo=gkSThf<<I5Q=idW~db;|#taD0e0sv`@OO^lt

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/2.png b/img/clothes/under_upper/pushupbra/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..c53bea18dcb7b98b5d598105d703c12909e9203e
GIT binary patch
literal 229
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkj^$WT^}C)prF9+
z(t=4KRV6`w!3+-1ZlnP@?Vc`<Ar-gYo>LTRF%WP)DB<HL-W<6(JX%<I^YX(94KWPH
zSqpY&J(*v{3RDdR502%>mFO#!I`G=9=;v5*vG!HN(zD&~jM-~`e_i1Iy_0#`|9hv>
zyWa(~%N%S_u09}9D{H&UUnbz%O4si*K`ulC745=&HtvpL{JU~MGM=t}F6*2UngFrD
BN3{R|

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/2_gray.png b/img/clothes/under_upper/pushupbra/2_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba428e552724edca078f399df3fbb14d0926bd54
GIT binary patch
literal 229
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkPZk4Xl`y^v0}x^
zx)YN@s!D?Vf*Bm1-ADs++C5zyLn>~)J*OztVj$ppP{PMgyg71nc(kza=H-VI8e$lX
zvli^mdNRL?6{s2t9vsV$E74adb>OvI(a*8sV(qJjrDwa}8MD{?{<^^Zdnfa>|MyO%
zcfSi}mpRy=Tzx>IR@Qcxzf8cjm9F1sf?S9OD%yqlY}_5g_;=-iWISE{T-G@yGywoi
CMo5$Z

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/3.png b/img/clothes/under_upper/pushupbra/3.png
new file mode 100644
index 0000000000000000000000000000000000000000..81687c60b67b36442db252f9faea6aad4890e952
GIT binary patch
literal 244
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkj^$WT^}C)prF9+
z(t=4KRV6`w!3+-1ZlnP@(>z@qLn>~)J+CNq$Uva&;w)3!SRY^B@WV&0JSmajQ8CUq
zv#RxbTG00YHFtr^VPM~m_0#u?2UsQe^S!Yb+@St0`R?{pj2q*U9+>4X4(IdWJM!Z5
zXAPMNvK=3DZbw=xm<v3<ntTN)J}2CMU7Ur&fA-^7wAgFdCTX$5j6~3X+RdLj`Y|8<
R5NHJw^mO%eS?83{1OSFvPmKTo

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/3_gray.png b/img/clothes/under_upper/pushupbra/3_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..996e097fe36163084ad7953edc1012180f664064
GIT binary patch
literal 244
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkPZk4Xl`y^v0}x^
zx)YN@s!D?Vf*Bm1-ADs+rg^$JhE&{odtOoKkbywk#aX7du|B@M;fIf0c~T<5qhg$K
zW>xF=w4m+(YwiM-!@#~B>!<G(53ow`=X+x>xIz70^4;yH7&pcxJuu5(9M0##cjU$A
z&l)llWII0Q+>W$XFc)}yHTeoqd``Iix;P7k|Ln)FXtCF@P10hA8Hu3(w3|P5^kY8y
RA<zmW=;`X`vd$@?2>>ndP;3AI

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/4.png b/img/clothes/under_upper/pushupbra/4.png
new file mode 100644
index 0000000000000000000000000000000000000000..19d23c4c27d7f8d7359d858ac9803d9572571a5a
GIT binary patch
literal 249
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkj^$WT^}C)prF9+
z(t=4KRV6`w!3+-1ZlnP@vproLLn>~)J+H`j*g(Mbpuprg=Tuadgliibp8V?-vs_E>
z#G>3ZmBW9l;()4Qpsr$`ewDsL=>aL3i2q6n`%Zh!{cc+9uyTI+&BbSbPqS382<Qus
z{TBF{&4vAx;U)H-3<quZPYsp=TraA>HQYFG@AkFoM-4ytw_ToO@xWSOiY3fo1iho(
XeDd^M_6Yl#{vbh5S3j3^P6<r_HjGo0

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/4_gray.png b/img/clothes/under_upper/pushupbra/4_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..48407333718b028aeea759951d8df73733ea028b
GIT binary patch
literal 249
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkPZk4Xl`y^v0}x^
zx)YN@s!D?Vf*Bm1-ADs+W_!9ghE&{odtQ<6uz`T<L4nD0&Z(#@3D-6>Jo(ovX1SK$
ziAA|-Du@48#Q{~rKwZT={VIKh(gRX55&xAE_MP^c``xtIVdebtn~Tr>o@S|F5zrSN
z`z`P@n+y9X!%OTv84lX+pBgL$xL#C$Yq)XX-tBAEj~agPZ@WCn;(@im6ib-F2zp1m
X`Q+)j>=E`e{Xv4Bu6{1-oD!M<;%`)Q

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/5.png b/img/clothes/under_upper/pushupbra/5.png
new file mode 100644
index 0000000000000000000000000000000000000000..19d23c4c27d7f8d7359d858ac9803d9572571a5a
GIT binary patch
literal 249
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkj^$WT^}C)prF9+
z(t=4KRV6`w!3+-1ZlnP@vproLLn>~)J+H`j*g(Mbpuprg=Tuadgliibp8V?-vs_E>
z#G>3ZmBW9l;()4Qpsr$`ewDsL=>aL3i2q6n`%Zh!{cc+9uyTI+&BbSbPqS382<Qus
z{TBF{&4vAx;U)H-3<quZPYsp=TraA>HQYFG@AkFoM-4ytw_ToO@xWSOiY3fo1iho(
XeDd^M_6Yl#{vbh5S3j3^P6<r_HjGo0

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/5_gray.png b/img/clothes/under_upper/pushupbra/5_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..48407333718b028aeea759951d8df73733ea028b
GIT binary patch
literal 249
zcmeAS@N?(olHy`uVBq!ia0y~yU;;838JL)X)Q*2@Uw{-(fKP}kkPZk4Xl`y^v0}x^
zx)YN@s!D?Vf*Bm1-ADs+W_!9ghE&{odtQ<6uz`T<L4nD0&Z(#@3D-6>Jo(ovX1SK$
ziAA|-Du@48#Q{~rKwZT={VIKh(gRX55&xAE_MP^c``xtIVdebtn~Tr>o@S|F5zrSN
z`z`P@n+y9X!%OTv84lX+pBgL$xL#C$Yq)XX-tBAEj~agPZ@WCn;(@im6ib-F2zp1m
X`Q+)j>=E`e{Xv4Bu6{1-oD!M<;%`)Q

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/frayed.png b/img/clothes/under_upper/pushupbra/frayed.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/frayed_gray.png b/img/clothes/under_upper/pushupbra/frayed_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/full.png b/img/clothes/under_upper/pushupbra/full.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/full_gray.png b/img/clothes/under_upper/pushupbra/full_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/tattered.png b/img/clothes/under_upper/pushupbra/tattered.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/tattered_gray.png b/img/clothes/under_upper/pushupbra/tattered_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/torn.png b/img/clothes/under_upper/pushupbra/torn.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/clothes/under_upper/pushupbra/torn_gray.png b/img/clothes/under_upper/pushupbra/torn_gray.png
new file mode 100644
index 0000000000000000000000000000000000000000..fec2adc71ce563f03bde8cb0680d4173e634ff30
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8385o&?)c?2`6(GeN;1l8sq?cFO-U3OM1o;Is
zI6S+N2IQ!Fx;TbZ+<JS^kP*l`r0{#W*)h2UAQJ^_WOfAVOH^EbA0+JQ>gTe~DWM4f
D_0t+>

literal 0
HcmV?d00001

diff --git a/img/misc/icon/clothes/pushup_bra.png b/img/misc/icon/clothes/pushup_bra.png
new file mode 100644
index 0000000000000000000000000000000000000000..2659b28abfc41b53466f0887967361ef72fd9463
GIT binary patch
literal 287
zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGmH|E?u0VP}1H*p?hBsjH8kju9
zz;F=E*bOEpGcZhKVA#vRaEXDTj)7r41H)Ga2K@l$J3!6cB|(0{44b}wc>mz?t_8D}
z*E%y?0Sb3{x;TbtoPT<bo3BNIhb7?8Yro9G_w_fH9%^#+U*M}?T&s9+Z-T*7gWC5c
zH?AwM`Q6Z+SLiDB<=C}PITd-8CN|sdNWY72ON>xq@=!lAx$B~K_;sFwmpnTrbH8k>
zT^HA_tf@1x+dXue@N2E#_F?a)Y@V(%|I>6;%gy}rEMG1PxGyj4<l$)b{l!nldEK0?
UMoYFg0$s)6>FVdQ&MBb@0PsX=6aWAK

literal 0
HcmV?d00001

diff --git a/img/misc/icon/clothes/traits/pushup.png b/img/misc/icon/clothes/traits/pushup.png
new file mode 100644
index 0000000000000000000000000000000000000000..34192e1711809911120d1a682eaa6c31bd5913b6
GIT binary patch
literal 254
zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa_5nU2u0Z-f(V(}t7fo%t=h=La
zxg|k<!3;;73|QCZr`hb=zIkRtVswzXs_+%t?K(jDC{Gv15Q)oMdp!9X40xC?Pr9@z
z|KI=U!obCG778qO5!W;%e`*~t?$F-;Vd>?ofj5&@7rIAs&U+hut!?K4xl?j4LK-=l
vTDB`Iip=d4C~EvKxcX(eLGUTrr_1MPwX>M#%$*$!w1vUb)z4*}Q$iB}{PKQL

literal 0
HcmV?d00001

diff --git a/img/misc/icon/clothes/traits/tanlines.png b/img/misc/icon/clothes/traits/tanLines.png
similarity index 100%
rename from img/misc/icon/clothes/traits/tanlines.png
rename to img/misc/icon/clothes/traits/tanLines.png
-- 
GitLab


From 4c473391f4b52c8cea53bbbee57a62a9c1e15cf4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=B6st?= <35009-Host@users.noreply.gitgud.io>
Date: Thu, 22 Sep 2022 00:32:36 +0000
Subject: [PATCH 44/50] More compact pepper sprays display in the sidebar
 (closes #107)

---
 game/04-Variables/variables-start.twee        |   3 +-
 .../04-Variables/variables-versionUpdate.twee |   4 +
 game/base-clothing/images.twee                |  20 +---
 game/base-clothing/widgets.twee               |  33 ++++++
 game/base-system/overlays/options.twee        |   8 +-
 modules/css/base.css                          | 110 +++++++++---------
 6 files changed, 102 insertions(+), 76 deletions(-)

diff --git a/game/04-Variables/variables-start.twee b/game/04-Variables/variables-start.twee
index 7b05924f00..598db90df3 100644
--- a/game/04-Variables/variables-start.twee
+++ b/game/04-Variables/variables-start.twee
@@ -45,7 +45,8 @@
 		newWardrobeStyle: true,
 		useNarrowMarket: false,
 		skipStatisticsConfirmation: false,
-		showDebugRenderer: false
+		showDebugRenderer: false,
+		pepperSprayDisplay: "sprays"
 	}>>
 
 <<if StartConfig.enableImages is false>>
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index 3080e1c906..a96d5029d3 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -3725,4 +3725,8 @@
 		<<set $makeup.mascara_running = 0>>
 	<</if>>
 
+	<!-- v0.3.11.4 New pepper spray display -->
+	<<if $options.pepperSprayDisplay is undefined>>
+		<<set $options.pepperSprayDisplay to "sprays">>
+	<</if>>
 <</widget>>
diff --git a/game/base-clothing/images.twee b/game/base-clothing/images.twee
index e7ba6ff434..548f571aaa 100644
--- a/game/base-clothing/images.twee
+++ b/game/base-clothing/images.twee
@@ -2,16 +2,10 @@
 <<widget "img">>
 <<set _filters to $skinColor.current>>
 <<set _img to setup.tanImg.sidebar[($options.tanImgEnabled ? "t" : "f")]>>
-<<charLight "118px" "187px">>
-<div id="img" @class="limitedColourContainerClasses() + ($options.sidebarAnimations isnot false ? '':' noAnimations')">
+<<charLight "118px" "183px">>
+<div id="img" @class="limitedColourContainerClasses() + ($options.sidebarAnimations isnot false ? '':' noAnimations') + ' offset-sidebar-img'">
 <<if $options.sidebarRenderer is 'canvas'>>
-	<<for _i to 1; _i lte $spraymax; _i++>>
-		<<if $spray gte _i>>
-			<img @id="'spray'+_i" src="img/ui/pepperspray.png">
-		<<else>>
-			<img @id="'spray'+_i" src="img/ui/emptyspray.png">
-		<</if>>
-	<</for>>
+	<<peppersprays>>
 	<<canvasimg>>
 <<else>>
 	<<if $options.sidebarRenderer is 'both'>>
@@ -70,13 +64,7 @@
 	<img class="layer-base anim-idle-2f" @src="_img.basenoarms" @style="'filter: '+_filters.body">
 	<img class="layer-basehead anim-idle-2f" @src="_img.basehead" @style="'filter: '+_filters.body">
 
-	<<for _i to 1; _i lte $spraymax; _i++>>
-		<<if $spray gte _i>>
-			<img @id="'spray'+_i" src="img/ui/pepperspray.png">
-		<<else>>
-			<img @id="'spray'+_i" src="img/ui/emptyspray.png">
-		<</if>>
-	<</for>>
+	<<peppersprays>>
 	<<if $options.tanImgEnabled>>
 		<<if $skinColor.tanValues[0] isnot $skinColor.tanValues[2]>>
 			<img class="layer-base anim-idle-2f" @src="_img.baseTanSwimshorts" @style="'filter: '+_filters.swimshorts">
diff --git a/game/base-clothing/widgets.twee b/game/base-clothing/widgets.twee
index 6c74b30951..36508307cd 100644
--- a/game/base-clothing/widgets.twee
+++ b/game/base-clothing/widgets.twee
@@ -1605,3 +1605,36 @@
 		<</if>>
 	<</if>>
 <</widget>>
+
+<<widget "peppersprays">>
+	<<if $options.pepperSprayDisplay isnot "none">>
+		<div id="pepper-sprays" class="pepper-sprays">
+			<!-- Compact style (dots) -->
+			<<if $spraymax gt 1 and ($options.pepperSprayDisplay is "compact" or $spraymax gt 7 or ($spraymax gt 5 and $options.sidebarRenderer is "both"))>>
+				<<if $spray gt 0>>
+					<img src="img/ui/pepperspray.png">
+				<<else>>
+					<img src="img/ui/emptyspray.png">
+				<</if>>
+				<div class="pepper-sprays-dots">
+					<<for _i to 1; _i lte $spraymax; _i++>>
+						<<if $spray gte _i>>
+							<div class="pepper-spray-dot-full"></div>
+						<<else>>
+							<div class="pepper-spray-dot-empty"></div>
+						<</if>>
+					<</for>>
+				</div>
+			<!-- "Sprays" style (up to 7 sprays, or 5 if renderer is "both") -->
+			<<else>>
+				<<for _i to 1; _i lte $spraymax; _i++>>
+					<<if $spray gte _i>>
+						<img src="img/ui/pepperspray.png">
+					<<else>>
+						<img src="img/ui/emptyspray.png">
+					<</if>>
+				<</for>>
+			<</if>>
+		</div>
+	<</if>>
+<</widget>>
diff --git a/game/base-system/overlays/options.twee b/game/base-system/overlays/options.twee
index 146f99c526..9996892796 100644
--- a/game/base-system/overlays/options.twee
+++ b/game/base-system/overlays/options.twee
@@ -60,6 +60,12 @@
 	<label><<radiovar "$options.sidebarRenderer" "both">><<updatesidebarimg>><</radiovar>> Both</label>
 	<br>
 
+	Pepper sprays display:
+	<label><<radiovar "$options.pepperSprayDisplay" "sprays">><<updatesidebarimg>><</radiovar>> Sprays</label> |
+	<label><<radiovar "$options.pepperSprayDisplay" "compact">><<updatesidebarimg>><</radiovar>> Compact (dots)</label> |
+	<label><<radiovar "$options.pepperSprayDisplay" "none">><<updatesidebarimg>><</radiovar>> None</label>
+	<br>
+
 	Closed sidebar stats:
 	<label><<radiobutton "$options.sidebarStats" "disabled" autocheck>> Disabled</label> |
 	<label><<radiobutton "$options.sidebarStats" "limited" autocheck>> Limited to important only</label> |
@@ -223,4 +229,4 @@
 	<<button "Fix stuck animations">>
 		<<run fixStuckAnimations()>>
 	<</button>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/modules/css/base.css b/modules/css/base.css
index 254490190f..ecfcd2d6cd 100644
--- a/modules/css/base.css
+++ b/modules/css/base.css
@@ -1165,10 +1165,10 @@ body.has-images #story-caption #storyCaptionDiv {
 
 body.has-images #storyCaptionContent {
 	position: fixed;
-	top: calc(232px + 1.32em);
+	top: calc(197px + 1.32em);
 	left: 10px;
 	width: 268px;
-	height: calc(100% - 246px - 1.32em);
+	height: calc(100% - 209px - 1.32em);
 	padding-right: 2px;
 	padding-bottom: 12px;
 	overflow-y: scroll;
@@ -1182,8 +1182,8 @@ body.has-images #storyCaptionContent {
 } */
 
 #storyCaptionDiv.statsExtended > #storyCaptionContent {
-	top: calc(232px + 2.64em);
-	height: calc(100% - 246px - 2.64em);
+	top: calc(197px + 2.64em);
+	height: calc(100% - 209px - 2.64em);
 }
 
 #story-caption {
@@ -1419,7 +1419,7 @@ span.suit {
 	border-bottom: var(--150) 2px solid;
 	padding-top: 1px;
 	position: fixed;
-	top: 228px;
+	top: 192px;
 	left: 0px;
 	background-color: var(--850);
 	z-index: 1000;
@@ -1452,7 +1452,7 @@ span.suit {
 }
 
 #img {
-	height: 256px;
+	height: 192px;
 	width: 256px;
 	overflow: hidden;
 	position: fixed;
@@ -1488,7 +1488,7 @@ span.suit {
 	top: 0;
 	left: 0;
 	width: 100%;
-	height: 250px;
+	height: 192px;
 
 	isolation: isolate;
 	background-color: var(--000);
@@ -1663,55 +1663,6 @@ span.suit {
 	top: 0%;
 }
 
-#spray1 {
-	position: fixed;
-	left: 0px;
-	top: 192px;
-	z-index: 10;
-}
-
-#spray2 {
-	position: fixed;
-	left: 13px;
-	top: 192px;
-	z-index: 10;
-}
-
-#spray3 {
-	position: fixed;
-	left: 27px;
-	top: 192px;
-	z-index: 10;
-}
-
-#spray4 {
-	position: fixed;
-	left: 42px;
-	top: 192px;
-	z-index: 10;
-}
-
-#spray5 {
-	position: fixed;
-	left: 56px;
-	top: 192px;
-	z-index: 10;
-}
-
-#spray6 {
-	position: fixed;
-	left: 68px;
-	top: 192px;
-	z-index: 10;
-}
-
-#spray7 {
-	position: fixed;
-	left: 80px;
-	top: 192px;
-	z-index: 10;
-}
-
 #childrenToysUI {
 	display: flex;
 	flex-wrap: wrap;
@@ -6666,7 +6617,7 @@ canvas {
 }
 
 #customOverlayTitle > button {
-  flex: 1 1 max-content;
+	flex: 1 1 max-content;
 }
 
 .dance_box{
@@ -6678,4 +6629,47 @@ canvas {
 	position: relative;
 	display: inline;
 	top: 10px;
-}
\ No newline at end of file
+}
+
+.pepper-sprays {
+	position: fixed !important;
+	left: unset !important;
+	top: 154px !important;
+	right: calc(100% - 278px);
+	display: inline-flex;
+	flex-direction: row-reverse;
+}
+
+.pepper-sprays img {
+	margin-left: -1px;
+}
+
+.pepper-sprays-dots {
+	display: flex;
+	max-width: 64px;
+	height: 32px;
+	flex-direction: row-reverse;
+	flex-wrap: wrap-reverse;
+	align-content: center;
+}
+
+.pepper-sprays-dots > div {
+	width: 6px;
+	height: 6px;
+	border: 2px solid #111D;
+	border-radius: 6px;
+	margin-left: 1px;
+	margin-top: 1px;
+}
+
+.pepper-spray-dot-empty {
+	background-color: #8884;
+}
+
+.pepper-spray-dot-full {
+	background-color: #822;
+}
+
+.offset-sidebar-img {
+	top: -4px !important;
+}
-- 
GitLab


From 619ce3508e6aa704eb7bdb05e84041bd8f6280e5 Mon Sep 17 00:00:00 2001
From: note leven <21133-noteleven@users.noreply.gitgud.io>
Date: Sat, 24 Sep 2022 22:07:57 +0000
Subject: [PATCH 45/50] fixes

---
 game/03-JavaScript/alias2.js           | 17 +++++++++++++
 game/03-JavaScript/debugMenu.js        | 34 +++++++++++++-------------
 game/03-JavaScript/sexShopMenu.js      | 18 ++++++--------
 game/04-Variables/npcNamed.twee        |  3 ++-
 game/overworld-town/loc-home/rent.twee |  2 +-
 5 files changed, 44 insertions(+), 30 deletions(-)
 create mode 100644 game/03-JavaScript/alias2.js

diff --git a/game/03-JavaScript/alias2.js b/game/03-JavaScript/alias2.js
new file mode 100644
index 0000000000..aca9815708
--- /dev/null
+++ b/game/03-JavaScript/alias2.js
@@ -0,0 +1,17 @@
+/* simple alias C.npc.Robin => V.NPCName[V.NPCNameList.indexOf("Robin")]
+ * `C.npc.Black Hawk` won't work however, use `C.npc["Great Wolf"]` instead
+ * run this after V.NPCName exists */
+function initCNPC() {
+	C.npc = {};
+	for (const name of V.NPCNameList) {
+		Object.defineProperty(C.npc, name, {
+			get() {
+				return V.NPCName[V.NPCNameList.indexOf(name)];
+			},
+			set(val) {
+				return (V.NPCName[V.NPCNameList.indexOf(name)] = val);
+			},
+		});
+	}
+}
+window.initCNPC = initCNPC;
diff --git a/game/03-JavaScript/debugMenu.js b/game/03-JavaScript/debugMenu.js
index d9f00adf49..c15fbd9e70 100644
--- a/game/03-JavaScript/debugMenu.js
+++ b/game/03-JavaScript/debugMenu.js
@@ -121,7 +121,7 @@ setup.debugMenu.eventList = {
 		{
 			link: [`Roll Over`, stayOnPassageFn],
 			widgets: [() => `<<set $position to ` + (V.position === "doggy" ? "doggy" : "missionary") + `>>`],
-			condition: () => (V.position === "doggy" || V.position === "missionary" ? 1 : 0),
+			condition() { return (V.position === "doggy" || V.position === "missionary" ? 1 : 0) },
 		},
 		{
 			link: [`RNG 1`, stayOnPassageFn],
@@ -317,7 +317,7 @@ setup.debugMenu.eventList = {
 		},
 		{
 			text_only: `\nVaginal Pregnancy<br>(New Pregnancy will only occur if not pregnant)\n`,
-			condition: () => V.pregnancyTesting,
+			condition() { return V.pregnancyTesting },
 		},
 		{
 			link: [`Get Pregnant with humans`, stayOnPassageFn],
@@ -330,7 +330,7 @@ setup.debugMenu.eventList = {
 					}
 				},
 			],
-			condition: () => V.pregnancyTesting,
+			condition() { return V.pregnancyTesting },
 		},
 		{
 			link: [`Get Pregnant with wolves`, stayOnPassageFn],
@@ -343,17 +343,17 @@ setup.debugMenu.eventList = {
 					}
 				},
 			],
-			condition: () => V.pregnancyTesting,
+			condition() { return V.pregnancyTesting },
 		},
 		{
 			link: [`Get Robin Pregnant with PCs children`, stayOnPassageFn],
 			widgets: [`<<set _sperm to ["pc"]>>`, `<<humanPregnancy "Robin" "pc" true>>`],
-			condition: () => V.pregnancyTesting,
+			condition() { return V.pregnancyTesting },
 		},
 		{
 			link: [`Get Bailey Pregnant with Black wolf`, stayOnPassageFn],
 			widgets: [`<<set _sperm to ["Black Wolf"]>>`, `<<wolfPregnancy "Bailey" "Black Wolf" true>>`],
-			condition: () => V.pregnancyTesting,
+			condition() { return V.pregnancyTesting },
 		},
 		{
 			link: [`Enable Debug Lines`, stayOnPassageFn],
@@ -914,27 +914,27 @@ setup.debugMenu.eventList = {
 		{
 			link: [`Default allure`, stayOnPassageFn],
 			widgets: [`<<set $alluretest to 0>>`],
-			condition: () => V.alluretest >= 1,
+			condition() { return V.alluretest >= 1; },
 		},
 		{
 			link: [`Become Alluring`, stayOnPassageFn],
 			widgets: [`<<set $alluretest to 1>>`],
-			condition: () => V.alluretest < 1,
+			condition() { return V.alluretest < 1 },
 		},
 		{
 			link: [`Become Unalluring`, stayOnPassageFn],
 			widgets: [`<<set $alluretest to 2>>`],
-			condition: () => V.alluretest < 1,
+			condition() { return V.alluretest < 1 },
 		},
 		{
 			link: [`Hide`, stayOnPassageFn],
 			widgets: [`<<dontHideRevert>>`],
-			condition: () => V.dontHide,
+			condition() { return V.dontHide; },
 		},
 		{
 			link: [`Don't hide`, stayOnPassageFn],
 			widgets: [`<<dontHideForNow>>`],
-			condition: () => !V.dontHide,
+			condition() { return !V.dontHide },
 		},
 		{
 			text_only: "\n\n",
@@ -1821,10 +1821,10 @@ function checkEventCondition() {
 		for (const section of ["Character", "Events", "Favourites", "Main"]) {
 			const ev = setup.debugMenu.eventList[section];
 			for (const i in ev) {
-				if (ev[i].hasOwnProperty("condition")) {
+				if (Object.hasOwn(ev[i], "condition")) {
 					if (
-						(typeof ev[i].condition === "function" && ev[i].condition() === 1) ||
-						(typeof ev[i].condition !== "function" && ev[i].condition === 1)
+						(typeof ev[i].condition === "function" && ev[i].condition()) ||
+						(typeof ev[i].condition !== "function" && ev[i].condition)
 					) {
 						if (document.getElementById(section + "-" + i) == null) return;
 						document.getElementById(section + "-" + i).classList.remove("condhide");
@@ -1916,7 +1916,7 @@ function submitNewDebugPassage() {
 	}
 	for (const section of ["Character", "Events", "Favourites", "Main"]) {
 		for (const ev of setup.debugMenu.eventList[section]) {
-			if (ev.hasOwnProperty("link") && ev.link[0] === inputList[0].value) {
+			if (Object.hasOwn(ev, "link") && ev.link[0] === inputList[0].value) {
 				inputList[0].setCustomValidity("This event title already exists. It needs to be unique!");
 				inputList[0].reportValidity();
 				document.getElementById("debugAddResult").innerHTML = "";
@@ -1947,7 +1947,7 @@ window.submitNewDebugPassage = submitNewDebugPassage;
 function syncDebugAddedEvents() {
 	if (V.debug_custom_events == null) V.debug_custom_events = { Main: [], Character: [], Events: [] };
 	for (const section of ["Main", "Character", "Events"]) {
-		if (V.debug_custom_events.hasOwnProperty(section) === false) V.debug_custom_events[section] = [];
+		if (Object.hasOwn(V.debug_custom_events, section) === false) V.debug_custom_events[section] = [];
 		for (const ev of V.debug_custom_events[section]) setup.debugMenu.eventList[section].unshift(ev);
 	}
 }
@@ -1961,7 +1961,7 @@ function removeDebugCustomPassage() {
 			if (V.debug_custom_events[section][ev].link[0] === selectedForRemoval) V.debug_custom_events[section].splice(ev, 1);
 			for (const ev2 in setup.debugMenu.eventList[section]) {
 				if (
-					setup.debugMenu.eventList[section][ev2].hasOwnProperty("link") &&
+					Object.hasOwn(setup.debugMenu.eventList[section][ev2], "link") &&
 					setup.debugMenu.eventList[section][ev2].link[0] === selectedForRemoval
 				) {
 					setup.debugMenu.eventList[section].splice(ev2, 1);
diff --git a/game/03-JavaScript/sexShopMenu.js b/game/03-JavaScript/sexShopMenu.js
index 13de9184b5..8da1fdd411 100644
--- a/game/03-JavaScript/sexShopMenu.js
+++ b/game/03-JavaScript/sexShopMenu.js
@@ -489,7 +489,7 @@ function sexShopOnItemClick(index) {
 				</a> (<span class="gold">£` +
 			  item.cost / 100 +
 			  `</span>)`
-			: `<span class="ssm_not_enough_money">Not enough money</span>`) +
+			: `<span class="ssm_not_enough_money">Not enough money</span> (<span class="gold">£${item.cost / 100}</span>)`) +
 		(item.type.includes("strap-on") ? determineRecipient(item.index) : "") +
 		`</div>
 			</div>
@@ -512,11 +512,7 @@ function determineRecipient(index) {
 	if (V.money < item.cost + 15 * 100) return "";
 
 	for (const li of ["Alex", "Eden", "Kylar", "Robin", "Sydney"]) {
-		if (
-			V.loveInterest.primary === li ||
-			V.loveInterest.secondary === li ||
-			V.loveInterest.tertiary === li
-		) {
+		if (isLoveInterest(li)) {
 			optionBuilder += `<option value="${li}">${li}</option>`;
 		}
 	}
@@ -635,11 +631,11 @@ function sexShopOnBuyClick(index) {
 		sexShopOnBuyClick.counter = setTimeout(function () {
 			if (document.getElementById("ssmBuyButton"))
 				document.getElementById("ssmBuyButton").outerHTML =
-					`<a id="ssmBuyButton" onclick="window.sexShopOnBuyClick(` +
-					index +
-					`)" class="ssm_buy_button ssm_fade_in_fast">
-			Buy it
-		</a>`;
+					V.money > item.cost
+						? `<a id="ssmBuyButton" onclick="window.sexShopOnBuyClick(` +
+						  index +
+						  `)" class="ssm_buy_button ssm_fade_in_fast">Buy it</a>`
+						: `<span class="ssm_not_enough_money">Not enough money</span>`;
 			sexShopOnBuyClick.counter = "off";
 		}, 1400);
 	}
diff --git a/game/04-Variables/npcNamed.twee b/game/04-Variables/npcNamed.twee
index 51e52de82c..04fd6ab28e 100644
--- a/game/04-Variables/npcNamed.twee
+++ b/game/04-Variables/npcNamed.twee
@@ -42,6 +42,7 @@
 <<set $NPCName = [_n1, _n2, _n3, _n4, _n5, _n6, _n7, _n8, _n9, _n10, _n11, _n12, _n13, _n14, _n15, _n16, _n17, _n18, _n19, _n20, _n21, _n22, _n23, _n24, _n25, _n26, _n27, _n28, _n29]>>
 
 <<set $NPCNameList to ["Avery","Bailey","Briar","Charlie","Darryl","Doren","Eden","Gwylan","Harper","Jordan","Kylar","Landry","Leighton","Mason","Morgan","River","Robin","Sam","Sirris","Whitney","Winter","Black Wolf","Niki","Quinn","Remy","Alex","Great Hawk","Wren","Sydney"]>>
+<<run initCNPC()>>
 
 <!-- Draft default pronoun list. Random selection is part of initNPCgender widget -->
 /% <<set _pro to ["m","f","f","m","m","m","m","m","f","f","m","m","f","m","f","m","m","m","f","m","m","m","m","m","f","m"]>> %/
@@ -358,4 +359,4 @@
 			<<set $NPCName[_args[0]].virginity.kiss to false>>
 			<<set $NPCName[_args[0]].virginity.handholding to false>>
 	<</switch>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-town/loc-home/rent.twee b/game/overworld-town/loc-home/rent.twee
index 5ed7805d9a..2a642752fe 100644
--- a/game/overworld-town/loc-home/rent.twee
+++ b/game/overworld-town/loc-home/rent.twee
@@ -214,7 +214,7 @@
 <<widget "rentRobinPunishment">>
 	You journey for some time until you feel that you're walking on grass. A small breeze flows by you. Another set of footsteps approach.
 
-	<<if !$robinPunishments.includes("docks")>>
+	<<if !$robinPunishments.includes("docks") and $debug>>/* locked behind debug until further improvements */
 		<<generate2>><<generate3>>
 		"Oh, <<nnpc_he "Robin">>'s cute. A perfect little travel companion," an unfamiliar <<person2>><<personsimple>>'s voice says.
 		<<if $NPCName[$NPCNameList.indexOf("Robin")].pronoun is $player.gender_appearance>>
-- 
GitLab


From 2fe09a994533d70b5e9e3a6b0d64e91f65e33c57 Mon Sep 17 00:00:00 2001
From: hwp <22502-hwp@users.noreply.gitgud.io>
Date: Sat, 24 Sep 2022 22:12:00 +0000
Subject: [PATCH 46/50] made englishstart a bit more modular

---
 game/overworld-town/loc-school/widgets.twee | 158 +++++++++-----------
 1 file changed, 74 insertions(+), 84 deletions(-)

diff --git a/game/overworld-town/loc-school/widgets.twee b/game/overworld-town/loc-school/widgets.twee
index 7731349d0f..a12deda5a8 100644
--- a/game/overworld-town/loc-school/widgets.twee
+++ b/game/overworld-town/loc-school/widgets.twee
@@ -1382,107 +1382,97 @@
 <</widget>>
 
 <<widget "englishstart">>
-<<endevent>>
-
-<<if $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and $kylarenglish is undefined>>
-	<<set $kylarenglish to 0>><<set $kylarenglishstate to "watching">>
-	<<npc Kylar>><<person1>>You spot Kylar sat alone in the back corner. <<He>> meets your gaze, blushes and looks away.
-	<br><br>
-
-	<<link [[Next|English Lesson]]>><<endevent>><</link>>
-	<br>
-<<elseif $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and ($kylarenglish is 0 or $kylarenglish is 3) and $NPCName[$NPCNameList.indexOf("Kylar")].love lt 30>>
-	<<set $kylarenglishstate to "watching">>
+	<<endevent>>
+	<<set _kylar to statusCheck("Kylar")>>
 
-	<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat, but <<he>> looks away whenever you glance at <<him>>.
-	<br><br>
+	<<if _kylar.state is "active">>
+		<<if $kylarenglish is 0>>
+			<<set $kylarenglishstate to "watching">>
+			<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat, but <<he>> looks away whenever you glance at <<him>>.
+			<br><br>
+			
+			<<if _kylar.love gte 30>>
+				Chair legs scrape across the ground. Kylar shuffles through the room, books clutched to <<his>> chest and eyes fixed on the empty seat beside you. <<He>> almost makes it. Then a <<generatey2>><<person2>><<person>> shoves <<person1>><<him>> aside and takes the seat for <<person2>><<himself>>.
+				<<if _kylar.love lt 60>>
+					Kylar glares at the <<person>>, but returns to <<person1>><<his>> original seat without a word.
+					<br><br>
+				<<else>>
+					<<He>> doesn't give Kylar a single glance.
+					<br><br>
 
-	<<link [[Next|English Lesson]]>><<endevent>><</link>>
-	<br>
+					Someone screams. <<person1>>Kylar remains stood, a <span class="red">knife</span> in <<his>> hand. <<He>> glares at the <<person2>><<person>> through <<person1>><<his>> dark fringe. The <<person2>><<person>> scrambles backwards over the desk, knocking it over and tumbling to the ground. The other students fall over each other trying to reach the door.
+					<br><br>
 
-<<elseif $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and ($kylarenglish is 0 or $kylarenglish is 3) and $NPCName[$NPCNameList.indexOf("Kylar")].love lt 60>>
-	<<set $kylarenglishstate to "watching">>
+					<<npc Doren 3>><<person3>>
+					Doren leaps onto <<his>> table and roars. The screams stop. The scrambling stops. Kylar drops the knife. Everyone stares at Doren, who climbs down and scoops up the weapon. <<He>> grips Kylar's arm. "You're being a right pain," <<he>> says. "Come on, let's not delay the class long." Kylar hangs <<person1>><<his>> head as <<hes>> pulled from the room.
+					<br><br>
 
-	<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat, but <<he>> looks away whenever you glance at <<him>>.
-	<br><br>
+					The class breaks into nervous laughter as the door shuts. Doren soon returns, without Kylar. Students pester <<him>> for information, but <<he>> won't say a word.
+					<br><br>
+					<<if $loveInterest.primary is "None">>
+						<<set $loveInterest.primary to "Kylar">>
+						<span class="gold">Kylar is now your love interest! You aren't sure if you agreed to this.</span>
+						<br><br>
+					<<else>>
+						<span class="gold">Kylar can now be claimed as your love interest! You aren't sure if you agreed to this. <br>You can change your love interest in the "Attitudes" menu.</span>
+						<br><br>
+					<</if>>
 
-	Chair legs scrape across the ground. Kylar shuffles through the room, books clutched to <<his>> chest and eyes fixed on the empty seat beside you. <<He>> almost makes it. Then a <<generatey2>><<person2>><<person>> shoves <<person1>><<him>> aside and takes the seat for <<person2>><<himself>>. Kylar glares at the <<person>>, but returns to <<person1>><<his>> original seat without a word.
-	<br><br>
+					<<set $kylarenglish to 1>>
+					<<set $kylarenglishstate to "absent">>
+				<</if>>
+			<</if>>
+		<<elseif $kylarenglish is 1>>
+			<<if _kylar.love gte 60>>
+				<<set $kylarenglish to 2>><<set $kylarenglishstate to "active">>
 
-	<<link [[Next|English Lesson]]>><<endevent>><</link>>
-	<br>
+				<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat. <<He>> stands and walks across the classroom, eyes fixed on the desk beside you.
+				No one stops <<him>>.
+				<<His>> breathing is heavy as <<he>> sits.
+				<br><br>
 
-<<elseif $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and ($kylarenglish is 0 or $kylarenglish is 3) and $NPCName[$NPCNameList.indexOf("Kylar")].love gte 60>>
-	<<set $kylarenglishstate to "absent">>
+				<<set $_specialOptions to true>>
+				<<link [[Sit somewhere else|English Kylar Move]]>><<npcincr Kylar love -5>><</link>><<lllove>>
+				<br>
+				<<link [[Stay seated|English Lesson]]>><<endevent>><<npcincr Kylar love 1>><<npcincr Kylar rage -1>><</link>><<glove>><<lksuspicion>>
+				<br>
+			<<else>>
+				<<set $kylarenglishstate to "absent">>
+			<</if>>
 
-	<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat, but <<he>> looks away whenever you glance at <<him>>.
-	<br><br>
+		<<elseif $kylarenglish is 2>>
+			<<if _kylar.love gte 60>>
+				<<set $kylarenglishstate to "active">>
 
-	Chair legs scrape across the ground. Kylar shuffles through the room, books clutched to <<his>> chest and eyes fixed on the empty seat beside you. <<He>> almost makes it. A <<generatey2>><<person2>><<person>> shoves <<person1>><<him>> aside and takes the seat for <<person2>><<himself>>. <<He>> doesn't give Kylar a single glance.
-	<br><br>
+				<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat. <<He>> stands and walks across the classroom, eyes fixed on the desk beside you.
+				<<His>> breathing is heavy as <<he>> sits.
+				<br><br>
 
-	Someone screams. <<person1>>Kylar remains stood, a <span class="red">knife</span> in <<his>> hand. <<He>> glares at the <<person2>><<person>> through <<person1>><<his>> dark fringe. The <<person2>><<person>> scrambles backwards over the desk, knocking it over and tumbling to the ground. The other students fall over each other trying to reach the door.
-	<br><br>
+				<<set $_specialOptions to true>>
+				<<link [[Sit somewhere else|English Kylar Move]]>><<npcincr Kylar love -5>><</link>><<lllove>>
+				<br>
+				<<link [[Stay seated|English Lesson]]>><<endevent>><<npcincr Kylar love 1>><<npcincr Kylar rage -1>><</link>><<glove>><<lksuspicion>>
+				<br>
 
-	Doren leaps onto <<nnpc_his "Doren">> table and roars. The screams stop. The scrambling stops. Kylar drops the knife. Everyone stares at Doren, who climbs down and scoops up the weapon. <<nnpc_He "Doren">> grips Kylar's arm. "You're being a right pain," <<nnpc_he "Doren">> says. "Come on, let's not delay the class long." Kylar hangs <<person1>><<his>> head as <<hes>> pulled from the room.
-	<br><br>
+			<<else>>
+				<<set $kylarenglishstate to "watching">>
 
-	<<endevent>><<npc Doren>><<person1>>
-	The class breaks into nervous laughter as the door shuts. Doren soon returns, without Kylar. Students pester <<him>> for information, but <<he>> won't say a word.
-	<br><br>
-	<<if $kylarenglish is 0>>
-		<<if $loveInterest.primary is "None">>
-			<<set $loveInterest.primary to "Kylar">>
-			<span class="gold">Kylar is now your love interest! You aren't sure if you agreed to this.</span>
-			<br><br>
+				<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat, but <<he>> looks away whenever you glance at <<him>>.
+				<br><br>
+			<</if>>
 		<<else>>
-			<span class="gold">Kylar can now be claimed as your love interest! You aren't sure if you agreed to this. <br>You can change your love interest in the "Attitudes" menu.</span>
+			<<set $kylarenglish to 0>><<set $kylarenglishstate to "watching">>
+			You spot Kylar sat alone in the back corner. <<nnpc_He "Kylar">> meets your gaze, blushes and looks away.
 			<br><br>
 		<</if>>
+	<<else>>
+		<<set $kylarenglishstate to "absent">>
 	<</if>>
 
-	<<set $kylarenglish to 1>>
-	<<link [[Next|English Lesson]]>><<endevent>><</link>>
-	<br>
-
-<<elseif $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and $kylarenglish is 1 and $NPCName[$NPCNameList.indexOf("Kylar")].love gte 60>>
-	<<set $kylarenglish to 2>><<set $kylarenglishstate to "active">>
-
-	<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat. <<He>> stands and walks across the classroom, eyes fixed on the desk beside you. No one stops <<him>>. <<His>> breathing is heavy as <<he>> sits.
-	<br><br>
-
-	<<link [[Sit somewhere else|English Kylar Move]]>><<npcincr Kylar love -5>><</link>><<lllove>>
-	<br>
-	<<link [[Stay seated|English Lesson]]>><<endevent>><<npcincr Kylar love 1>><<npcincr Kylar rage -1>><</link>><<glove>><<lksuspicion>>
-	<br>
-
-<<elseif $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and $kylarenglish is 2 and $NPCName[$NPCNameList.indexOf("Kylar")].love gte 60>>
-	<<set $kylarenglishstate to "active">>
-
-	<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat. <<He>> stands and walks across the classroom, eyes fixed on the desk beside you. <<His>> breathing is heavy as <<he>> sits.
-	<br><br>
-
-	<<link [[Sit somewhere else|English Kylar Move]]>><<npcincr Kylar love -5>><</link>><<lllove>>
-	<br>
-	<<link [[Stay seated|English Lesson]]>><<endevent>><<npcincr Kylar love 1>><<npcincr Kylar rage -1>><</link>><<glove>><<lksuspicion>>
-	<br>
-
-<<elseif $NPCName[$NPCNameList.indexOf("Kylar")].state is "active" and $kylarenglish is 2>>
-	<<set $kylarenglishstate to "watching">>
-
-	<<npc Kylar>><<person1>>You feel Kylar stare at you as you take your seat, but <<he>> looks away whenever you glance at <<him>>.
-	<br><br>
-
-	<<link [[Next|English Lesson]]>><<endevent>><</link>>
-	<br>
-
-<<else>>
-	<<set $kylarenglishstate to "absent">>
-
-	<<link [[Next|English Lesson]]>><<endevent>><</link>>
-	<br>
-
-<</if>>
+	<<if !$_specialOptions>>
+		<<link [[Next|English Lesson]]>><<endevent>><</link>>
+		<br>
+	<</if>>
 <</widget>>
 
 :: Widgets Events History [widget]
-- 
GitLab


From 92a2e9bf1ddd1384d7d9d2fd2f8ec5e1a2d7c6b5 Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Sun, 25 Sep 2022 00:26:16 +0100
Subject: [PATCH 47/50] Correct ize to ise where applicable

---
 game/base-debug/test encounters.twee           | 2 +-
 game/base-system/mirror.twee                   | 2 +-
 game/base-system/pregnancy/events.twee         | 2 +-
 game/overworld-town/loc-hospital/pharmacy.twee | 2 +-
 game/overworld-town/loc-prison/canteen.twee    | 2 +-
 game/overworld-town/special-kylar/manor.twee   | 4 ++--
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/game/base-debug/test encounters.twee b/game/base-debug/test encounters.twee
index a1623b1286..8443f71283 100644
--- a/game/base-debug/test encounters.twee	
+++ b/game/base-debug/test encounters.twee	
@@ -1378,7 +1378,7 @@ A terminal is attached to the tube.
 	<<straponGeneratorOptions>>
 	</span>
 
-	<<button "<i>Randomize</i>">>
+	<<button "<i>Randomise</i>">>
 		<<set _straponSize to [2,3,4].random()>>
 		<<set _straponColour to ["black","red","pink","purple","fleshy","blue","green"].random()>>
 		<<set _straponShape to ["dildo","penis","beaded dildo","horse cock","knotted cock","tentacle","dolphin cock","studded cock","fist dildo"].random()>>
diff --git a/game/base-system/mirror.twee b/game/base-system/mirror.twee
index c2c0cc0dd4..9ba4c2008e 100644
--- a/game/base-system/mirror.twee
+++ b/game/base-system/mirror.twee
@@ -1146,7 +1146,7 @@ __Hair__
 		<<set $hairtype to "default">>
 		<<set $fringetype to "default">>
 	<</link>> |
-	<<link [[Randomize|$passage]]>>
+	<<link [[Randomise|$passage]]>>
 		<<set _hairType to Object.values(_hairTypeByName)>>
 		<<set $hairtype to _hairType[random(0,_hairType.length - 1)]>>
 		<<set _fringeType to Object.values(_fringeTypeByName)>>
diff --git a/game/base-system/pregnancy/events.twee b/game/base-system/pregnancy/events.twee
index 0ae98bb7cb..37acc08ca9 100644
--- a/game/base-system/pregnancy/events.twee
+++ b/game/base-system/pregnancy/events.twee
@@ -406,7 +406,7 @@ Following the directions from Doctor Harper, you get into position and attempt t
 :: Harper Parasite Book
 <<effects>>
 <<set $sexStats.anus.pregnancy.book to 2>>
-Harper nods approvingly. "It's good that you want to know more." <<He>> brings out a rather thick book and shows it to you. "This is a popular reference guide among scientists. It has a lot of information on this subject, but it's property of the hospital. I'm not authorized to lend it out."
+Harper nods approvingly. "It's good that you want to know more." <<He>> brings out a rather thick book and shows it to you. "This is a popular reference guide among scientists. It has a lot of information on this subject, but it's property of the hospital. I'm not authorised to lend it out."
 <br><br>
 
 <<He>> thinks for a few seconds. "<span class="gold">The pet shop on High Street may have something.</span> If nothing else, you could pick up a notebook and fill out info you gather yourself."
diff --git a/game/overworld-town/loc-hospital/pharmacy.twee b/game/overworld-town/loc-hospital/pharmacy.twee
index 489cb8eb4e..3ee2d193c0 100644
--- a/game/overworld-town/loc-hospital/pharmacy.twee
+++ b/game/overworld-town/loc-hospital/pharmacy.twee
@@ -189,7 +189,7 @@ An assortment of colourful contact lenses is displayed behind the glass. You can
 :: Pharmacy Ask If Lenses Delivered
 <<if $left_before_nurse_returned is 1>>
 	"Hello how can I he-", <<he>> frowns, "Don't you think I forgot last time. It's not cool, you can't just send me looking for your package and just leave. Don't do that again please."
-	<br>You apologize, and <<he>> then goes check if your package arrived.
+	<br>You apologise, and <<he>> then goes check if your package arrived.
 <<elseif $left_before_nurse_returned is 2>>
 	"Who do we have here," says the nurse a rictus on <<his>> face, "Get out, you wasted enough of my time already. Try again tomorrow if you're done with your little game."
 	<<set $left_before_nurse_returned to 3>>
diff --git a/game/overworld-town/loc-prison/canteen.twee b/game/overworld-town/loc-prison/canteen.twee
index 5ad8406a5e..4462820fcd 100644
--- a/game/overworld-town/loc-prison/canteen.twee
+++ b/game/overworld-town/loc-prison/canteen.twee
@@ -335,7 +335,7 @@ You bow your head, but pay no attention to <<methodical_guard 0 apo>> words.
 	<<elseif isLoveInterest("Great Hawk")>>
 		You think about the great hawk. <<nnpc_He "Great Hawk">> must be watching for you, but you doubt <<nnpc_he "Great Hawk">> would search this far.
 	<<else>>
-		You think about the town, and realize how much of it you took for granted.
+		You think about the town, and realise how much of it you took for granted.
 	<</if>>
 <<else>>
 	<<if $rng gte 81>>
diff --git a/game/overworld-town/special-kylar/manor.twee b/game/overworld-town/special-kylar/manor.twee
index aa29189a13..72a2c71d3d 100644
--- a/game/overworld-town/special-kylar/manor.twee
+++ b/game/overworld-town/special-kylar/manor.twee
@@ -277,7 +277,7 @@ In front of you stands a bizarre monstrance, almost as tall as you. Numerous spi
 "Wh-what is it?" Kylar asks.
 <br><br>
 <<if $history gte 600>>
-	<span class="green">You recognize it from history class.</span> "It's a host for sacramental bread," you explain. <span class="gold">"The temple might know more about this one."</span>
+	<span class="green">You recognise it from history class.</span> "It's a host for sacramental bread," you explain. <span class="gold">"The temple might know more about this one."</span>
 	<br><br>
 <<else>>
 	<span class="red">You're not quite sure yourself.</span> "It's some kind of religious thing," you say. <span class="gold">"Maybe the temple will know more."</span>
@@ -698,4 +698,4 @@ You're not sure if one, or both, are beneath the bed, but you sit atop it and ta
 You walk to the manor together. Kylar gives you a hug before sitting at <<his>> computer.
 <br><br>
 
-<<kylaroptions>>
\ No newline at end of file
+<<kylaroptions>>
-- 
GitLab


From 387a8a61e14c4502a019700a5245e0484479ecb8 Mon Sep 17 00:00:00 2001
From: ChexAndBalances <34724-ChexAndBalances@users.noreply.gitgud.io>
Date: Sun, 25 Sep 2022 17:52:21 +0000
Subject: [PATCH 48/50] Grammar fixes

---
 game/base-combat/ejaculation-sydney.twee      |  6 ++---
 game/base-combat/speech.twee                  |  4 ++--
 game/base-debug/sceneViewer.twee              |  4 ++--
 game/base-system/bodywriting.twee             |  2 +-
 game/base-system/pregnancy/children.twee      |  4 ++--
 .../overworld-forest/loc-cabin/christmas.twee |  4 ++--
 game/overworld-forest/loc-cabin/events.twee   |  4 ++--
 .../overworld-forest/loc-cabin/halloween.twee |  2 +-
 game/overworld-forest/loc-cabin/main.twee     | 20 ++++++++--------
 game/overworld-forest/loc-lake/widgets.twee   |  2 +-
 game/overworld-forest/loc-wolfpack/hunts.twee |  2 +-
 game/overworld-plains/loc-farm/events.twee    |  6 ++---
 game/overworld-plains/loc-farm/woodland.twee  |  4 ++--
 .../overworld-plains/loc-livestock/intro.twee |  8 +++----
 game/overworld-town/loc-adultshop/events.twee |  2 +-
 .../overworld-town/loc-adultshop/widgets.twee |  6 ++---
 game/overworld-town/loc-arcade/main.twee      |  2 +-
 game/overworld-town/loc-docks/main.twee       |  2 +-
 game/overworld-town/loc-home/main.twee        |  2 +-
 game/overworld-town/loc-museum/main.twee      |  2 +-
 game/overworld-town/loc-park/robin.twee       |  2 +-
 game/overworld-town/loc-school/hallways.twee  |  4 ++--
 game/overworld-town/loc-school/widgets.twee   |  2 +-
 game/overworld-town/loc-shop/petShop.twee     |  4 ++--
 game/overworld-town/loc-street/events.twee    |  2 +-
 game/overworld-town/loc-temple/main.twee      |  2 +-
 .../loc-temple/soup-kitchen.twee              |  2 +-
 .../special-robin/crossdressing.twee          | 24 +++++++++----------
 game/overworld-town/special-robin/flirt.twee  |  4 ++--
 .../special-robin/lemonade.twee               |  4 ++--
 game/overworld-town/special-robin/main.twee   |  8 +++----
 game/overworld-town/special-robin/walk.twee   |  2 +-
 .../overworld-town/special-robin/widgets.twee |  6 ++---
 game/overworld-town/special-sydney/main.twee  |  4 ++--
 game/overworld-town/special-whitney/main.twee |  6 ++---
 .../special-whitney/street.twee               |  4 ++--
 .../loc-cave/widgets.twee                     |  2 +-
 .../loc-sewers/old-sewers-events.twee         |  4 ++--
 game/special-dance/effects.twee               |  2 +-
 game/special-masturbation/effects.twee        |  2 +-
 game/special-masturbation/main.twee           |  2 +-
 41 files changed, 90 insertions(+), 90 deletions(-)

diff --git a/game/base-combat/ejaculation-sydney.twee b/game/base-combat/ejaculation-sydney.twee
index fe3d9196fd..9c090e3b81 100644
--- a/game/base-combat/ejaculation-sydney.twee
+++ b/game/base-combat/ejaculation-sydney.twee
@@ -167,7 +167,7 @@
 			<<He>> moans loudly as <<he>> climaxes. "Hmph," <<he>> pouts, giving <<his>> chastity belt a useless tug.
 		<<elseif $NPCList[_nn].vagina is "vagina">>
 			<<if random(1)>>
-				<<He>> wraps <<his>> arms around you as <<he>> finishes, and you hold each other tightly as you continue to grind together. You only slow down once <<he>>'s done shaking.
+				<<He>> wraps <<his>> arms around you as <<he>> finishes, and you hold each other tightly as you continue to grind together. You only slow down once <<hes>> done shaking.
 			<<else>>
 				<<switch _sydneyStatus>>
 					<<case "pure" "pureLust">>
@@ -961,7 +961,7 @@
 		<<He>> moans loudly as <<he>> climaxes. "Hmph," <<he>> pouts, giving <<his>> chastity belt a useless tug.
 	<<elseif $NPCList[_nn].penis is "penis">>
 		<<if random(1)>>
-			<<He>> wraps <<his>> arms around you as <<he>> finishes, and you hold each other tightly as you continue to grind together. You only slow down once <<he>>'s done shaking.
+			<<He>> wraps <<his>> arms around you as <<he>> finishes, and you hold each other tightly as you continue to grind together. You only slow down once <<hes>> done shaking.
 		<<else>>
 			<<switch _sydneyStatus>>
 				<<case "pure" "pureLust">>
@@ -1479,4 +1479,4 @@
 
 	<</if>>
 <</if>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/base-combat/speech.twee b/game/base-combat/speech.twee
index 20fac1c021..2ee2ed603c 100644
--- a/game/base-combat/speech.twee
+++ b/game/base-combat/speech.twee
@@ -5243,7 +5243,7 @@
 				`Robin is crying.`,
 				`Robin frantically tries to look away from you, but <<he>> doesn't stop.`,
 				`"I d-don't..." Robin whispers under <<his>> breath.`,
-				`"I love you!" Robin says, though <<he>>'s not smiling.`,
+				`"I love you!" Robin says, though <<hes>> not smiling.`,
 				`"I just need-" Robin gasps. <<He>> doesn't try to finish <<his>> sentence.`,
 				`Robin closes <<his>> eyes, unable to meet your gaze.`,
 				`Robin cries out. Tears are running down <<his>> face.`,
@@ -5447,7 +5447,7 @@
 				<<if random(1, 2) lte 1>>
 					<<set $_text_output to `<<He>> laughs. "Did you just admit <<printTo>> fucking a dog? You're making this too easy."`>>
 				<<else>>
-					<<set $_text_output to `<<He>> laughs. "I think I need <<printTo>> remind you who's bitch you actually are."`>>
+					<<set $_text_output to `<<He>> laughs. "I think I need <<printTo>> remind you whose bitch you actually are."`>>
 				<</if>>
 			<<elseif _loveInterest is "Great Hawk">>
 				<<if random(1, 2) lte 1>>
diff --git a/game/base-debug/sceneViewer.twee b/game/base-debug/sceneViewer.twee
index 4a9cba6da9..d00765724c 100644
--- a/game/base-debug/sceneViewer.twee
+++ b/game/base-debug/sceneViewer.twee
@@ -730,7 +730,7 @@ Robin looks at the clock on the wall and sighs. "I need to get my _stand set up.
 :: Robin School CD SV Intro
 <<npc Robin>><<person1>>
 <<set _robin to statusCheck("Robin")>>
-You enter Robin's room, <<he>>'s standing in front of <<his>> mirror holding a
+You enter Robin's room, <<hes>> standing in front of <<his>> mirror holding a
 <<print (_robin.pronoun is "m" ? "girl's" : "boy's")>> school uniform in front of <<him>>.
 <<He>> seems focused on how <<he>> looks and doesn't notice you at first.
 <br><br>
@@ -765,4 +765,4 @@ You are on Wolf Street. The nearby forest bleeds into the town here, particularl
 <<streeteffects>>
 <br><br>
 
-<<monstrance_accost>>
\ No newline at end of file
+<<monstrance_accost>>
diff --git a/game/base-system/bodywriting.twee b/game/base-system/bodywriting.twee
index 3d49e0b915..945fccf5de 100755
--- a/game/base-system/bodywriting.twee
+++ b/game/base-system/bodywriting.twee
@@ -2401,7 +2401,7 @@ Second arg: tool */
 
 	<<set $_skirt to setup.clothes.lower[clothesIndex('lower', $worn.lower)].skirt>>
 	<<if ["left_bottom", "right_bottom"].includes($tattoo_bodypart)>>
-		"Alright," <<he>> says, pulling the curtain shut. "Lets see your bottom."
+		"Alright," <<he>> says, pulling the curtain shut. "Let's see your bottom."
 		<<if $worn.lower.type.includes("naked")>>
 			<<if $worn.under_lower.type.includes("naked")>>
 				You <<nervously>> turn, showing <<him>> your <<bottom>>.
diff --git a/game/base-system/pregnancy/children.twee b/game/base-system/pregnancy/children.twee
index 012a8241d7..ac8ccb4f2c 100644
--- a/game/base-system/pregnancy/children.twee
+++ b/game/base-system/pregnancy/children.twee
@@ -854,7 +854,7 @@ args[3] - "both" to include unrelated children or "only" to exclude the player c
 			<<humanChildActivityNoToy>>
 		<</if>>
 	<<case "clownHappy">>
-		<<childHe>>'s playing happily with the clown, pullings it's cord and making it chuckle every now and then.
+		<<childHe>>'s playing happily with the clown, pulling its cord and making it chuckle every now and then.
 	<<default>>
 		<<childHe>>'s has figured out that they're in a video game (This is an error, please report).
 		<<print $children[_args[0]].localVariables.activity>>
@@ -957,4 +957,4 @@ args[3] - "both" to include unrelated children or "only" to exclude the player c
 		<<childHe>>'s has figured out that they're in a video game (This is an error, please report).
 		<<print $children[_args[0]].localVariables.activity>>
 <</switch>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-forest/loc-cabin/christmas.twee b/game/overworld-forest/loc-cabin/christmas.twee
index 28f6e23f64..0c8706d5eb 100644
--- a/game/overworld-forest/loc-cabin/christmas.twee
+++ b/game/overworld-forest/loc-cabin/christmas.twee
@@ -1,7 +1,7 @@
 :: Eden Jacket
 <<set $outside to 0>><<set $location to "cabin">><<effects>>
 
-Snow falls around the cabin, painting the scenery a pure white. A distinctive winter chill settles in you, causing you to shiver. When you find Eden, <<he>>'s as busy as always.
+Snow falls around the cabin, painting the scenery a pure white. A distinctive winter chill settles in you, causing you to shiver. When you find Eden, <<hes>> as busy as always.
 You call <<him>> over and hand <<him>> the hunting jacket. "Merry Christmas," you say.
 <br><br>
 Eden looks taken aback. "Is it Christmas already?" <<he>> asks. Taking the hunting jacket, <<he>> turns it over and inspects it, then goes to the cabin mirror and tries it on. Looks like you bought the right size.
@@ -47,7 +47,7 @@ You and Eden take a seat, and you try a bite of the food. It's delicious and bur
 <br><br>
 It's not usual for <<him>> to be nervous. In an attempt to reassure <<him>>, you smile and compliment <<his>> work. <<He>> looks relieved by your words, and starts eating. <<He>> still seems doubtful.
 <br><br>
-You chat with Eden over the meal, attempting to lighten the mood. <<He>>'s as quiet as always, but seems more attentive than usual today. Halfway through, <<he>> looks up, as if just remembering something. Going to a nearby cabinet, <<he>> pulls out a fancy looking bottle of bourbon. You wonder how you've never seen it in the cabin before.
+You chat with Eden over the meal, attempting to lighten the mood. <<Hes>> as quiet as always, but seems more attentive than usual today. Halfway through, <<he>> looks up, as if just remembering something. Going to a nearby cabinet, <<he>> pulls out a fancy looking bottle of bourbon. You wonder how you've never seen it in the cabin before.
 <br><br>
 <<He>> goes back to the table and prepares two glasses. "Want some?" <<he>> asks.
 <br><br>
diff --git a/game/overworld-forest/loc-cabin/events.twee b/game/overworld-forest/loc-cabin/events.twee
index 56158a05c2..b39c35990c 100644
--- a/game/overworld-forest/loc-cabin/events.twee
+++ b/game/overworld-forest/loc-cabin/events.twee
@@ -1098,7 +1098,7 @@ You nod. The two of you watch the embers crackle into the night.
 <<elseif $rng gte 40>>
 	You ask Eden about reading. "It helps pass the time," <<he>> says.
 <<elseif $rng gte 35>>
-	You ask Eden about how long <<he>>'s lived in the forest. "Some time," <<he>> says. <<He>> doesn't elaborate.
+	You ask Eden about how long <<hes>> lived in the forest. "Some time," <<he>> says. <<He>> doesn't elaborate.
 <<elseif $rng gte 30>>
 	You ask Eden about school. <<He>> shrugs. "I've always been more of a hands-on learner."
 <<elseif $rng gte 25>>
@@ -3240,7 +3240,7 @@ You and Eden inflate the raft and push it onto the water. You spend the time bas
 :: Eden View
 <<set $outside to 1>><<effects>>
 
-You and Eden sit together by the lake. <<He>> holds you close as you admire the view. It's calming, even more so that <<he>>'s here with you right now. <<ltrauma>><<lstress>><<trauma -6>><<stress -6>>
+You and Eden sit together by the lake. <<He>> holds you close as you admire the view. It's calming, even more so that <<hes>> here with you right now. <<ltrauma>><<lstress>><<trauma -6>><<stress -6>>
 <br><br>
 After a while, <<he>> stands and offers <<his>> hand to you. "I think that's enough downtime for today," <<he>> says.
 <br><br>
diff --git a/game/overworld-forest/loc-cabin/halloween.twee b/game/overworld-forest/loc-cabin/halloween.twee
index c98298ea50..c0dc5bfff7 100644
--- a/game/overworld-forest/loc-cabin/halloween.twee
+++ b/game/overworld-forest/loc-cabin/halloween.twee
@@ -130,7 +130,7 @@ Using your knife, you whittle away at the surface of the pumpkin.
 <</if>>
 <br><br>
 
-Stepping back from your work, you walk over to Eden to look at <<his>> creation. It seems <<he>>'s carved the image of a deer into the pumpkin. It looks quite skillfully done, no doubt from how experienced <<he>> is with <<his>> hands.
+Stepping back from your work, you walk over to Eden to look at <<his>> creation. It seems <<hes>> carved the image of a deer into the pumpkin. It looks quite skillfully done, no doubt from how experienced <<he>> is with <<his>> hands.
 <br><br>
 
 <<if $submissive gte 1150>>
diff --git a/game/overworld-forest/loc-cabin/main.twee b/game/overworld-forest/loc-cabin/main.twee
index 5780fc1a76..cde9b46043 100644
--- a/game/overworld-forest/loc-cabin/main.twee
+++ b/game/overworld-forest/loc-cabin/main.twee
@@ -890,7 +890,7 @@ You are in the clearing outside Eden's cabin. The surrounding trees are so huge
 <<elseif ($edenfreedom is 2 and $edendays gte 8 and $hour gte 6) or ($edenfreedom is 1 and $edendays gte 2 and $hour gte 6)>>
 	<<set $edendays to 0>>
 	<<npcincr Eden love -1>>
-	Eden looks up as you approach the cabin. <<He>> stops what <<he>>'s doing and rushes over to you.
+	Eden looks up as you approach the cabin. <<He>> stops what <<hes>> doing and rushes over to you.
 	<<if $edenPreyEscaped>><<unset $edenPreyEscaped>>
 		"Don't think I forgot about our game. You weren't supposed to escape me," <<he>> grumbles. "You shouldn't have been gone so long, either. Where the hell have you been?"
 	<<else>>
@@ -1062,7 +1062,7 @@ You are in the clearing outside Eden's cabin. The surrounding trees are so huge
 		<<set $edenhurt to 1>>
 		<<person1>>
 		The sudden snapping of a twig draws your attention to the treeline. Eden emerges from the forest, <<his>> clothes looking ragged and torn in various places.
-		<<His>> rifle, usually slung over <<his>> shoulder, is grasped tightly in <<his>> hand. You gasp when you see the state <<he>>'s in, and flinch when you notice the claw shaped marks covering <<his>> arms and chest.
+		<<His>> rifle, usually slung over <<his>> shoulder, is grasped tightly in <<his>> hand. You gasp when you see the state <<hes>> in, and flinch when you notice the claw shaped marks covering <<his>> arms and chest.
 		<br><br>
 
 		<<if $submissive gte 1150>>
@@ -1844,8 +1844,8 @@ After you enter the cabin, Eden shuts the door behind you and wraps you up in a
 	<br>
 	"You're hurt," <<he>> notes, pulling away and scanning you up and down.
 	<br><br>
-	Eden leads you to the dining table and treats you as best <<he>> can with a first aid kit. You notice a look of guilt on <<his>> face as <<he>> tends to you, almost as if <<he>>'s blaming <<him>>self for your injuries.
-	After <<he>>'s done, <<he>> brings you a glass of water and some painkillers, which you down in one shot. <<He>> then pulls up a chair in front of you.
+	Eden leads you to the dining table and treats you as best <<he>> can with a first aid kit. You notice a look of guilt on <<his>> face as <<he>> tends to you, almost as if <<hes>> blaming <<him>>self for your injuries.
+	After <<hes>> done, <<he>> brings you a glass of water and some painkillers, which you down in one shot. <<He>> then pulls up a chair in front of you.
 	<<lllpain>><<lltrauma>><<llstress>><<trauma -20>><<pain -200>><<stress -20>>
 	<br><br>
 <</if>>
@@ -1892,7 +1892,7 @@ You feel safe once beneath the canopy, but don't stop until you reach the cabin.
 		<<He>> applies a strange liquid to the cattle brand. The ink runs from your skin.
 		<<bodywriting_clear left_bottom>>
 	<</if>>
-	After <<he>>'s done, <<he>> brings you a glass of water and some painkillers, which you down in one shot. <<He>> pulls up a chair in front of you.
+	After <<hes>> done, <<he>> brings you a glass of water and some painkillers, which you down in one shot. <<He>> pulls up a chair in front of you.
 	<<lllpain>><<lltrauma>><<llstress>><<trauma -20>><<pain -200>><<stress -20>>
 	<br><br>
 <</if>>
@@ -2035,11 +2035,11 @@ The song leads you two into a slow waltz. You stare into Eden's eyes and feel a
 Eden seems to have trouble maintaining your gaze, but holds you tight nonetheless. You can feel the nervousness settle in <<his>> shoulders, causing them to feel stiff at your touch.
 In fact, the vulnerability of the moment seems to have exposed <<him>>, somehow. Let you see the part of <<him>> that <<he>> tries so hard to hide from the world.
 <br><br>
-You feel glad that <<he>>'s showing this to you now, even if it's through uncertain and awkward movements. Maybe, that's what makes it special.
+You feel glad that <<hes>> showing this to you now, even if it's through uncertain and awkward movements. Maybe, that's what makes it special.
 <br><br>
-<<He>>'s no expert at dancing and stumbles more than a few times, but it's nice. You're struck with the realisation that even if life with Eden isn't perfect, <<he>> is trying for you.
+<<Hes>> no expert at dancing and stumbles more than a few times, but it's nice. You're struck with the realisation that even if life with Eden isn't perfect, <<he>> is trying for you.
 <br><br>
-Like <<he>>'s trying right now.
+Like <<hes>> trying right now.
 <br><br>
 <<link [[Next|Eden Radio Intro 4]]>><<npcincr Eden love 1>><</link>>
 <br>
@@ -2482,7 +2482,7 @@ You awaken on the cabin bed. Turning your head to the side, you see Eden sitting
 <br><br>
 
 <<if $pain gte 10>>
-	It seems <<he>>'s fixed your injuries while you were out. <<He>> helps you to your feet and gives you one last look before walking off.
+	It seems <<hes>> fixed your injuries while you were out. <<He>> helps you to your feet and gives you one last look before walking off.
 	<<lllpain>><<pain -200>>
 	<br><br>
 <<else>>
@@ -2676,4 +2676,4 @@ Releasing your leash, <<he>> walks away, leaving you staring at the mirror. Your
 <<takeKissVirginity "Eden" "romantic">>
 <br><br>
 
-<<link [[Next|Eden Cabin]]>><<endevent>><</link>>
\ No newline at end of file
+<<link [[Next|Eden Cabin]]>><<endevent>><</link>>
diff --git a/game/overworld-forest/loc-lake/widgets.twee b/game/overworld-forest/loc-lake/widgets.twee
index 0de5d0056a..eb2e89af40 100644
--- a/game/overworld-forest/loc-lake/widgets.twee
+++ b/game/overworld-forest/loc-lake/widgets.twee
@@ -253,7 +253,7 @@ Someone screams. Everyone turns and backs away from the newcomer, a <<beasttype>
 			The surrounding trees are almost invisible in the dark.<<gstress>><<stress 6>>
 			<br><br>
 		<<else>>
-			You see a fox rummaging in the dirt at the lake's edge. It's ears perk, and it bounds between the trees.
+			You see a fox rummaging in the dirt at the lake's edge. Its ears perk, and it bounds between the trees.
 			<br><br>
 		<</if>>
 	<</if>>
diff --git a/game/overworld-forest/loc-wolfpack/hunts.twee b/game/overworld-forest/loc-wolfpack/hunts.twee
index 457605c668..fff0256746 100644
--- a/game/overworld-forest/loc-wolfpack/hunts.twee
+++ b/game/overworld-forest/loc-wolfpack/hunts.twee
@@ -633,7 +633,7 @@ The pack creeps up to the cave. The <<beasttypes>> eyes open, and the pack lunge
 
 <<if $wolfpackharmony + $wolfpackferocity + 20 gte $rng>>
 
-	The <<beasttype>> tries to stand, but it's too late. Several sets of jaws clamp down on it's body. It roars in pain and swipes at the attackers, but they jump back to safety.
+	The <<beasttype>> tries to stand, but it's too late. Several sets of jaws clamp down on its body. It roars in pain and swipes at the attackers, but they jump back to safety.
 	<br><br>
 
 	Groggy and hurt, the <<beasttype>> stumbles away from the cave and leaves the deer carcass unguarded. <<if $monster is 1>>"Thieving wolves... take the deer if you want it so badly!<</if>> The Black Wolf keeps the choice parts for itself. You find some berries growing nearby which serve you better.
diff --git a/game/overworld-plains/loc-farm/events.twee b/game/overworld-plains/loc-farm/events.twee
index 4181bf9958..359bb4966f 100644
--- a/game/overworld-plains/loc-farm/events.twee
+++ b/game/overworld-plains/loc-farm/events.twee
@@ -1330,7 +1330,7 @@ Alex arrives at the stable, and runs along the lane. "You okay?" <<he>> asks. "Y
 		<br><br>
 	<</if>>
 	<<if $farm.beasts.horses lte -20 and $rng gte 51>>
-		"Fuck this," the second centaur says. "Lets give <<phim>> a proper seeing to." Still holding your arms, <<farm_he horse>> lifts you into the air and throws you over a nearby fence. <<farm_He horse>> steps over you.
+		"Fuck this," the second centaur says. "Let's give <<phim>> a proper seeing to." Still holding your arms, <<farm_he horse>> lifts you into the air and throws you over a nearby fence. <<farm_He horse>> steps over you.
 		<br><br>
 
 		<<link [[Next|Farm Horse Rape]]>><<set $molestationstart to 1>><</link>>
@@ -4439,7 +4439,7 @@ You walk back to the farmhouse. Alex insists on you leading the way. Once there,
 :: Farm Race Look
 <<effects>>
 
-You look away. "What's the matter?" <<he>> asks, followed by a gasp as <<he>> notices the problem. "L-lets get back to the farmhouse," <<he>> says, <<his>> hands clamped to <<his>> crotch as a blush spreads on <<his>> face.
+You look away. "What's the matter?" <<he>> asks, followed by a gasp as <<he>> notices the problem. "L-let's get back to the farmhouse," <<he>> says, <<his>> hands clamped to <<his>> crotch as a blush spreads on <<his>> face.
 <br><br>
 
 You walk back to the farmhouse. Alex insists on you leading the way. Once there, <<he>> disappears inside, and emerges with a fresh <<if $pronoun is "f">>skirt<<else>>pair of shorts<</if>>. <<Hes>> still blushing.
@@ -4902,7 +4902,7 @@ You stagger to your feet. Alex does likewise.
 <<if $submissive gte 1150>>
 	"I-I'm fine," you say. "We can fix the farm. They haven't won yet."
 <<elseif $submissive lte 850>>
-	"Sorry for what?" you ask. "We can't let them walk all over us. Lets fix this mess."
+	"Sorry for what?" you ask. "We can't let them walk all over us. Let's fix this mess."
 <<else>>
 	"We can fix the farm," you say. "They haven't won yet."
 <</if>>
diff --git a/game/overworld-plains/loc-farm/woodland.twee b/game/overworld-plains/loc-farm/woodland.twee
index addb8ce8c2..4efff9584f 100644
--- a/game/overworld-plains/loc-farm/woodland.twee
+++ b/game/overworld-plains/loc-farm/woodland.twee
@@ -584,7 +584,7 @@ Alex jerks <<his>> head away and closes <<his>> eyes.
 	<<link [[Next|Farm Woodland Tend Alex Sex]]>><<set $sexstart to 1>><</link>>
 	<br>
 <<else>>
-	"I-I," Alex stammers while looking down. "S-sorry, I didn't..." <<He>> trails off. "L-lets just get back to work."
+	"I-I," Alex stammers while looking down. "S-sorry, I didn't..." <<He>> trails off. "L-let's just get back to work."
 	<br><br>
 
 	<<link [[Next|Farm Woodland]]>><</link>>
@@ -645,7 +645,7 @@ You smirk, toss the branch aside, and hop off the ladder. You press your body ag
 	<<link [[Next|Farm Woodland Tend Alex Sex]]>><<set $sexstart to 1>><</link>>
 	<br>
 <<else>>
-	Alex averts <<his>> gaze, then laughs. "You're quite something," <<he>> says. <<He>> clamps <<his>> hands against your <<bottom>>, pulling you against <<him>>. "I'll be good. Lets get back to work." <<He>> plants a kiss on your cheek.
+	Alex averts <<his>> gaze, then laughs. "You're quite something," <<he>> says. <<He>> clamps <<his>> hands against your <<bottom>>, pulling you against <<him>>. "I'll be good. Let's get back to work." <<He>> plants a kiss on your cheek.
 	<br><br>
 
 	<<link [[Next|Farm Woodland]]>><</link>>
diff --git a/game/overworld-plains/loc-livestock/intro.twee b/game/overworld-plains/loc-livestock/intro.twee
index dedfb960e4..5fa17a5ad9 100644
--- a/game/overworld-plains/loc-livestock/intro.twee
+++ b/game/overworld-plains/loc-livestock/intro.twee
@@ -1406,7 +1406,7 @@ You're forcefully shoved to the ground, falling to the dirt with a thud. Your pr
 You have little time to anticipate what they have in store for you, as your thoughts are interrupted by the sound of footsteps approaching.
 <br><br>
 
-"I’ll be," says a voice. It's Remy. <<nnpc_He "Remy">> squats down beside your head, <<nnpc_his "Remy">> leather boots squeaking slightly. "The little escape artist returns."<<livestock_obey -10>><<lllobey>>
+"I'll be," says a voice. It's Remy. <<nnpc_He "Remy">> squats down beside your head, <<nnpc_his "Remy">> leather boots squeaking slightly. "The little escape artist returns."<<livestock_obey -10>><<lllobey>>
 <br><br>
 
 <<link [[Next|Livestock Return Kennel 2]]>><</link>>
@@ -1431,13 +1431,13 @@ Remy nods at someone behind you, prompting several unseen hands to grasp your li
 Remy approaches one of the cages, sticking <<nnpc_his "Remy">> hand through the bars and stroking the <<beasttypes>> head. "We care for you, keep you safe and secure," Remy says. "And yet, you still defy us." You hear the jangle of iron chains behind you as Remy speaks. "Defiance is never acceptable."
 <br><br>
 
-A thick iron collar clamps around your neck from behind, connecting the short length of chain with a mounting in the ground you hadn’t noticed and rendering you immobile.
+A thick iron collar clamps around your neck from behind, connecting the short length of chain with a mounting in the ground you hadn't noticed and rendering you immobile.
 <br><br>
 
-The farmhands whisper to each other as Remy undoes the latch to the cage, swinging the door open. You hear the <<if $monster is 1>>patter of bare feet<<else>>clatter of claws<</if>> on the floor as a slew of the estate’s guard-<<beastsplural>> emerge from the kennel.
+The farmhands whisper to each other as Remy undoes the latch to the cage, swinging the door open. You hear the <<if $monster is 1>>patter of bare feet<<else>>clatter of claws<</if>> on the floor as a slew of the estate's guard-<<beastsplural>> emerge from the kennel.
 <br><br>
 
-"These poor things spent hours looking for you," Remy says, squatting down in front of you as <<nnpc_he "Remy">> playfully rubs a <<beasttypes>> head. The others circle you hungrily. "They worked so hard to find you, it’s only fair that they get rewarded for such hard work." Remy stands up and steps away from you, giving you a clear view of the <<beasttypes>> <<if $NPCList[0].penis isnot "none">>erect penis<<else>>wet pussy<</if>>.
+"These poor things spent hours looking for you," Remy says, squatting down in front of you as <<nnpc_he "Remy">> playfully rubs a <<beasttypes>> head. The others circle you hungrily. "They worked so hard to find you, it's only fair that they get rewarded for such hard work." Remy stands up and steps away from you, giving you a clear view of the <<beasttypes>> <<if $NPCList[0].penis isnot "none">>erect penis<<else>>wet pussy<</if>>.
 <br><br>
 
 Behind you, one of the <<beastsplural>> gives you a cursory sniff before mounting you.
diff --git a/game/overworld-town/loc-adultshop/events.twee b/game/overworld-town/loc-adultshop/events.twee
index 389b9885e5..58a4ab15a3 100644
--- a/game/overworld-town/loc-adultshop/events.twee
+++ b/game/overworld-town/loc-adultshop/events.twee
@@ -1251,7 +1251,7 @@ You gain <<moneyGain 40>>.
 	You nod your head in agreement.
 <</if>>
 <br><br>
-Spotting Sirris heading in your direction, <<he>> releases your arms and puts <<his>> hands around your shoulders. "Lets get out of here. There's an alleyway out back where no one will disturb us."
+Spotting Sirris heading in your direction, <<he>> releases your arms and puts <<his>> hands around your shoulders. "Let's get out of here. There's an alleyway out back where no one will disturb us."
 <br><br>
 <<link [[Go with Whitney|Adult Shop Whitney Spank Sex]]>><<set $location to "alley">><<giveNPCsextoy 0 "flog">><<npcstrapon 0>><<set $sexstart to 1>><</link>>
 
diff --git a/game/overworld-town/loc-adultshop/widgets.twee b/game/overworld-town/loc-adultshop/widgets.twee
index 420f46a41a..e9901019d6 100644
--- a/game/overworld-town/loc-adultshop/widgets.twee
+++ b/game/overworld-town/loc-adultshop/widgets.twee
@@ -529,15 +529,15 @@
 			<br><br>
 			<<person2>>
 			<<if _sydneyStatus.includes("pure")>>
-				"We don't allow product sampling but we can certainly try and help with any questions you might have." Sydney appears and picks up the _toy, "Now lets see-"
+				"We don't allow product sampling but we can certainly try and help with any questions you might have." Sydney appears and picks up the _toy, "Now let's see-"
 				Sydney's face goes red as <<he>> reads the packaging. Leaning over to you <<he>> whispers, "Is this really what this is for?"
 				<<set $phase to 0>>
 			<<elseif _sydneyStatus.includes("corrupt")>>
-				"We don't allow product sampling but we can certainly give our recommendations." Sydney appears and picks up the _toy, "Now lets see-"
+				"We don't allow product sampling but we can certainly give our recommendations." Sydney appears and picks up the _toy, "Now let's see-"
 				<<He>> smiles as <<he>> examines the _toy. Leaning over to you <<he>> whispers, "Doesn't this one look fun?" <<He>> nudges you with a wink before turning back to the customer.
 				<<set $phase to 1>>
 			<<else>>
-				"We don't allow product sampling but we can certainly help with any questions you might have." Sydney appears and picks up the _toy. "Now lets see-"
+				"We don't allow product sampling but we can certainly help with any questions you might have." Sydney appears and picks up the _toy. "Now let's see-"
 				<<He>> furrows <<his>> brow in concentration as <<he>> reads the package. Leaning over to you <<he>> whispers, "this is the maximum pleasure version, isn't it?"
 				<<set $phase to 3>>
 			<</if>>
diff --git a/game/overworld-town/loc-arcade/main.twee b/game/overworld-town/loc-arcade/main.twee
index 10b01737f3..9f3b909731 100644
--- a/game/overworld-town/loc-arcade/main.twee
+++ b/game/overworld-town/loc-arcade/main.twee
@@ -224,7 +224,7 @@ The games and gambling machines lie silent.
 			<<generate1>><<person1>>
 			You choose a beat-em-up, whacking enemies away as they approach you. As you play, you hear a small crowd form behind you. They fixate on a <<person>> playing a classic game.
 			<br><br>
-			"Wow! <<He>>'s going to beat the high score at this rate!" One of the onlookers shout, "Everyone come look!"
+			"Wow! <<Hes>> going to beat the high score at this rate!" One of the onlookers shout, "Everyone come look!"
 			<br><br>
 			<<link [[Go watch|Arcade Watch High Score]]>><<set $phase to 1>><</link>>
 			<br>
diff --git a/game/overworld-town/loc-docks/main.twee b/game/overworld-town/loc-docks/main.twee
index 1be6311a97..19c6dec9e3 100644
--- a/game/overworld-town/loc-docks/main.twee
+++ b/game/overworld-town/loc-docks/main.twee
@@ -1719,7 +1719,7 @@ You leave with your laughing colleagues.
 
 <<set $outside to 0>><<set $location to "pub">><<dockeffects>><<effects>>
 
-Your colleagues reach for the money, but you snatch it away from them. You remind them who's butt was on the line. They grumble, but agree. You've gained <<moneyGain 360>>.
+Your colleagues reach for the money, but you snatch it away from them. You remind them whose butt was on the line. They grumble, but agree. You've gained <<moneyGain 360>>.
 <br><br>
 
 You and your colleagues enjoy your free drinks and leave in an elevated mood.
diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index 2425ca75f9..59e189210c 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -3098,7 +3098,7 @@ The <<person2>><<person>> leans over to <<his>> friend. They whisper back and fo
 <<if $submissive gte 1150>>
 	"I-I'll do what you ask," you say. "J-Just don't hurt me. Please."
 <<elseif $submissive lte 850>>
-	"Look," you say. "I know how this works. I'll play along, lets just not waste any more of my time than we have to."
+	"Look," you say. "I know how this works. I'll play along, let's just not waste any more of my time than we have to."
 <<else>>
 	"I'll cooperate," you say. "Just be gentle."
 <</if>>
diff --git a/game/overworld-town/loc-museum/main.twee b/game/overworld-town/loc-museum/main.twee
index 3a6ed6794e..72cf984f99 100644
--- a/game/overworld-town/loc-museum/main.twee
+++ b/game/overworld-town/loc-museum/main.twee
@@ -400,7 +400,7 @@ You return to the museum.
 You crouch beside Winter, and ask if you should call an ambulance. <<He>> shakes <<his>> head. "I'll be up in no time. Just winded."
 <br><br>
 
-When <<he>>'s ready, you help <<him>> to <<his>> feet. <<He>> steadies <<himself>> against a pedestal. "Thank you. The police will bring our culprit to justice." <<He>> notices the slash across the leather map, and sighs.
+When <<hes>> ready, you help <<him>> to <<his>> feet. <<He>> steadies <<himself>> against a pedestal. "Thank you. The police will bring our culprit to justice." <<He>> notices the slash across the leather map, and sighs.
 <br><br>
 
 <<link [[Help Winter clean up (0:30)|Museum Attack Help]]>><<pass 30>><<npcincr Winter love 1>><<npcincr Winter dom -1>><</link>><<ldom>><<glove>>
diff --git a/game/overworld-town/loc-park/robin.twee b/game/overworld-town/loc-park/robin.twee
index a13a54deda..f18015f79c 100644
--- a/game/overworld-town/loc-park/robin.twee
+++ b/game/overworld-town/loc-park/robin.twee
@@ -192,7 +192,7 @@
 			<<set $robinparksnow to 1>>
 			A snowball hurtles through the air.
 			<<if _robin.trauma gte 40>>
-				Robin sees the snowball but freezes, only managing to flinch before <<he>>'s hit with a faceful of snow. You duck and pull <<him>> down.
+				Robin sees the snowball but freezes, only managing to flinch before <<hes>> hit with a faceful of snow. You duck and pull <<him>> down.
 				<br><br>
 				Robin wipes the snow from <<his>> face and shivers. "Let's just w-wait," <<he>> says. "They'll leave us alone eventually."
 			<<else>>
diff --git a/game/overworld-town/loc-school/hallways.twee b/game/overworld-town/loc-school/hallways.twee
index a0d2b12cb4..4c4cccdfb2 100644
--- a/game/overworld-town/loc-school/hallways.twee
+++ b/game/overworld-town/loc-school/hallways.twee
@@ -1881,7 +1881,7 @@ The pair push you back into the storage room.
 :: Hallways Exposed Storeroom Slap
 <<effects>>
 
-You slap the grin off the <<person2>><<persons>> face, and shove by. "I'm telling the head you hit me!" <<He>> shouts after you. <<His>> friend laughs, you're not sure at who.
+You slap the grin off the <<person2>><<persons>> face, and shove by. "I'm telling the head you hit me!" <<He>> shouts after you. <<His>> friend laughs, you're not sure at whom.
 <br><br>
 
 <<link [[Next|Hallways]]>><<endevent>><<set $eventskip to 1>><</link>>
@@ -1983,4 +1983,4 @@ You slap the grin off the <<person2>><<persons>> face, and shove by. "I'm tellin
 	<<fameexhibitionism 40>><<exhibitionism2>>
 	<<underlowerruined>>
 <</if>>
-<<lockereventnext>>
\ No newline at end of file
+<<lockereventnext>>
diff --git a/game/overworld-town/loc-school/widgets.twee b/game/overworld-town/loc-school/widgets.twee
index 7731349d0f..a4f85873c9 100644
--- a/game/overworld-town/loc-school/widgets.twee
+++ b/game/overworld-town/loc-school/widgets.twee
@@ -2084,7 +2084,7 @@
 		<<rng>>
 		<<if $rng gte 81>>
 			<<generates2>><<person2>>As you approach the diving platform however, a <<person>> turns.
-			You cover your body as <<he>> shouts to <<his>> friends, attracting more attention. Mason tries to control the situation, but its no use.
+			You cover your body as <<he>> shouts to <<his>> friends, attracting more attention. Mason tries to control the situation, but it's no use.
 			The whole class is soon staring at you.
 			<<gtrauma>><<trauma 2>><<gstress>><<stress 2>>
 			<br><br>
diff --git a/game/overworld-town/loc-shop/petShop.twee b/game/overworld-town/loc-shop/petShop.twee
index d6302ee6b9..eaf0993953 100644
--- a/game/overworld-town/loc-shop/petShop.twee
+++ b/game/overworld-town/loc-shop/petShop.twee
@@ -23,7 +23,7 @@ You are in the pet shop. <<if $daystate is "night">>Most of the animals are slee
 <<if $seenPets isnot true and $daystate isnot "night" and $fame.bestiality gte 200 and $bestialitydisable is "f" and ($monsterchance lt 100 or $monsterhallucinations is "t")>>
 	<<set $seenPets to true>><<generate1>><<person1>>
 	<<if $fame.bestiality gte 600>>
-		A <<person>> confronts you as you walk into the store. <<He>>'s wearing a nametag and the uniform of the place. <<His>> tone is polite, but firm.
+		A <<person>> confronts you as you walk into the store. <<Hes>> wearing a nametag and the uniform of the place. <<His>> tone is polite, but firm.
 		"Those animals are under my responsibility, and I don't want you to touch them in any way. If you're not here to buy something, please leave." <<stress 12>><<ggstress>>
 		<br><br>
 	<<elseif $fame.bestiality gte 400>>
@@ -277,4 +277,4 @@ You take a look at the collection of <<print $selectedToy.set>>. They cost <span
 	You can't afford this toy.
 <</if>>
 
-<<link [[Don't buy|Pet Shop]]>><<unset $selectedToy>><</link>>
\ No newline at end of file
+<<link [[Don't buy|Pet Shop]]>><<unset $selectedToy>><</link>>
diff --git a/game/overworld-town/loc-street/events.twee b/game/overworld-town/loc-street/events.twee
index 4ddb82db88..f100bfec2a 100644
--- a/game/overworld-town/loc-street/events.twee
+++ b/game/overworld-town/loc-street/events.twee
@@ -7472,7 +7472,7 @@ The <<person>> frowns at you. "You shouldn't scare dogs like that."
 :: Street Dog Growl 2
 <<effects>>
 
-You growl at the <<person>>. <<He>> backs away from you. "E-Easy," <<he>> says, holding up <<his>> hands. <<He>>'s hesitant to turn <<his>> back to you.
+You growl at the <<person>>. <<He>> backs away from you. "E-Easy," <<he>> says, holding up <<his>> hands. <<Hes>> hesitant to turn <<his>> back to you.
 <br><br>
 
 <<endevent>>
diff --git a/game/overworld-town/loc-temple/main.twee b/game/overworld-town/loc-temple/main.twee
index b5f5fa7b1d..22c0a86191 100644
--- a/game/overworld-town/loc-temple/main.twee
+++ b/game/overworld-town/loc-temple/main.twee
@@ -1295,7 +1295,7 @@ You fight through the shame and speak.
 <br><br>
 They guide you outside. The soft ground and muffled sound of traffic suggest they're taking you into the forest.
 <br><br>
-You walk for some time. They must be careful with the route they're leading you through, as you have no difficulty and your unease at walking while blind soon fades. Occasionally the group stops and you bump into whoever's in front of you. You hear someone move a branch out of way before continuing.
+You walk for some time. They must be careful with the route they're leading you through, as you have no difficulty and your unease at walking while blind soon fades. Occasionally the group stops and you bump into whomever's in front of you. You hear someone move a branch out of way before continuing.
 <br><br>
 The group stops once more, but this time someone rests their hand on your arm. You hear Jordan's voice. "We're here." <<He>> lifts your hand and places it on something cold and hard. "This is an altar. You'll need to lie on top of it. First though, your clothes."
 <br><br>
diff --git a/game/overworld-town/loc-temple/soup-kitchen.twee b/game/overworld-town/loc-temple/soup-kitchen.twee
index b29ff56a43..28918741b7 100644
--- a/game/overworld-town/loc-temple/soup-kitchen.twee
+++ b/game/overworld-town/loc-temple/soup-kitchen.twee
@@ -356,7 +356,7 @@ You walk around the corner. A <<person1>><<person>> pins a <<person3>><<person>>
 <<else>>
 	You fall to the ground, too hurt to continue. The <<person1>><<person>> steps on the <<person3>><<person>>, who was trying to crawl away. The <<person2>><<person>> looks at you.
 	<br><br>
-	"Lets take <<phim>> with us," <<he>> says. "Boss'll be happy."
+	"Let's take <<phim>> with us," <<he>> says. "Boss'll be happy."
 	<br><br>
 	"Alright," the <<person1>><<person>> says. "You carry <<phim>>. I'll get this fuck in the van."
 	<br><br>
diff --git a/game/overworld-town/special-robin/crossdressing.twee b/game/overworld-town/special-robin/crossdressing.twee
index 7f2d20b5a3..76989d35bb 100644
--- a/game/overworld-town/special-robin/crossdressing.twee
+++ b/game/overworld-town/special-robin/crossdressing.twee
@@ -259,7 +259,7 @@ you're left to stew in your curiosity.
 	You look at Robin's attire and shake your head. Robin nods and stays quiet.
 	<br><br>
 
-	"Huh, that's weird," a <<person2>><<personsimple>> mumbles out from outside Robin's door. <<person1>>"<<He>> always leaves a note up when <<person1>><<he>>'s not here."
+	"Huh, that's weird," a <<person2>><<personsimple>> mumbles out from outside Robin's door. <<person1>>"<<He>> always leaves a note up when <<person1>><<hes>> not here."
 	You hear retreating footsteps and Robin lets out a deep breath.
 	<br><br>
 
@@ -391,7 +391,7 @@ you're left to stew in your curiosity.
 
 	Robin sighs as soon as the <<personsimple>> is out of earshot.
 	<<if _robin.dom gte 60>>
-		<<person1>><<He>> seems like <<he>>'s about to say something, but takes a deep breath.
+		<<person1>><<He>> seems like <<hes>> about to say something, but takes a deep breath.
 		"Thanks. I guess I'll have to be more careful from now on," <<person1>><<He>> says as <<his>> smile returns.
 		"Still, this was really fun! It's exhilarating in a way." <<He>> hugs you tightly before turning to leave. "I'll be in my room if you need me."
 	<<else>>
@@ -420,7 +420,7 @@ you're left to stew in your curiosity.
 	<br><br>
 
 	<<if _robin.dom gte 60>>
-		<<person1>><<He>> seems like <<he>>'s about to say something about <<person2>><<him>>, but takes a deep breath. "Thanks for changing the subject,"
+		<<person1>><<He>> seems like <<hes>> about to say something about <<person2>><<him>>, but takes a deep breath. "Thanks for changing the subject,"
 		<<person1>><<he>> says. "I don't care what people say, I'm not like that. It just makes me feel nice that's all."
 		<<He>> moves to hug you tightly. "I'll be in my room if you need me."
 	<<else>>
@@ -575,7 +575,7 @@ you're left to stew in your curiosity.
 	<</if>>
 	<br><br>
 
-	Robin excitedly hugs you and quickly gathers <<person1>><<his>> supplies, as well as <<his>> new outfit. When <<he>>'s done, Robin turns to you.
+	Robin excitedly hugs you and quickly gathers <<person1>><<his>> supplies, as well as <<his>> new outfit. When <<hes>> done, Robin turns to you.
 	"Mind waiting outside for a bit? I'll be right out."
 	You exit and a few moments later Robin comes out, looking decisively <<print _robin.pronoun is "m" ? "feminine" : "masculine">>.
 	<br><br>
@@ -664,11 +664,11 @@ you're left to stew in your curiosity.
 
 		You place a gentle hand on <<person1>><<his>> shoulder, causing <<him>> to relax <<his>> fists.
 		<<if $submissive gte 1150>>
-			"I'm glad <<person2>><<he>>'s gone." You breathe a sigh of relief. "Are you okay Robin?"
+			"I'm glad <<person2>><<hes>> gone." You breathe a sigh of relief. "Are you okay Robin?"
 		<<elseif $submissive lte 850>>
-			"That asshole doesn't know what <<person2>><<he>>'s talking about," You say, rubbing Robin's shoulder. "Ignore <<him>>."
+			"That asshole doesn't know what <<person2>><<hes>> talking about," You say, rubbing Robin's shoulder. "Ignore <<him>>."
 		<<else>>
-			"Good thing <<person2>><<he>>'s gone," you say while smiling at Robin. "You going to be alright?"
+			"Good thing <<person2>><<hes>> gone," you say while smiling at Robin. "You going to be alright?"
 		<</if>>
 		<br><br>
 
@@ -879,7 +879,7 @@ you're left to stew in your curiosity.
 	<</if>>
 
 	<<if _robin.dom gte 60>>
-		If Robin's disappointed, <<he>>'s not letting it show. "There's always next time." <<He>> breaks the hug.
+		If Robin's disappointed, <<hes>> not letting it show. "There's always next time." <<He>> breaks the hug.
 		"I suppose I should change back then," <<he>> says. "I brought a change of clothes with my stand just in case something like this happened."
 	<<else>>
 		Robin nods. "I suppose there's no urgency in this," <<he>> says, a bit of pep returning to <<his>> voice.
@@ -1001,7 +1001,7 @@ you're left to stew in your curiosity.
 	<br><br>
 
 	"Really?" Robin is as happy as can be. <<He>> hugs you tightly for a long moment before letting go. "I'll go get changed."
-	<<He>>'s so excited that <<he>> starts changing into it immediately. "I don't mind if you watch me do this," <<he>> calls out.
+	<<Hes>> so excited that <<he>> starts changing into it immediately. "I don't mind if you watch me do this," <<he>> calls out.
 	<br><br>
 
 	<<if $promiscuity gte 15>>
@@ -1032,7 +1032,7 @@ you're left to stew in your curiosity.
 	<</if>>
 	<br><br>
 
-	When <<he>>'s done, <<he>> turns to you, and hugs you tightly. "I love you."
+	When <<hes>> done, <<he>> turns to you, and hugs you tightly. "I love you."
 	<br><br>
 
 	<<link [[Walk to school (0:20)|Robin School CD Walk]]>><<npcincr Robin love 5>><<pass 20>><</link>><<gglove>>
@@ -2067,7 +2067,7 @@ you're left to stew in your curiosity.
 	You try to milk everything out of <<him>> as <<he>> pumps a few more times.
 	<br><br>
 
-	Robin collapses on the bed after <<he>>'s spent. "That was intense." You lie next to <<him>>.
+	Robin collapses on the bed after <<hes>> spent. "That was intense." You lie next to <<him>>.
 	<br><br>
 
 	<<if _hole is "ass">>
@@ -2271,7 +2271,7 @@ you're left to stew in your curiosity.
 		<br><br>
 
 		You give another slow lick causing <<him>> to whimper.
-		<<He>>'s about to protest before you dig in, eagerly swapping between licking <<his>> outer folds and lightly sucking <<his>> erect clitoris.
+		<<Hes>> about to protest before you dig in, eagerly swapping between licking <<his>> outer folds and lightly sucking <<his>> erect clitoris.
 		Robin's protest devolves into a long drawn out moan as you keep pleasuring <<him>>. You tentatively poke your tongue inside slightly, making <<him>> tense up.
 		You can feel Robin's walls contract around your tongue as you push it further inside.
 		Once fully in, you explore <<his>> pussy, making sure to taste everything you can reach.
diff --git a/game/overworld-town/special-robin/flirt.twee b/game/overworld-town/special-robin/flirt.twee
index 2e2e798c0f..96fe4c910f 100644
--- a/game/overworld-town/special-robin/flirt.twee
+++ b/game/overworld-town/special-robin/flirt.twee
@@ -254,7 +254,7 @@
 				<<npcincr Robin love 1>><<npcincr Robin dom 1>><<npcincr Robin trauma -1>><<glove>><<gdom>><<lrtrauma>>
 			<<else>>
 				<<He>> looks you in the eyes. You look back at <<him>> and smile as you keep playing with <<his>> hair. <<He>> flushes but maintains the eye contact.
-				When you do break off, it looks like <<he>>'s about to say something but stops <<himself>>.
+				When you do break off, it looks like <<hes>> about to say something but stops <<himself>>.
 				<<npcincr Robin love 1>><<npcincr Robin trauma -1>><<glove>><<lrtrauma>>
 			<</if>>
 		<<elseif $robinromance gte 1>>
@@ -583,4 +583,4 @@ You make a kissing sound with your lips, causing <<him>> to get even more embarr
 "You can be really mean sometimes," <<he>> says.
 <br><br>
 
-<<robinoptions>>
\ No newline at end of file
+<<robinoptions>>
diff --git a/game/overworld-town/special-robin/lemonade.twee b/game/overworld-town/special-robin/lemonade.twee
index a2aae274b5..17fae46358 100644
--- a/game/overworld-town/special-robin/lemonade.twee
+++ b/game/overworld-town/special-robin/lemonade.twee
@@ -375,7 +375,7 @@ You walk to the other end of the populated part of the beach, and then back to R
 
 You walk to the High Street and buy a large bottle of water. You return to the beach.
 <<if _robin.trauma gte 40>>
-	Robin waves you over. <<He>>'s shaking. "I was so worried that something happened to you!" <<He>> hugs you tightly. <<npcincr Robin trauma 1>><<grtrauma>>
+	Robin waves you over. <<Hes>> shaking. "I was so worried that something happened to you!" <<He>> hugs you tightly. <<npcincr Robin trauma 1>><<grtrauma>>
 <<else>>
 	Robin waves at you. "Thank you. I'd need to close the stand if not for you." <<He>> hugs you.
 <</if>>
@@ -816,4 +816,4 @@ The other customers are less creepy.
 <<endevent>>
 <<link [[Offer help (0:30)|Robin's Lemonade Help]]>><<npcincr Robin love 1>><<npcincr Robin trauma -1>><<pass 30>><</link>><<glove>><<lrtrauma>>
 <br>
-<<link [[Leave|Beach]]>><</link>>
\ No newline at end of file
+<<link [[Leave|Beach]]>><</link>>
diff --git a/game/overworld-town/special-robin/main.twee b/game/overworld-town/special-robin/main.twee
index 9a6526d208..6ee819c1ab 100644
--- a/game/overworld-town/special-robin/main.twee
+++ b/game/overworld-town/special-robin/main.twee
@@ -1052,7 +1052,7 @@ The <<person1>><<person>> unties Robin, who doesn't seem to be aware of what's h
 
 <<upperruined>><<lowerruined>><<underruined>>
 <<set $leftarm to "bound">><<set $rightarm to "bound">>
-"You won't be needing these," the <<person2>><<person>> says, tearing off your clothing. "Right, lets go."
+"You won't be needing these," the <<person2>><<person>> says, tearing off your clothing. "Right, let's go."
 <br><br>
 
 The yacht starts to move. You see Robin lying on the dock, but the <<person3>><<person>> steps in the way. "So what will we do with you?"
@@ -3120,7 +3120,7 @@ Finally, <<he>> relents and gives you the money. You make £<<print $robinmoney>
 		<<link [[Nod|Robin Cow Help]]>><</link>><<lstress>><<ltrauma>>
 		<br>
 	<<elseif $livestock_robin is 10>>
-		Robin smiles at you. <<He>> knows you're happy this way, but <<he>>'s still worried about you. <br><br>
+		Robin smiles at you. <<He>> knows you're happy this way, but <<hes>> still worried about you. <br><br>
 		<<if $robinconsole is 0>>
 			<<He>> stares out the window, but glances at you a lot.
 		<<else>>
@@ -4476,7 +4476,7 @@ You arrive at the orphanage and step off the bus. Robin walks you to your room.
 			Robin looks at <<his>> wardrobe. "Do you think I should get something new?" <<He>> asks. "I'm thinking a hat."
 		<<else>>
 			<<if _robin.trauma gte 50>>
-				Robin looks like <<he>>'s been crying. "It's nothing, really," <<he>> assures you.
+				Robin looks like <<hes>> been crying. "It's nothing, really," <<he>> assures you.
 			<<else>>
 				Robin kicks <<his>> feet idly. "Do you want to do something today?"
 			<</if>>
@@ -6012,4 +6012,4 @@ You get up from the bed and leave the room. Robin doesn't look at you.
 <br><br>
 
 <<link [[Next|Orphanage]]>><</link>>
-<br>
\ No newline at end of file
+<br>
diff --git a/game/overworld-town/special-robin/walk.twee b/game/overworld-town/special-robin/walk.twee
index 29ca8e8ed4..9097ec3782 100644
--- a/game/overworld-town/special-robin/walk.twee
+++ b/game/overworld-town/special-robin/walk.twee
@@ -1194,7 +1194,7 @@ You talk with Robin.
 
 :: Robin Forest Milking
 <<location "forest">><<effects>>
-Robin seems engrossed in <<his>> sandwich, though you catch <<him>> glancing in your direction. <<He>>'s blushing, and avoids eye contact.
+Robin seems engrossed in <<his>> sandwich, though you catch <<him>> glancing in your direction. <<Hes>> blushing, and avoids eye contact.
 <br><br>
 You smirk as a lewd idea strikes you. You stand and take Robin's sandwich from <<his>> hand, placing it back in the basket. Robin looks embarrassed, and stares at <<his>> lap.
 <br><br>
diff --git a/game/overworld-town/special-robin/widgets.twee b/game/overworld-town/special-robin/widgets.twee
index b8b7936585..2edf9c6441 100644
--- a/game/overworld-town/special-robin/widgets.twee
+++ b/game/overworld-town/special-robin/widgets.twee
@@ -191,7 +191,7 @@
 			You knock on the door. Robin throws it open and hugs you. "Come in," <<he>> says, pulling you inside. <<He>> sits on the bed and stares at the spot <<his>> console used to fill.
 			<<if _robin.crossdressing gte 2>>
 				<<if _robin.pronoun is "f">>
-					It looks like <<he>>'s wearing <<his>> chest binder today.
+					It looks like <<hes>> wearing <<his>> chest binder today.
 				<<else>>
 					You take note of <<his>> <<npcClothesText _robin "upper">>.
 				<</if>>
@@ -202,7 +202,7 @@
 			<<He>> sits on the bed beside the television and picks up the controller.
 			<<if _robin.crossdressing gte 2>>
 				<<if _robin.pronoun is "f">>
-					It looks like <<he>>'s wearing <<his>> chest binder today.
+					It looks like <<hes>> wearing <<his>> chest binder today.
 				<<else>>
 					You take note of <<his>> <<npcClothesText _robin "upper">>.
 				<</if>>
@@ -685,4 +685,4 @@ You knock on the door. Robin throws it open and hugs you. "Come in," <<he>> says
 	<i>You've proven to Bailey that <<nnpc_he "Bailey">> can't simply expect you to pay <<nnpc_him "Bailey">> on time.
 	<span class="red">Robin will no longer be safe from Bailey, unless you can hold Bailey off.</span></i>
 	<br><br>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-town/special-sydney/main.twee b/game/overworld-town/special-sydney/main.twee
index 38e082efcc..9fe79cc16c 100644
--- a/game/overworld-town/special-sydney/main.twee
+++ b/game/overworld-town/special-sydney/main.twee
@@ -1899,7 +1899,7 @@ You yelp as the blow lands right on your <<genitals>>, but with the <<nnpc_title
 <</if>>
 <br><br>
 You are left sore and sour from the harsh punishment Sydney has been forced to perform on you. "Good work Sydney, perhaps there's hope for you yet. Dismissed!" Leighton orders Sydney to leave the library and roughly grabs at your reddened ass as <<nnpc_he "Leighton">> leans over your back and whispers into your ear.
-"Sirris' <<daughter>> may be off-limits, but you are not. I suggest you behave yourself in the future." Left alone, bent over the desk with your ass bared to whoever enters the library, you try to recover.
+"Sirris' <<daughter>> may be off-limits, but you are not. I suggest you behave yourself in the future." Left alone, bent over the desk with your ass bared to whomever enters the library, you try to recover.
 <br><br>
 <<if _sydneyStatus.includes("corrupt")>>
 	"Is that rotten <<if $NPCName[$NPCNameList.indexOf("Leighton")].pronoun is "m">>bastard<<else>>bitch<</if>> gone?"
@@ -3907,4 +3907,4 @@ You shake your head, but thank Sirris for the offer anyways.
 	Sydney hugs you<<if $sydneyromance is 1>> and kisses your cheek<</if>> before the two of them leave the temple.
 	<br><br>
 	<<link [[Next|Temple]]>><<endevent>><</link>>
-<</if>>
\ No newline at end of file
+<</if>>
diff --git a/game/overworld-town/special-whitney/main.twee b/game/overworld-town/special-whitney/main.twee
index 6d547da7cc..fee89174bc 100644
--- a/game/overworld-town/special-whitney/main.twee
+++ b/game/overworld-town/special-whitney/main.twee
@@ -2176,7 +2176,7 @@ One of the <<persons>> crewmates catches up and stares at Whitney. "Something's
 
 <<endevent>><<npc Whitney>><<person1>>
 
-Whitney steps forward, fists clenched. <<His>> gang doesn't seem so eager to start a fight though. Two of them pull <<him>> back. "You weak fucks," <<he>> shouts, you're not sure at who. "I hope you fish fuckers get raped by a whale." <<He>> turns with <<his>> friends and walks away.
+Whitney steps forward, fists clenched. <<His>> gang doesn't seem so eager to start a fight though. Two of them pull <<him>> back. "You weak fucks," <<he>> shouts, you're not sure at whom. "I hope you fish fuckers get raped by a whale." <<He>> turns with <<his>> friends and walks away.
 <br><br>
 
 The crew make sure you're okay, then head back to their ship.
@@ -2621,7 +2621,7 @@ You scramble after before anyone in the crowd steals them. You make it in time.
 <<flaunting>> you trot down the hallway on all fours with Whitney and <<his>> friends guiding you. You block their path once or twice, sitting down in front of them in a begging position<<if $leftarm is "bound" and $rightarm is "bound">> to the best of your ability<</if>>, barking and panting like an animal until they pat your head or scratch your chin and you purr.
 <<exhibitionism5>>
 
-"You can't decide if you're a dog or a cat," Whitney remarks. "Lets see you play fetch."
+"You can't decide if you're a dog or a cat," Whitney remarks. "Let's see you play fetch."
 
 You're steered round a corner and into a corridor full of <<peopley>>. <<covered>> A nearby <<persony>><<person1>> looks at you and gasps in shock. Others have a similar reaction. As the noise grows more turn to look, until everyone is watching you.
 <br><br>
@@ -6344,4 +6344,4 @@ You watch <<him>> skulk into an alley, leaving you alone.
 <br><br>
 
 <<link [[Next|Domus Street]]>><<endevent>><<set $eventskip to 1>><</link>>
-<br>
\ No newline at end of file
+<br>
diff --git a/game/overworld-town/special-whitney/street.twee b/game/overworld-town/special-whitney/street.twee
index 56498ab9b4..9a99b345bc 100644
--- a/game/overworld-town/special-whitney/street.twee
+++ b/game/overworld-town/special-whitney/street.twee
@@ -3296,7 +3296,7 @@ You walk a meandering path through the streets, arm locked with Whitney, with <<
 	<br><br>
 <<else>>
 	<<generateyv2>>
-	You arrive outside the orphanage. "What a shithole," Whitney exclaims, kicking open the front door. <<Hes>> greeted by a surprised resident, a <<person2>><<person>>, who's expression turns to horror at the sight of Whitney. <<He>> scurries deeper into the building. Whitney laughs.
+	You arrive outside the orphanage. "What a shithole," Whitney exclaims, kicking open the front door. <<Hes>> greeted by a surprised resident, a <<person2>><<person>>, whose expression turns to horror at the sight of Whitney. <<He>> scurries deeper into the building. Whitney laughs.
 	<br><br>
 	"So where can we put our feet up?"
 	<br><br>
@@ -3680,4 +3680,4 @@ You kneel beside the sofa, and displace Whitney's <<npcClothesText $NPCName[$NPC
 	<br><br>
 <</if>>
 
-<<link [[Next|Orphanage]]>><</link>>
\ No newline at end of file
+<<link [[Next|Orphanage]]>><</link>>
diff --git a/game/overworld-underground/loc-cave/widgets.twee b/game/overworld-underground/loc-cave/widgets.twee
index 21285a69a0..33bac505ca 100644
--- a/game/overworld-underground/loc-cave/widgets.twee
+++ b/game/overworld-underground/loc-cave/widgets.twee
@@ -381,7 +381,7 @@
 
 <<widget "slug_caught">>
 <<if $voredisable is "f">>
-	With a final leap, the giant slug catches up, and forces you to the ground. It's maw wraps around you, and it sucks you inside.
+	With a final leap, the giant slug catches up, and forces you to the ground. Its maw wraps around you, and it sucks you inside.
 	<br><br>
 
 	<<link [[Next|Beach Slug Vore]]>><<set $molestationstart to 1>><</link>>
diff --git a/game/overworld-underground/loc-sewers/old-sewers-events.twee b/game/overworld-underground/loc-sewers/old-sewers-events.twee
index 58af3f5e79..3d5501308c 100644
--- a/game/overworld-underground/loc-sewers/old-sewers-events.twee
+++ b/game/overworld-underground/loc-sewers/old-sewers-events.twee
@@ -315,7 +315,7 @@ Emboldened, the slime slides between your thighs, teasing your taint as your rea
 <br><br>
 Then the slime pressed up against your <<genitals>> seems to come alive, the goo
 <<if $worn.genitals.type.includes("hidden")>>
-	finds it's way inside of your $worn.genitals.name and despite the lack of space, causes immense pleasure to your <<genitals 1>>.
+	finds its way inside of your $worn.genitals.name and despite the lack of space, causes immense pleasure to your <<genitals 1>>.
 <<else>>
 	<<if $player.penisExist>>
 		feeling as if it is stroking you from <<if $player.ballsExist>>your balls<<else>>the bottom<</if>> to the tip of your
@@ -324,7 +324,7 @@ Then the slime pressed up against your <<genitals>> seems to come alive, the goo
 		vibrating right on top of your excited clit as it rubs up, down, and between your pussy lips.
 	<</if>>
 <</if>>
-You let out a cry of surprise as sharp pleasurable feelings run up your spine. You struggle weakly, causing the creature to redouble it's attentions.
+You let out a cry of surprise as sharp pleasurable feelings run up your spine. You struggle weakly, causing the creature to redouble its attentions.
 <br><br>
 Your nude body is engulfed almost entirely, and being teased mercilessly. It's too much. With a loud squeak, you cum. Hard.
 <br><br>
diff --git a/game/special-dance/effects.twee b/game/special-dance/effects.twee
index 4025adc860..13ac02a638 100644
--- a/game/special-dance/effects.twee
+++ b/game/special-dance/effects.twee
@@ -1121,7 +1121,7 @@
 					<<if $rng gte 76>>
 						"Give us a peek beneath your skirt."
 					<<elseif $rng gte 51>>
-						"Twirl faster <<girl>>, lets see that skirt flare."
+						"Twirl faster <<girl>>, let's see that skirt flare."
 					<<elseif $rng gte 26>>
 						"I love it when they dance in skirts."
 					<<else>>
diff --git a/game/special-masturbation/effects.twee b/game/special-masturbation/effects.twee
index 726c111f83..793521c00c 100644
--- a/game/special-masturbation/effects.twee
+++ b/game/special-masturbation/effects.twee
@@ -1151,7 +1151,7 @@
 	<<if $arousal gte ($arousalmax / 5) * 4>>
 		You shiver as you drink down the fluid while sucking and moving your head back and forward.
 	<<elseif $arousal gte ($arousalmax / 5) * 3>>
-		You're sucking on the plant while lapping up it's fluid.
+		You're sucking on the plant while lapping up its fluid.
 	<<else>>
 		You're sucking on the phallus plant.
 	<</if>>
diff --git a/game/special-masturbation/main.twee b/game/special-masturbation/main.twee
index 8b652881b6..d369f8bb89 100644
--- a/game/special-masturbation/main.twee
+++ b/game/special-masturbation/main.twee
@@ -1093,7 +1093,7 @@ You put on a brave face and tell <<him>> you're fine. "Okay. If you say so," <<h
 		You <<nervously>> remove your $worn.lower.name and $worn.under_lower.name while trying to keep your <<genitals>> concealed from the teacher.
 		<<underlowerstrip>>
 	<</if>>
-	As Winter moves your hands <<his>> eyes widen. "Oh," <<he>> says. "You're already locked up, and it wasn't enough?" <<He>> thinks for a moment. "I found the key to the chastity cage you're wearing, lets take this a step further." <<He>> pulls a key from <<his>> pocket and unlocks the cage from around your penis.
+	As Winter moves your hands <<his>> eyes widen. "Oh," <<he>> says. "You're already locked up, and it wasn't enough?" <<He>> thinks for a moment. "I found the key to the chastity cage you're wearing, let's take this a step further." <<He>> pulls a key from <<his>> pocket and unlocks the cage from around your penis.
 	<<set $worn.genitals.type.push("broken")>>
 	<<genitalsruined>>
 	<<if $vaginalchastityparasite isnot 0>>
-- 
GitLab


From b9d5f4536077a0a982bf0aeda35b7791e0997cac Mon Sep 17 00:00:00 2001
From: Jimmy <23598-Jimmys@users.noreply.gitgud.io>
Date: Sun, 25 Sep 2022 17:53:04 +0000
Subject: [PATCH 49/50] EventSystem clean-up and validator

---
 game/03-JavaScript/EventDebug.js              | 121 ++++++++---
 game/03-JavaScript/tabs.js                    |  14 +-
 .../04-Variables/variables-versionUpdate.twee |   2 +-
 game/base-combat/beast-generation.twee        |   2 +-
 game/base-combat/end.twee                     |   6 +-
 game/base-combat/npc-generation.twee          |   2 +-
 game/base-debug/debug-events.twee             | 198 +++++++++---------
 game/base-system/caption.twee                 |  23 +-
 game/base-system/named-npcs.twee              |   6 +-
 game/base-system/persistent-npcs.twee         |   4 +-
 game/overworld-town/loc-cafe/main.twee        |   6 +-
 11 files changed, 229 insertions(+), 155 deletions(-)

diff --git a/game/03-JavaScript/EventDebug.js b/game/03-JavaScript/EventDebug.js
index 521e01994e..97dc2eac28 100644
--- a/game/03-JavaScript/EventDebug.js
+++ b/game/03-JavaScript/EventDebug.js
@@ -25,7 +25,7 @@ class EventData {
 		this.disable = false;
 	}
 
-	Push(passage, index, time) {
+	push(passage, index, time) {
 		if (this.disable) return;
 		if (V.event == null) {
 			V.event = { buffer: [], schema: 1 };
@@ -37,36 +37,108 @@ class EventData {
 		});
 	}
 
-	Pop(index) {
+	pop(index) {
 		if (this.disable) return;
 		if (V.event) {
 			V.event.buffer = V.event.buffer.filter(e => e.slot !== index); // TODO: Splice backwards instead.
 			if (V.event.buffer.length === 0) {
-				this.Clear();
+				this.clear();
 			}
 		}
 	}
 
-	Get(index) {
-		if (V.event) {
-			return V.event.buffer.find(e => e.slot === index);
-		}
-		return undefined;
+	get(index) {
+		return V.event?.buffer.find(e => e.slot === index);
 	}
 
-	GetEvery(index) {
-		if (V.event) {
-			return V.event.buffer.filter(e => e.slot === index);
-		}
-		return [];
+	has(index) {
+		return V.event?.buffer.some(e => e.slot === index);
+	}
+
+	getEvery(index) {
+		return V.event?.buffer.filter(e => e.slot === index) ?? [];
 	}
 
-	Clear() {
+	count() {
+		return V.event?.buffer.length || 0;
+	}
+
+	any() {
+		return V.event?.buffer.length > 0;
+	}
+
+	clear() {
 		if (this.disable) return;
 		delete V.event;
 	}
 
-	Update() {
+	isSlotTaken(index) {
+		return V.event?.buffer.some(e => e.slot === index);
+	}
+
+	get Disable() {
+		return this.disable;
+	}
+
+	set Disable(value) {
+		if (typeof value === "boolean") {
+			this.disable = value;
+		} else {
+			console.debug("EventData.disable set with unexpected data-type, requires boolean.");
+		}
+	}
+
+	validate() {
+		// Return false if an event is not in progress. True would be a problem in our stack system for NPCs. False indicates normal operation.
+		if (V.event == null) return true;
+		// Extrapolate slots
+		const buffer = V.event.buffer;
+		// Making assumptions for the validator, traverse from the end, and when we hit the first NPC, return index.
+		// We plus one because we want the semantic size that we believe the NPC list is at.
+		// An NPCList of [empty, npc, npc, empty, empty, empty] would have a size of 3.
+		// We assume the first empty is a mistake, someone not following proper conduct in NPC gen.
+		const numOfNPCs = V.NPCList.findLastIndex(e => Object.hasOwn(e, "type")) + 1;
+
+		// First check for if buffer's length exceeds NPCList's length. (Guaranteed gaps or inaccurate tracking)
+		if (buffer.length > numOfNPCs) return false;
+
+		// Generate array to track whether an NPC slot is used.
+		const usedArr = Array(numOfNPCs).fill(false);
+		// Example: [false, false, false, false, false] for 5 NPCs in $NPCList
+		for (let i = 0; i < buffer.length; i++) {
+			const element = buffer[i];
+			if (!usedArr[element.slot]) {
+				// Slot not accounted for yet, NPC is good.
+				usedArr[element.slot] = true;
+				continue;
+			} else if (V.debugdisable === "f" || V.debug) {
+				// NPC position is being used more than once, although not a gap, flag.
+				console.warn(
+					"NPC slot",
+					element.slot,
+					"is being used more than once. Existing NPCs should be disposed before using their slot."
+				);
+				return false;
+			}
+		}
+
+		// Check usedArr for false values. Filter results where false remains into a new array at the index.
+		// [true, false, true, false] => [1, 3]
+		// We then intend to display these indices to the user for debugging.
+		const slots = [];
+		for (let i = 0; i < usedArr.length; i++) {
+			const e = usedArr[i];
+			if (!e) slots.push(i);
+		}
+		if (slots.length !== 0) {
+			// Index is slot, index being 0 or higher means we have an empty slot.
+			console.warn("NPC slots that are empty:", slots);
+			return false;
+		}
+		return true;
+	}
+
+	update() {
 		if (V.event == null) {
 			return;
 		}
@@ -86,28 +158,11 @@ class EventData {
 			schema: 1,
 		};
 		for (let i = 0; i < event.length; i++) {
-			this.Push(event[i], V.eventslot[i], V.eventtime[i]);
+			this.push(event[i], V.eventslot[i], V.eventtime[i]);
 		}
 		delete V.eventtime;
 		delete V.eventslot;
 	}
-
-	IsSlotTaken(index) {
-		if (V.event == null) return false;
-		return V.event.buffer.some(e => e.slot === index);
-	}
-
-	get Disable() {
-		return this.disable;
-	}
-
-	set Disable(value) {
-		if (typeof value === "boolean") {
-			this.disable = value;
-		} else {
-			console.debug("EventData.disable set with unexpected data-type, requires boolean.");
-		}
-	}
 }
 
 // Jimmy: Potentially flawed design style, static class basically.
diff --git a/game/03-JavaScript/tabs.js b/game/03-JavaScript/tabs.js
index 74293b0818..494ba5536c 100644
--- a/game/03-JavaScript/tabs.js
+++ b/game/03-JavaScript/tabs.js
@@ -1,4 +1,4 @@
-window.Tab = class {
+const Tab = class {
 	constructor(element, selectedClass) {
 		this.element = element;
 		this.selectedClass = selectedClass;
@@ -7,17 +7,20 @@ window.Tab = class {
 	}
 
 	setupTabs() {
-		$(() => { this.tabs = $("#" + this.element).find("button"); });
+		$(() => {
+			this.tabs = $("#" + this.element).find("button");
+		});
 	}
+
 	setActive(index = 0) {
 		$(() => {
-			if(index === -1) return;
+			if (index === -1) return;
 			this.activeTab = index;
 			this.toggle(this.tabs.eq(index));
 		});
 	}
 
-	toggle(target = $(window.event.target)) {
+	toggle(target = $(window.event.currentTarget)) {
 		this.reset();
 		this.activeTab = this.tabs.index(target);
 		target.addClass(this.selectedClass);
@@ -27,4 +30,5 @@ window.Tab = class {
 		this.activeTab = -1;
 		this.tabs.removeClass(this.selectedClass);
 	}
-};
\ No newline at end of file
+};
+window.Tab = Tab;
diff --git a/game/04-Variables/variables-versionUpdate.twee b/game/04-Variables/variables-versionUpdate.twee
index a96d5029d3..d4a672423d 100644
--- a/game/04-Variables/variables-versionUpdate.twee
+++ b/game/04-Variables/variables-versionUpdate.twee
@@ -2722,7 +2722,7 @@
 
 	<!-- Jimmy: Run updater for EventSystem.
 				Only runs if behind on schema, and if $event exists. -->
-	<<run EventSystem.Update()>>
+	<<run EventSystem.update()>>
 
 	<!-- Jimmy: Updater for NNPCs that lack pronouns structures.
 				Based off of $perNPCFix located in VVU -->
diff --git a/game/base-combat/beast-generation.twee b/game/base-combat/beast-generation.twee
index 176bef8262..342f261745 100644
--- a/game/base-combat/beast-generation.twee
+++ b/game/base-combat/beast-generation.twee
@@ -47,7 +47,7 @@
 
 <<beastattribute _n _type>>
 
-<<run EventSystem.Push($passage, _n, $time)>>
+<<run EventSystem.push($passage, _n, $time)>>
 <</widget>>
 
 <<widget "beastattribute">>
diff --git a/game/base-combat/end.twee b/game/base-combat/end.twee
index a95850a201..9679eaf4c3 100644
--- a/game/base-combat/end.twee
+++ b/game/base-combat/end.twee
@@ -500,7 +500,7 @@
 <<set $npcnum.splice(0)>>
 <<set $npcrow.splice(0)>>
 <<if $endeventerror is undefined>>
-	<<run EventSystem.Clear()>>
+	<<run EventSystem.clear()>>
 <</if>>
 <</widget>>
 
@@ -522,12 +522,12 @@
 	<<set $enemyno -= 1>>
 <</if>>
 <<if $endeventerror is undefined>>
-	<<run EventSystem.Pop(_i)>>
+	<<run EventSystem.pop(_i)>>
 <</if>>
 <<if $enemyno is 0>>
 	<<set $pronoun to 0>>
 	<<if $endeventerror is undefined>>
-		<<run EventSystem.Clear()>>
+		<<run EventSystem.clear()>>
 	<</if>>
 <</if>>
 <<if $NPCList[_i].strapon isnot undefined>>
diff --git a/game/base-combat/npc-generation.twee b/game/base-combat/npc-generation.twee
index 74268aefc4..48834990a9 100644
--- a/game/base-combat/npc-generation.twee
+++ b/game/base-combat/npc-generation.twee
@@ -63,7 +63,7 @@
 
 <<npcattribute _n _gender _lvl>>
 
-<<run EventSystem.Push($passage, _n, $time)>>
+<<run EventSystem.push($passage, _n, $time)>>
 <</widget>>
 
 <<widget "generateRole">>
diff --git a/game/base-debug/debug-events.twee b/game/base-debug/debug-events.twee
index 5ce84e5f52..f780448805 100644
--- a/game/base-debug/debug-events.twee
+++ b/game/base-debug/debug-events.twee
@@ -4,7 +4,7 @@
 	Since I didn't find an appropriate file to put this in, I decided to make my own.
 	Feel free to delete this comment at leisure. -->
 <<widget "checkEventNPC">>
-	<<if (EventSystem.IsSlotTaken(_args[0]) and !EventSystem.Disable) or $enemynomax gte 6 or $enemyno gte 6>>
+	<<if (EventSystem.isSlotTaken(_args[0]) and !EventSystem.Disable) or $enemynomax gte 6 or $enemyno gte 6>>
 		<<set $endeventerror to $lastgenerated>>
 		<<clearsinglenpc _args[0]>>
 		<!-- <<endevent phaseless>> -->
@@ -13,122 +13,130 @@
 <</widget>>
 
 <<widget "eventExtraInfo">>
-<!-- Setup useful variables -->
-<<set $_passages = (V.event is undefined
-	? []
-	: V.event.buffer.reduce((prev, cur) => {
-		prev.pushUnique(cur.area[0]);
-		return prev;
-	}, [])
-)>>
+	<!-- Setup useful variables -->
+	<<set $_passages = V.event is undefined
+		? []
+		: V.event.buffer.reduce((prev, cur) => {
+			prev.pushUnique(cur.area[0]);
+			return prev;
+		}, [])
+	>>
 
-<<if _eventalertmajorarea is true>>
-	<span class="red">You are in a major area, which means an NPC escaped!</span>
-	<<if $cheatdisable is "f">>
-		Ignore this message if you've just used a cheat. Otherwise, <span class="red">please report this!</span>
-	<<else>>
-		<span class="red">Please report this!</span>
-	<</if>>
-	<<set _eventreason to true>>
-<<elseif _eventalertmajorarea is false>>
-	<span class="green">This NPC was defined in this passage</span><<set _eventreason to true>>
-<<else>>
-	<<if $passage.includes("Street Stalk")>>
-		<span class="green">You are being stalked. Usually this means everything is in order.</span>
+	<h3>Area information</h3>
+
+	<br>
+	Passage: $_passages
+	<br>
+
+	<<if _eventAlertMajorArea is true>>
+		<span class="red">You are in a major area, which means an NPC escaped!</span>
+		<<if $cheatdisable is "f">>
+			Ignore this message if you've just used a cheat. Otherwise, <span class="red">please report this!</span>
+		<<else>>
+			<span class="red">Please report this!</span>
+		<</if>>
 		<<set _eventreason to true>>
-	<</if>>
-	<<if $event isnot undefined>>
-		<<if $_passages.includes($passage)>>
-			<span class="green">You are in a passage where NPCs were generated.</span>
-			<<set _eventreason to true>>
-		<<elseif $passage.includes($_passages)>>
-			<span class="green">You are in a subpassage from where NPCs were generated. Usually this means they are still in use.</span>
+	<<elseif !_eventAlertMajorArea>>
+		<span class="green">This NPC was defined in this passage</span>
+		<<set _eventreason to true>>
+	<<else>>
+		<<if $passage.includes("Street Stalk")>>
+			<span class="green">You are being stalked. Usually this means everything is in order.</span>
 			<<set _eventreason to true>>
 		<</if>>
-	<<else>>
-		<span class="yellow">You are not in an event.</span>
+		<<if $event isnot undefined>>
+			<<if $_passages.includes($passage)>>
+				<span class="green">You are in a passage where NPCs were generated.</span>
+				<<set _eventreason to true>>
+			<<elseif $passage.includes($_passages)>>
+				<span class="green">You are in a subpassage from where NPCs were generated. Usually this means they are still in use.</span>
+				<<set _eventreason to true>>
+			<</if>>
+		<<else>>
+			<span class="yellow">You are not in an event.</span>
+		<</if>>
 	<</if>>
-<</if>>
-<<if _eventreason isnot true>>
-	<span class="yellow">NPCs were generated at some point and may not be cleared. They could still be in use. If you feel like they shouldn't be active, please report this. If you're unsure whether or not to report this, go to a major area (i.e a street/alleyway/outside) and check this again.</span>
-<</if>>
-<br><br>
-<h3>NPC information</h3><br>
-$enemyno NPC<<if $enemyno gt 1>>s are<<else>> is<</if>> currently active. Max: $enemynomax. Them being:<br><br>
-
-<div class="debug-event-container">
-<<for $_i to 0; $_i lt $NPCList.length; $_i++>>
-	<<set $_npc to $NPCList[$_i]>>
-	<<set $_eventNPC to EventSystem.Get($_i)>>
-	<<if $_npc.type isnot undefined and $_eventNPC isnot undefined>>
-		<div class="debug-event-item debug-event-success">
-			ID: $_i | $_npc.fullDescription<br>
-			Sex: $_npc.gender | Gender: $_npc.pronouns.man<br>
-			Description: $_npc.description<<if $_npc.role>> | Role: $_npc.role<</if>><br>
-			Source: <<print $_eventNPC.area[0]>>, at: <<ampm `Math.floor($_eventNPC.time / 60)` `$_eventNPC.time % 60`>>.<br>
-		</div>
-	<<else>>
-		<div class="debug-event-item debug-event-empty">
-			NPC #: $_i
-		</div>
+	<<if !_eventreason>>
+		<span class="yellow">NPCs were generated at some point and may not be cleared. They could still be in use. If you feel like they shouldn't be active, please report this. If you're unsure whether or not to report this, go to a major area (i.e a street/alleyway/outside) and check this again.</span>
 	<</if>>
-<</for>>
-</div>
+	<br><br>
+	<h3>NPC information</h3>
+	<br>
+	$enemyno NPC<<if $enemyno gt 1>>s are<<else>> is<</if>> currently active. Max: $enemynomax. Them being:<br><br>
 
-<<if $event isnot undefined>>
-	<br>Extra debugging:<br>
-	<<for $_i to 0; $_i lt $event.buffer.length; $_i++>>
-		<<set $_eventNPC to $event.buffer[$_i]>>
-		<<print ($NPCList[$_eventNPC.slot] || {}).fullDescription || "No description.">><br>
-		Defined in passage <<print $_eventNPC.area[0]>>, at <<ampm `Math.floor($_eventNPC.time / 60)` `$_eventNPC.time % 60`>>.<br>
-		<<if $_eventNPC.area.length gt 1>>
-			Widget Stack:
-			<<set $_widgetStack to $_eventNPC.area.slice(1)>>
-			<<for $_iStack = 0; $_iStack lt $_widgetStack.length; $_iStack++>>
-				<<print "<<$_widgetStack[$_iStack]>>">><<if $_iStack isnot $_widgetStack.length - 1>>, <</if>>
-			<</for>>
-			<br>
+	<div class="debug-event-container">
+	<<for $_i to 0; $_i lt $NPCList.length; $_i++>>
+		<<set $_npc to $NPCList[$_i]>>
+		<<set $_eventNPC to EventSystem.get($_i)>>
+		<<if $_npc.type isnot undefined and $_eventNPC isnot undefined>>
+			<div class="debug-event-item debug-event-success">
+				ID: $_i | $_npc.fullDescription<br>
+				Sex: $_npc.gender | Gender: $_npc.pronouns.man<br>
+				Description: $_npc.description<<if $_npc.role>> | Role: $_npc.role<</if>><br>
+				Source: <<print $_eventNPC.area[0]>>, at: <<ampm `Math.floor($_eventNPC.time / 60)` `$_eventNPC.time % 60`>>.<br>
+			</div>
+		<<else>>
+			<div class="debug-event-item debug-event-empty">
+				NPC #: $_i
+			</div>
 		<</if>>
-		<!-- Check other event NPCs for linked passages -->
-		<<for $_j to 0; $_j lt $event.buffer.length; $_j++>>
-			<<set $_eventNPC2 to $event.buffer[$_j]>>
-			<<if $_i isnot $_j and $_eventNPC.area[0] is $_eventNPC2.area[0]>>
-				<<if _eventnumberinpassage is undefined>>
-					<<set _eventnumberinpassage to 0>>
-				<</if>>
-				<<set _eventnumberinpassage += 1>>
+	<</for>>
+	</div>
+
+	<<if $event isnot undefined>>
+		<br>Extra debugging:<br>
+		<<for $_i to 0; $_i lt $event.buffer.length; $_i++>>
+			<<set $_eventNPC to $event.buffer[$_i]>>
+			<<print ($NPCList[$_eventNPC.slot] || {}).fullDescription || "No description.">><br>
+			Defined in passage <<print $_eventNPC.area[0]>>, at <<ampm `Math.floor($_eventNPC.time / 60)` `$_eventNPC.time % 60`>>.<br>
+			<<if $_eventNPC.area.length gt 1>>
+				Widget Stack:
+				<<set $_widgetStack to $_eventNPC.area.slice(1)>>
+				<<for $_iStack = 0; $_iStack lt $_widgetStack.length; $_iStack++>>
+					<<print "<<$_widgetStack[$_iStack]>>">><<if $_iStack isnot $_widgetStack.length - 1>>, <</if>>
+				<</for>>
+				<br>
 			<</if>>
-		<</for>>
-		<!-- Check other event NPCs for linked passages -->
-		<<if _eventnumberinpassage isnot undefined>>
-			<<print _eventnumberinpassage>> other NPC<<if _eventnumberinpassage isnot 1>>s<</if>> have also been defined in passage <<print $_eventNPC.area[0]>>.<br>
-			<<unset _eventnumberinpassage>>
-		<</if>>
-		Set in slot <<print $_eventNPC.slot>> of $$NPCList.<br>
-		<<for $_j to 0; $_j lt $event.buffer.length; $_j++>>
-			<<if $_i isnot $_j and $_eventNPC.slot is $_eventNPC.slot[$_j]>>
-				<span class="red">This NPC has been overwritten or overwrote another one in slot <<print $event.slot[$_eventNPC.slot]>>!</span><br>
-				<<break>>
+			<!-- Check other event NPCs for linked passages -->
+			<<for $_j to 0; $_j lt $event.buffer.length; $_j++>>
+				<<set $_eventNPC2 to $event.buffer[$_j]>>
+				<<if $_i isnot $_j and $_eventNPC.area[0] is $_eventNPC2.area[0]>>
+					<<if _eventnumberinpassage is undefined>>
+						<<set _eventnumberinpassage to 0>>
+					<</if>>
+					<<set _eventnumberinpassage += 1>>
+				<</if>>
+			<</for>>
+			<!-- Check other event NPCs for linked passages -->
+			<<if _eventnumberinpassage isnot undefined>>
+				<<print _eventnumberinpassage>> other NPC<<if _eventnumberinpassage isnot 1>>s<</if>> have also been defined in passage <<print $_eventNPC.area[0]>>.<br>
+				<<unset _eventnumberinpassage>>
 			<</if>>
+			Set in slot <<print $_eventNPC.slot>> of $$NPCList.<br>
+			<<for $_j to 0; $_j lt $event.buffer.length; $_j++>>
+				<<if $_i isnot $_j and $_eventNPC.slot is $_eventNPC.slot[$_j]>>
+					<span class="red">This NPC has been overwritten or overwrote another one in slot <<print $event.slot[$_eventNPC.slot]>>!</span><br>
+					<<break>>
+				<</if>>
+			<</for>>
+			<br>
 		<</for>>
-		<br>
-	<</for>>
-	Phase: $phase
-<</if>>
+		Phase: $phase
+	<</if>>
 <</widget>>
 
 <!-- <<widget "eventAlert">>
  <<if $event[0] is $passage>>
 	<span class="green" style="text-align: center">Event Active</span>
 	<<if $debug is 1>>
-		<<set _eventalertmajorarea to false>>
+		<<set _eventAlertMajorArea to false>>
 		<span class="rainbow"><<button "More Event Info">>
 			<<overlayReplace "eventExtraInfo">>
 		<</button>></span>
 	<</if>>
 <<elseif ["Orphanage", "Bedroom", "Barb Street", "Cliff Street", "Connudatus Street", "Danube Street", "Domus Street", "Elk Street", "Harvest Street", "High Street", "Mer Street", "Nightingale Street", "Oxford Street", "Starfish Street", "Wolf Street", "Residential alleyways", "Commercial alleyways", "Industrial alleyways", "Park", "Hallways", "Brothel", "Strip Club", "Beach", "Ocean Breeze", "Docks Work", "Residential Drain", "Commercial Drain", "Industrial Drain", "Forest", "Farmland", "Livestock Field", "Forest Wolf Cave", "Wolf Cave", "Wolf Cave Clearing", "Asylum", "Asylum Cell", "Underground Cell"].includes($passage)>>
 	<span class="red" style="text-align: center">Event Active</span>
-	<<set _eventalertmajorarea to true>>
+	<<set _eventAlertMajorArea to true>>
 	<span class="rainbow"><<button "More Event Info">>
 		<<overlayReplace "eventExtraInfo">>
 	<</button>></span>
@@ -140,4 +148,4 @@ $enemyno NPC<<if $enemyno gt 1>>s are<<else>> is<</if>> currently active. Max: $
 		<<overlayReplace "eventExtraInfo">>
 	<</button>></span>
 <</if>>
-<</widget>> -->
\ No newline at end of file
+<</widget>> -->
diff --git a/game/base-system/caption.twee b/game/base-system/caption.twee
index 8c965cb872..a0fea25743 100644
--- a/game/base-system/caption.twee
+++ b/game/base-system/caption.twee
@@ -277,15 +277,22 @@
 			</div>
 			<!-- Event debug button - Shows an overlay stored in debug-events.twee. -->
 			<<if $event isnot undefined and $debugdisable is "f">>
+				<!-- Default _temp to what we should people regularly if an event active. -->
 				<<set _temp to "<span class='yellow'>SHOW EVENT INFO</span>">>
-				<<if EventSystem.Get(0).area[0] is $passage>>
-					<<set _eventalertmajorarea to false>>
-					<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
-				<<elseif setup.majorAreas.includes($passage)>>
-					<<set _eventalertmajorarea to true>>
-					<<set _temp to "<span class='red'>EVENT ACTIVE</span>">>
-				<<elseif $event.buffer.map(e => e.area[0]).length is 1 and ["Forest Cabin", "Eden Cabin", "Eden Clearing"].includes(EventSystem.Get(0).area[0])>>
-					<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
+				<!-- Prepare for cases where we want to update the button view. -->
+				<<if EventSystem.any()>>
+					<<if !EventSystem.validate()>>
+						<!-- Could not validate the NPC list with event data. -->
+						<<set _temp to "<span class='red'>EVENT ERROR</span>">>
+					<<elseif EventSystem.has(0) and EventSystem.get(0).area[0] is $passage>>
+						<<set _eventAlertMajorArea to false>>
+						<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
+					<<elseif setup.majorAreas.includes($passage)>>
+						<<set _eventAlertMajorArea to true>>
+						<<set _temp to "<span class='red'>EVENT ACTIVE</span>">>
+					<<elseif $event.buffer.map(e => e.area[0]).length is 1 and EventSystem.has(0) and ["Forest Cabin", "Eden Cabin", "Eden Clearing"].includes(EventSystem.get(0).area[0])>>
+						<<set _temp to "<span class='green'>EVENT ACTIVE</span>">>
+					<</if>>
 				<</if>>
 				<<button _temp>><<overlayReplace "eventExtraInfo">><</button>>
 				<<unset _temp>>
diff --git a/game/base-system/named-npcs.twee b/game/base-system/named-npcs.twee
index c016d1c01a..2d31a47a49 100644
--- a/game/base-system/named-npcs.twee
+++ b/game/base-system/named-npcs.twee
@@ -60,12 +60,12 @@
 		<<set $enemyno -= 1>>
 		<<set $enemynomax -= 1>>
 		<<if $endeventerror is undefined>>
-			<<run EventSystem.Pop(_ii)>>
+			<<run EventSystem.pop(_ii)>>
 		<</if>>
 		<<if $enemyno is 0>>
 			<<set $pronoun to 0>>
 			<<if $endeventerror is undefined>>
-				<<run EventSystem.Clear()>>
+				<<run EventSystem.clear()>>
 			<</if>>
 		<</if>>
 		<<set $npc.splice(_leindex, 1)>>
@@ -979,7 +979,7 @@ alternative way to write that:
 	<<set $monster to 0>>
 <</if>>
 
-<<run EventSystem.Push($passage, _npcno, $time)>>
+<<run EventSystem.push($passage, _npcno, $time)>>
 <<set $index to _npcno>>
 <</widget>>
 
diff --git a/game/base-system/persistent-npcs.twee b/game/base-system/persistent-npcs.twee
index 872fbf12aa..11dbd7e208 100644
--- a/game/base-system/persistent-npcs.twee
+++ b/game/base-system/persistent-npcs.twee
@@ -30,7 +30,7 @@
 		<<else>>
 			<<set $monster to 0>>
 		<</if>>
-		<<run EventSystem.Push($passage, _args[0], $time)>>
+		<<run EventSystem.push($passage, _args[0], $time)>>
 	<<else>>
 		<span class="red">[ERROR: NPC "<<print _temp1>>" is undefined in passage: "<<print $passage>>"! Please report this issue.]</span>
 
@@ -230,4 +230,4 @@
 <<for _per_keys range Object.keys($per_npc)>>
 	<<set $per_npc[_per_keys][_args[0]][_args[1]] to _args[2]>>
 <</for>>
-<</widget>>
\ No newline at end of file
+<</widget>>
diff --git a/game/overworld-town/loc-cafe/main.twee b/game/overworld-town/loc-cafe/main.twee
index f2d416a6ff..f1dadb597d 100644
--- a/game/overworld-town/loc-cafe/main.twee
+++ b/game/overworld-town/loc-cafe/main.twee
@@ -1450,7 +1450,7 @@ It arrives promptly; Wafting the delicious smell of fresh coffee up your nose.
 			<<set _photos_taken to 0>>
 			<<if $cameras_raised gte 1>>
 				<!-- Necessary as attempting to clear the first NPC if it did not exist would cause issues with $eventslot. -->
-				<<if EventSystem.IsSlotTaken(0)>>
+				<<if EventSystem.isSlotTaken(0)>>
 					<<clearsinglenpc 0>>
 				<</if>>
 				<span class="pink">
@@ -1473,7 +1473,7 @@ It arrives promptly; Wafting the delicious smell of fresh coffee up your nose.
 			<</if>>
 
 			<<if $cameras_raised gte 2>>
-				<<if EventSystem.IsSlotTaken(1)>>
+				<<if EventSystem.isSlotTaken(1)>>
 					<<clearsinglenpc 1>>
 				<</if>>
 				<span class="pink">
@@ -1496,7 +1496,7 @@ It arrives promptly; Wafting the delicious smell of fresh coffee up your nose.
 			<</if>>
 
 			<<if $cameras_raised gte 3>>
-				<<if EventSystem.IsSlotTaken(2)>>
+				<<if EventSystem.isSlotTaken(2)>>
 					<<clearsinglenpc 2>>
 				<</if>>
 				<span class="pink">
-- 
GitLab


From 4f2a7825928a92d1006e2f68d111bb505844e65c Mon Sep 17 00:00:00 2001
From: hwp <22502-hwp@users.noreply.gitgud.io>
Date: Tue, 27 Sep 2022 19:40:42 +0000
Subject: [PATCH 50/50] Cheat Menu Improvements

---
 game/04-Variables/variables-static.twee |  14 +
 game/base-system/overlays/cheats.twee   | 643 ++++++------------------
 2 files changed, 172 insertions(+), 485 deletions(-)

diff --git a/game/04-Variables/variables-static.twee b/game/04-Variables/variables-static.twee
index 0bd79676fd..981a99a149 100644
--- a/game/04-Variables/variables-static.twee
+++ b/game/04-Variables/variables-static.twee
@@ -650,4 +650,18 @@ and are required for processing for loops, default objects, etc.*/
 	"anteSizes":   [25000, 50000, 100000],
 }>>
 
+<<set setup.parasiteTypesPerBodypart to {
+	"nipples": ["none", "urchin", "slime"],
+	"penis": ["none", "urchin", "slime"],
+	"clit": ["none", "urchin", "slime"],
+	"bottom": ["none", "urchin", "slime", "maggot"],
+	"left_thigh": ["none", "maggot"],
+	"right_thigh": ["none", "maggot"],
+	"left_arm": ["none", "maggot"],
+	"right_arm": ["none", "maggot"],
+	"left_ear": ["none", "slime"],
+	"right_ear": ["none", "slime"],
+	"tummy": ["none", "maggot"],
+}>>
+
 <</widget>>
diff --git a/game/base-system/overlays/cheats.twee b/game/base-system/overlays/cheats.twee
index 63acaae181..6d248eda33 100644
--- a/game/base-system/overlays/cheats.twee
+++ b/game/base-system/overlays/cheats.twee
@@ -19,6 +19,62 @@ Can cause problems if confirmed during events, or with NPCs around.
 
 <</widget>>
 
+<<widget "cheatVirginityToggle">>
+	<<set _type to _args[0]>>
+	<<set _id to `stats${_type}virginity`>>
+	<<capture _type _id>>
+		<span @id="_id"><<print ($player.virginity[_type] is true ? "Present" : "Taken by " + ($player.virginity[_type] is false ? "unknown" : $player.virginity[_type]))>></span> |
+		<span @id="_id + 'link'"><<link `($player.virginity[_type] is true ? "Take" : "Restore")`>>
+			<<if $player.virginity[_type] is true>>
+				<<set $player.virginity[_type] to (_virginity[_type] is true ? false : _virginity[_type])>><<set $player.virginity.temple to false>>
+			<<else>>
+				<<set $player.virginity[_type] to true>>
+			<</if>>
+			<<run $(`#${_id}link .link-internal`).html($player.virginity[_type] is true ? "Take" : "Restore")>>
+			<<run $(`#${_id}`).html($player.virginity[_type] is true ? "Present" : "Taken by " + ($player.virginity[_type] is false ? "unknown" : $player.virginity[_type]))>>
+		<</link>></span>
+	<</capture>>
+<</widget>>
+
+<<widget "cheatParasiteToggle">>
+
+	<<set _bodypart to _args[0]>>
+	<<set _id to `stats${_bodypart}parasite`>>
+	<<capture _bodypart _id>>
+		<<set $_currentType to $parasite[_bodypart].name or "none">>
+		<<print _bodypart.toUpperFirst().replace("_", " ")>> parasite: <span @id="_id" class="gold"><<print $_currentType>></span> |
+	
+		<<set T["parasiteType"+_bodypart] to $_currentType>>
+		<<set _optionName to "_parasiteType"+_bodypart>>
+		<<for _parasiteOption range setup.parasiteTypesPerBodypart[_bodypart]>>
+			<label>_parasiteOption <<radiobutton `_optionName` _parasiteOption autocheck>></label> |
+		<</for>>
+		<<link "Set">>
+			<<removeparasite _bodypart>>
+
+			<<set _parasiteTypeActual to T["parasiteType"+_bodypart]>>
+			<<if _parasiteTypeActual isnot "none">>
+				<<parasite _bodypart _parasiteTypeActual>>
+			<</if>>
+			<<run $(`#${_id}`).html($parasite[_bodypart].name or "none")>>
+			<<updatesidebarimg>>
+		<</link>>
+	<</capture>>
+<</widget>>
+
+<<widget "cheatBodyliquidOnPart">>
+	<<set _part to _args[0]>>
+	<<set _label to _args[1]>>
+	<<set _type to _args[2]>>
+	<<capture _type _label _part>>
+		<<set _id to `stats${_part}${_type}`>>
+		<<link "<">><<bodyliquid _part _type -1>><<run $(`#stats${_part}${_type}`).html(Math.trunc($player.bodyliquid[_part][_type]))>><<updatesidebarimg>><</link>>
+		_label: <span @id="_id"><<print Math.trunc($player.bodyliquid[_part][_type])>></span>
+		<<link ">">><<bodyliquid _part _type 1>><<run $(`#stats${_part}${_type}`).html(Math.trunc($player.bodyliquid[_part][_type]))>><<updatesidebarimg>><</link>>
+		|
+	<</capture>>
+<</widget>>
+
 <<widget "cheats-characterStats">>
 
 <span class="gold">Miscellaneous</span>
@@ -44,7 +100,7 @@ Money: <span id="statsmoney"><<print Math.trunc($money)>></span>
 	<br>
 <</if>>
 
-Infinite spray: <span id="statsinfinitespray">$infinitespray</span> |
+Infinite spray: <span id="statsinfinitespray"><<print ($infinitespray ? "on" : "off")>></span> |
 <<link "Change">>
 	<<if $infinitespray is 1>>
 		<<set $infinitespray to 0>>
@@ -52,7 +108,7 @@ Infinite spray: <span id="statsinfinitespray">$infinitespray</span> |
 		<<spray 5>>
 		<<set $infinitespray to 1>>
 	<</if>>
-	<<replace "#statsinfinitespray">><<print $infinitespray>><</replace>>
+	<<replace "#statsinfinitespray">><<print ($infinitespray ? "on" : "off")>><</replace>>
 <</link>>
 <br>
 
@@ -243,74 +299,23 @@ Body size:
 	<</replace>>
 <</link>> |
 <br><br>
+
+<<set _virginity to clone($player.virginity)>>
 <<if $player.vaginaExist>>
-	Vaginal virginity: <span id="statsvaginalvirginity"><<print ($player.virginity.vaginal is true ? "Present" : "Taken by " + ($player.virginity.vaginal is false ? "unknown" : $player.virginity.vaginal))>></span> |
-	<<link "Change">>
-		<<if $player.virginity.vaginal is true>>
-			<<set $player.virginity.vaginal to false>><<set $player.virginity.temple to false>>
-		<<else>>
-			<<set $player.virginity.vaginal to true>>
-		<</if>>
-		<<replace "#statsvaginalvirginity">><<print ($player.virginity.vaginal is true ? "Present" : "Taken by " + ($player.virginity.vaginal is false ? "unknown" : $player.virginity.vaginal))>><</replace>>
-	<</link>>
+	Vaginal virginity: <<cheatVirginityToggle "vaginal">>
 	<br>
 <</if>>
-
 <<if $player.penisExist>>
-	Penile virginity: <span id="statspenilevirginity"><<print ($player.virginity.penile is true ? "Present" : "Taken by " + ($player.virginity.penile is false ? "unknown" : $player.virginity.penile))>></span> |
-	<<link "Change">>
-		<<if $player.virginity.penile is true>>
-			<<set $player.virginity.penile to false>><<set $player.virginity.temple to false>>
-		<<else>>
-			<<set $player.virginity.penile to true>>
-		<</if>>
-		<<replace "#statspenilevirginity">><<print ($player.virginity.penile is true ? "Present" : "Taken by " + ($player.virginity.penile is false ? "unknown" : $player.virginity.penile))>><</replace>>
-	<</link>>
+	Penile virginity: <<cheatVirginityToggle "penile">>
 	<br>
 <</if>>
-
-Anal virginity: <span id="statsanalvirginity"><<print ($player.virginity.anal is true ? "Present" : "Taken by " + ($player.virginity.anal is false ? "unknown" : $player.virginity.anal))>></span> |
-<<link "Change">>
-	<<if $player.virginity.anal is true>>
-		<<set $player.virginity.anal to false>>
-	<<else>>
-		<<set $player.virginity.anal to true>>
-	<</if>>
-	<<replace "#statsanalvirginity">><<print ($player.virginity.anal is true ? "Present" : "Taken by " + ($player.virginity.anal is false ? "unknown" : $player.virginity.anal))>><</replace>>
-<</link>>
+Anal virginity: <<cheatVirginityToggle "anal">>
 <br>
-
-Oral virginity: <span id="statsoralvirginity"><<print ($player.virginity.oral is true ? "Present" : "Taken by " + ($player.virginity.oral is false ? "unknown" : $player.virginity.oral))>></span> |
-<<link "Change">>
-	<<if $player.virginity.oral is true>>
-		<<set $player.virginity.oral to false>>
-	<<else>>
-		<<set $player.virginity.oral to true>>
-	<</if>>
-	<<replace "#statsoralvirginity">><<print ($player.virginity.oral is true ? "Present" : "Taken by " + ($player.virginity.oral is false ? "unknown" : $player.virginity.oral))>><</replace>>
-<</link>>
+Oral virginity: <<cheatVirginityToggle "oral">>
 <br>
-
-Handholding virginity: <span id="statshandholdingvirginity"><<print ($player.virginity.handholding is true ? "Present" : "Taken by " + ($player.virginity.handholding is false ? "unknown" : $player.virginity.handholding))>></span> |
-<<link "Change">>
-	<<if $player.virginity.handholding is true>>
-		<<set $player.virginity.handholding to false>>
-	<<else>>
-		<<set $player.virginity.handholding to true>>
-	<</if>>
-	<<replace "#statshandholdingvirginity">><<print ($player.virginity.handholding is true ? "Present" : "Taken by " + ($player.virginity.handholding is false ? "unknown" : $player.virginity.handholding))>><</replace>>
-<</link>>
+Handholding virginity: <<cheatVirginityToggle "handholding">>
 <br>
-
-First kiss: <span id="statskissvirginity"><<print ($player.virginity.kiss is true ? "Present" : "Taken by " + ($player.virginity.kiss is false ? "unknown" : $player.virginity.kiss))>></span> |
-<<link "Change">>
-	<<if $player.virginity.kiss is true>>
-		<<set $player.virginity.kiss to false>>
-	<<else>>
-		<<set $player.virginity.kiss to true>>
-	<</if>>
-	<<replace "#statskissvirginity">><<print ($player.virginity.kiss is true ? "Present" : "Taken by " + ($player.virginity.kiss is false ? "unknown" : $player.virginity.kiss))>><</replace>>
-<</link>>
+First kiss: <<cheatVirginityToggle "kiss">>
 <br><br>
 
 <span class="gold">State</span>
@@ -1169,470 +1174,138 @@ Between your legs is your: <span id="statsgenitals"><<genitals>></span>
 <br>
 
 <<if $parasitedisable is "f">>
-<span class="gold">Parasites</span>
-<br>
-Nipple parasites: <span id="statsnippleparasite"><<if $parasite.nipples.name>>$parasite.nipples.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.nipples.name>>
-<<removeparasite nipples>><<parasite nipples urchin>>
-<<elseif $parasite.nipples.name is "urchin">>
-<<removeparasite nipples>><<parasite nipples slime>>
-<<else>>
-<<removeparasite nipples>>
-<</if>>
-<<replace "#statsnippleparasite">><<print $parasite.nipples.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-<<if $player.penisExist>>
-	Penis parasites: <span id="statspenisparasite"><<if $parasite.penis.name>>$parasite.penis.name<<else>>None<</if>></span> |
-	<<link "Change">>
-	<<if !$parasite.penis.name>>
-	<<removeparasite penis>><<parasite penis urchin>>
-	<<elseif $parasite.penis.name is "urchin">>
-	<<removeparasite penis>><<parasite penis slime>>
-	<<else>>
-	<<removeparasite penis>>
-	<</if>>
-	<<replace "#statspenisparasite">><<print $parasite.penis.name>><</replace>>
-	<<updatesidebarimg>>
-	<</link>>
+	<span class="gold">Parasites</span>
 	<br>
-<</if>>
-
-<<if !$player.penisExist>>
-	Clit parasites: <span id="statsclitparasite"><<if $parasite.clit.name>>$parasite.clit.name<<else>>None<</if>></span> |
-	<<link "Change">>
-	<<if !$parasite.clit.name>>
-	<<removeparasite clit>><<parasite clit urchin>>
-	<<elseif $parasite.clit.name is "urchin">>
-	<<removeparasite clit>><<parasite clit slime>>
+	<<cheatParasiteToggle "nipples">>
+	<br>
+	<<if $player.penisExist>>
+		<<cheatParasiteToggle "penis">>
+		<br>
 	<<else>>
-	<<removeparasite clit>>
+		<<cheatParasiteToggle "clit">>
+		<br>
 	<</if>>
-	<<replace "#statsclitparasite">><<print $parasite.clit.name>><</replace>>
-	<<updatesidebarimg>>
-	<</link>>
+	<<cheatParasiteToggle "bottom">>
 	<br>
-<</if>>
-
-Ass parasites: <span id="statsbottomparasite"><<if $parasite.bottom.name>>$parasite.bottom.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.bottom.name>>
-	<<removeparasite bottom>><<parasite bottom urchin>>
-<<elseif $parasite.bottom.name is "urchin">>
-	<<removeparasite bottom>><<parasite bottom slime>>
-<<elseif $parasite.bottom.name is "slime">>
-	<<removeparasite bottom>><<parasite bottom maggot>>
-<<else>>
-	<<removeparasite bottom>>
-<</if>>
-<<replace "#statsbottomparasite">><<print $parasite.bottom.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-Left thigh Parasite:<span id="statsleft_thighparasite"><<if $parasite.left_thigh.name>>$parasite.left_thigh.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.left_thigh.name>>
-	<<removeparasite left_thigh>><<parasite left_thigh maggot>>
-<<else>>
-	<<removeparasite left_thigh>>
-<</if>>
-<<replace "#statsleft_thighparasite">><<print $parasite.left_thigh.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-
-Right thigh Parasite:<span id="statsright_thighparasite"><<if $parasite.right_thigh.name>>$parasite.right_thigh.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.right_thigh.name>>
-	<<removeparasite right_thigh>><<parasite right_thigh maggot>>
-<<else>>
-	<<removeparasite right_thigh>>
-<</if>>
-<<replace "#statsright_thighparasite">><<print $parasite.right_thigh.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-Left arm parasite:<span id="statsleft_armparasite"><<if $parasite.left_arm.name>>$parasite.left_arm.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.left_arm.name>>
-	<<removeparasite left_arm>><<parasite left_arm maggot>>
-<<else>>
-	<<removeparasite left_arm>>
-<</if>>
-<<replace "#statsleft_armparasite">><<print $parasite.left_arm.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-Right arm parasite:<span id="statsright_armparasite"><<if $parasite.right_arm.name>>$parasite.right_arm.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.right_arm.name>>
-	<<removeparasite right_arm>><<parasite right_arm maggot>>
-<<else>>
-	<<removeparasite right_arm>>
-<</if>>
-<<replace "#statsright_armparasite">><<print $parasite.right_arm.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-Tummy parasite:<span id="statstummyparasite"><<if $parasite.tummy.name>>$parasite.tummy.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.tummy.name>>
-	<<removeparasite tummy>><<parasite tummy maggot>>
-<<else>>
-	<<removeparasite tummy>>
-<</if>>
-<<replace "#statstummyparasite">><<print $parasite.tummy.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-
-
-Left ear parasite: <span id="statsleft_earparasite"><<if $parasite.left_ear.name>>$parasite.left_ear.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.left_ear.name>>
-<<removeparasite left_ear>><<parasite left_ear slime>>
-<<else>>
-<<removeparasite left_ear>>
-<</if>>
-<<replace "#statsleft_earparasite">><<print $parasite.left_ear.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-<br>
-
-Right ear parasite: <span id="statsright_earparasite"><<if $parasite.right_ear.name>>$parasite.right_ear.name<<else>>None<</if>></span> |
-<<link "Change">>
-<<if !$parasite.right_ear.name>>
-<<removeparasite right_ear>><<parasite right_ear slime>>
-<<else>>
-<<removeparasite right_ear>>
-<</if>>
-<<replace "#statsright_earparasite">><<print $parasite.right_ear.name>><</replace>>
- <<updatesidebarimg>>
-<</link>>
-
-<br><br>
+	<<cheatParasiteToggle "left_thigh">>
+	<br>
+	<<cheatParasiteToggle "right_thigh">>
+	<br>
+	<<cheatParasiteToggle "left_arm">>
+	<br>
+	<<cheatParasiteToggle "right_arm">>
+	<br>
+	<<cheatParasiteToggle "tummy">>
+	<br>
+	<<cheatParasiteToggle "left_ear">>
+	<br>
+	<<cheatParasiteToggle "right_ear">>
+	<br><br>
 <</if>>
 
 <span class="gold">Semen</span>
 <br>
 <<link "Add all semen">>
-<!-- todosemen -->
-<<bodyliquid "neck" "semen" 5>><<replace "#statsnecksemen">><<print Math.trunc($player.bodyliquid.neck.semen )>><</replace>>
-<<bodyliquid "rightarm" "semen" 5>><<replace "#statsrightarmsemen">><<print Math.trunc($player.bodyliquid.rightarm.semen )>><</replace>>
-<<bodyliquid "leftarm" "semen" 5>><<replace "#statsleftarmsemen">><<print Math.trunc($player.bodyliquid.leftarm.semen )>><</replace>>
-<<bodyliquid "thigh" "semen" 5>><<replace "#statsthighsemen">><<print Math.trunc($player.bodyliquid.thigh.semen )>><</replace>>
-<<bodyliquid "bottom" "semen" 5>><<replace "#statsbottomsemen">><<print Math.trunc($player.bodyliquid.bottom.semen )>><</replace>>
-<<bodyliquid "tummy" "semen" 5>><<replace "#statstummysemen">><<print Math.trunc($player.bodyliquid.tummy.semen )>><</replace>>
-<<bodyliquid "chest" "semen" 5>><<replace "#statschestsemen">><<print Math.trunc($player.bodyliquid.chest.semen )>><</replace>>
-<<bodyliquid "face" "semen" 5>><<replace "#statsfacesemen">><<print Math.trunc($player.bodyliquid.face.semen )>><</replace>>
-<<bodyliquid "hair" "semen" 5>><<replace "#statshairsemen">><<print Math.trunc($player.bodyliquid.hair.semen )>><</replace>>
-<<bodyliquid "feet" "semen" 5>><<replace "#statsfeetsemen">><<print Math.trunc($player.bodyliquid.feet.semen )>><</replace>>
-<<bodyliquid "vaginaoutside" "semen" 5>><<replace "#statsvaginaoutsidesemen">><<print Math.trunc($player.bodyliquid.vaginaoutside.semen )>><</replace>>
-<<bodyliquid "vagina" "semen" 5>><<replace "#statsvaginasemen">><<print Math.trunc($player.bodyliquid.vagina.semen )>><</replace>>
-<<bodyliquid "penis" "semen" 5>><<replace "#statspenissemen">><<print Math.trunc($player.bodyliquid.penis.semen )>><</replace>>
-<<bodyliquid "anus" "semen" 5>><<replace "#statsanussemen">><<print Math.trunc($player.bodyliquid.anus.semen )>><</replace>>
-<<bodyliquid "mouth" "semen" 5>><<replace "#statsmouthsemen">><<print Math.trunc($player.bodyliquid.mouth.semen )>><</replace>>
- <<updatesidebarimg>>
+	<<for _type range ["neck","rightarm","leftarm","thigh","bottom","tummy","chest","face","hair","feet","vaginaoutside","vagina","penis","anus","mouth"]>>
+		<<bodyliquid _type "semen" 5>><<run $(`#stats${_type}semen`).html(Math.trunc($player.bodyliquid[_type].semen))>>	
+	<</for>>
+	<<updatesidebarimg>>
 <</link>> |
 
 <<link "Remove all semen">>
-<<bodyliquid "neck" "semen" -5>><<replace "#statsnecksemen">><<print Math.trunc($player.bodyliquid.neck.semen )>><</replace>>
-<<bodyliquid "rightarm" "semen" -5>><<replace "#statsrightarmsemen">><<print Math.trunc($player.bodyliquid.rightarm.semen )>><</replace>>
-<<bodyliquid "leftarm" "semen" -5>><<replace "#statsleftarmsemen">><<print Math.trunc($player.bodyliquid.leftarm.semen )>><</replace>>
-<<bodyliquid "thigh" "semen" -5>><<replace "#statsthighsemen">><<print Math.trunc($player.bodyliquid.thigh.semen )>><</replace>>
-<<bodyliquid "bottom" "semen" -5>><<replace "#statsbottomsemen">><<print Math.trunc($player.bodyliquid.bottom.semen )>><</replace>>
-<<bodyliquid "tummy" "semen" -5>><<replace "#statstummysemen">><<print Math.trunc($player.bodyliquid.tummy.semen )>><</replace>>
-<<bodyliquid "chest" "semen" -5>><<replace "#statschestsemen">><<print Math.trunc($player.bodyliquid.chest.semen )>><</replace>>
-<<bodyliquid "face" "semen" -5>><<replace "#statsfacesemen">><<print Math.trunc($player.bodyliquid.face.semen )>><</replace>>
-<<bodyliquid "hair" "semen" -5>><<replace "#statshairsemen">><<print Math.trunc($player.bodyliquid.hair.semen )>><</replace>>
-<<bodyliquid "feet" "semen" -5>><<replace "#statsfeetsemen">><<print Math.trunc($player.bodyliquid.feet.semen )>><</replace>>
-<<bodyliquid "vaginaoutside" "semen" -5>><<replace "#statsvaginaoutsidesemen">><<print Math.trunc($player.bodyliquid.vaginaoutside.semen )>><</replace>>
-<<bodyliquid "vagina" "semen" -5>><<replace "#statsvaginasemen">><<print Math.trunc($player.bodyliquid.vagina.semen )>><</replace>>
-<<bodyliquid "penis" "semen" -5>><<replace "#statspenissemen">><<print Math.trunc($player.bodyliquid.penis.semen )>><</replace>>
-<<bodyliquid "anus" "semen" -5>><<replace "#statsanussemen">><<print Math.trunc($player.bodyliquid.anus.semen )>><</replace>>
-<<bodyliquid "mouth" "semen" -5>><<replace "#statsmouthsemen">><<print Math.trunc($player.bodyliquid.mouth.semen )>><</replace>>
- <<updatesidebarimg>>
+	<<for _type range ["neck","rightarm","leftarm","thigh","bottom","tummy","chest","face","hair","feet","vaginaoutside","vagina","penis","anus","mouth"]>>
+		<<bodyliquid _type "semen" -5>><<run $(`#stats${_type}semen`).html(Math.trunc($player.bodyliquid[_type].semen))>>
+	<</for>>
+	<<updatesidebarimg>>
 <</link>> |
 
 <br>
 
-<<link "<">><<bodyliquid "neck" "semen" -1>><<replace "#statsnecksemen">><<print Math.trunc($player.bodyliquid.neck.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Neck semen: <span id="statsnecksemen"><<print Math.trunc($player.bodyliquid.neck.semen )>></span>
-<<link ">">><<bodyliquid "neck" "semen">><<replace "#statsnecksemen">><<print Math.trunc($player.bodyliquid.neck.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "rightarm" "semen" -1>><<replace "#statsrightarmsemen">><<print Math.trunc($player.bodyliquid.rightarm.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Right arm semen: <span id="statsrightarmsemen"><<print Math.trunc($player.bodyliquid.rightarm.semen )>></span>
-<<link ">">><<bodyliquid "rightarm" "semen">><<replace "#statsrightarmsemen">><<print Math.trunc($player.bodyliquid.rightarm.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "leftarm" "semen" -1>><<replace "#statsleftarmsemen">><<print Math.trunc($player.bodyliquid.leftarm.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Left arm semen: <span id="statsleftarmsemen"><<print Math.trunc($player.bodyliquid.leftarm.semen )>></span>
-<<link ">">><<bodyliquid "leftarm" "semen">><<replace "#statsleftarmsemen">><<print Math.trunc($player.bodyliquid.leftarm.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "thigh" "semen" -1>><<replace "#statsthighsemen">><<print Math.trunc($player.bodyliquid.thigh.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Thigh semen: <span id="statsthighsemen"><<print Math.trunc($player.bodyliquid.thigh.semen )>></span>
-<<link ">">><<bodyliquid "thigh" "semen">><<replace "#statsthighsemen">><<print Math.trunc($player.bodyliquid.thigh.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "bottom" "semen" -1>><<replace "#statsbottomsemen">><<print Math.trunc($player.bodyliquid.bottom.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Bottom semen: <span id="statsbottomsemen"><<print Math.trunc($player.bodyliquid.bottom.semen )>></span>
-<<link ">">><<bodyliquid "bottom" "semen">><<replace "#statsbottomsemen">><<print Math.trunc($player.bodyliquid.bottom.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "tummy" "semen" -1>><<replace "#statstummysemen">><<print Math.trunc($player.bodyliquid.tummy.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Tummy semen: <span id="statstummysemen"><<print Math.trunc($player.bodyliquid.tummy.semen )>></span>
-<<link ">">><<bodyliquid "tummy" "semen">><<replace "#statstummysemen">><<print Math.trunc($player.bodyliquid.tummy.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "chest" "semen" -1>><<replace "#statschestsemen">><<print Math.trunc($player.bodyliquid.chest.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Chest semen: <span id="statschestsemen"><<print Math.trunc($player.bodyliquid.chest.semen )>></span>
-<<link ">">><<bodyliquid "chest" "semen">><<replace "#statschestsemen">><<print Math.trunc($player.bodyliquid.chest.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "face" "semen" -1>><<replace "#statsfacesemen">><<print Math.trunc($player.bodyliquid.face.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Face semen: <span id="statsfacesemen"><<print Math.trunc($player.bodyliquid.face.semen )>></span>
-<<link ">">><<bodyliquid "face" "semen">><<replace "#statsfacesemen">><<print Math.trunc($player.bodyliquid.face.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "hair" "semen" -1>><<replace "#statshairsemen">><<print Math.trunc($player.bodyliquid.hair.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Hair semen: <span id="statshairsemen"><<print Math.trunc($player.bodyliquid.hair.semen )>></span>
-<<link ">">><<bodyliquid "hair" "semen">><<replace "#statshairsemen">><<print Math.trunc($player.bodyliquid.hair.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "feet" "semen" -1>><<replace "#statsfeetsemen">><<print Math.trunc($player.bodyliquid.feet.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Feet semen: <span id="statsfeetsemen"><<print Math.trunc($player.bodyliquid.feet.semen )>></span>
-<<link ">">><<bodyliquid "feet" "semen">><<replace "#statsfeetsemen">><<print Math.trunc($player.bodyliquid.feet.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "vaginaoutside" "semen" -1>><<replace "#statsvaginaoutsidesemen">><<print Math.trunc($player.bodyliquid.vaginaoutside.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Labia semen: <span id="statsvaginaoutsidesemen"><<print Math.trunc($player.bodyliquid.vaginaoutside.semen )>></span>
-<<link ">">><<bodyliquid "vaginaoutside" "semen">><<replace "#statsvaginaoutsidesemen">><<print Math.trunc($player.bodyliquid.vaginaoutside.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "vagina" "semen" -1>><<replace "#statsvaginasemen">><<print Math.trunc($player.bodyliquid.vagina.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Vagina semen: <span id="statsvaginasemen"><<print Math.trunc($player.bodyliquid.vagina.semen )>></span>
-<<link ">">><<bodyliquid "vagina" "semen">><<replace "#statsvaginasemen">><<print Math.trunc($player.bodyliquid.vagina.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "penis" "semen" -1>><<replace "#statspenissemen">><<print Math.trunc($player.bodyliquid.penis.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Penis semen: <span id="statspenissemen"><<print Math.trunc($player.bodyliquid.penis.semen )>></span>
-<<link ">">><<bodyliquid "penis" "semen">><<replace "#statspenissemen">><<print Math.trunc($player.bodyliquid.penis.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "anus" "semen" -1>><<replace "#statsanussemen">><<print Math.trunc($player.bodyliquid.anus.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Anus semen: <span id="statsanussemen"><<print Math.trunc($player.bodyliquid.anus.semen )>></span>
-<<link ">">><<bodyliquid "anus" "semen">><<replace "#statsanussemen">><<print Math.trunc($player.bodyliquid.anus.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "mouth" "semen" -1>><<replace "#statsmouthsemen">><<print Math.trunc($player.bodyliquid.mouth.semen )>><</replace>> <<updatesidebarimg>><</link>>
-Mouth semen: <span id="statsmouthsemen"><<print Math.trunc($player.bodyliquid.mouth.semen )>></span>
- <<link ">">><<bodyliquid "mouth" "semen" 1>><<replace "#statsmouthsemen">><<print Math.trunc($player.bodyliquid.mouth.semen )>><</replace>> <<updatesidebarimg>><</link>>
-|
+<<cheatBodyliquidOnPart "neck" "Neck" "semen">>
+<<cheatBodyliquidOnPart "rightarm" "Right arm" "semen">>
+<<cheatBodyliquidOnPart "leftarm" "Left arm" "semen">>
+<<cheatBodyliquidOnPart "thigh" "Thigh" "semen">>
+<<cheatBodyliquidOnPart "bottom" "Bottom" "semen">>
+<<cheatBodyliquidOnPart "tummy" "Tummy" "semen">>
+<<cheatBodyliquidOnPart "chest" "Chest" "semen">>
+<<cheatBodyliquidOnPart "face" "Face" "semen">>
+<<cheatBodyliquidOnPart "hair" "Hair" "semen">>
+<<cheatBodyliquidOnPart "feet" "Feet" "semen">>
+<<cheatBodyliquidOnPart "vaginaoutside" "Labia" "semen">>
+<<cheatBodyliquidOnPart "vagina" "Vagina" "semen">>
+<<cheatBodyliquidOnPart "penis" "Penis" "semen">>
+<<cheatBodyliquidOnPart "anus" "Anus" "semen">>
+<<cheatBodyliquidOnPart "mouth" "Mouth" "semen">>
 <br><br>
 
 <span class="gold">Slime</span>
 <br>
 <<link "Add all slime">>
-<<bodyliquid "neck" "goo" 5>><<replace "#statsneckgoo">><<print Math.trunc($player.bodyliquid.neck.goo)>><</replace>>
-<<bodyliquid "rightarm" "goo" 5>><<replace "#statsrightarmgoo">><<print Math.trunc($player.bodyliquid.rightarm.goo)>><</replace>>
-<<bodyliquid "leftarm" "goo" 5>><<replace "#statsleftarmgoo">><<print Math.trunc($player.bodyliquid.leftarm.goo)>><</replace>>
-<<bodyliquid "thigh" "goo" 5>><<replace "#statsthighgoo">><<print Math.trunc($player.bodyliquid.thigh.goo)>><</replace>>
-<<bodyliquid "bottom" "goo" 5>><<replace "#statsbottomgoo">><<print Math.trunc($player.bodyliquid.bottom.goo)>><</replace>>
-<<bodyliquid "tummy" "goo" 5>><<replace "#statstummygoo">><<print Math.trunc($player.bodyliquid.tummy.goo)>><</replace>>
-<<bodyliquid "chest" "goo" 5>><<replace "#statschestgoo">><<print Math.trunc($player.bodyliquid.chest.goo)>><</replace>>
-<<bodyliquid "face" "goo" 5>><<replace "#statsfacegoo">><<print Math.trunc($player.bodyliquid.face.goo)>><</replace>>
-<<bodyliquid "hair" "goo" 5>><<replace "#statshairgoo">><<print Math.trunc($player.bodyliquid.hair.goo)>><</replace>>
-<<bodyliquid "feet" "goo" 5>><<replace "#statsfeetgoo">><<print Math.trunc($player.bodyliquid.feet.goo)>><</replace>>
-<<bodyliquid "vaginaoutside" "goo" 5>><<replace "#statsvaginaoutsidegoo">><<print Math.trunc($player.bodyliquid.vaginaoutside.goo)>><</replace>>
-<<bodyliquid "vagina" "goo" 5>><<replace "#statsvaginagoo">><<print Math.trunc($player.bodyliquid.vagina.goo)>><</replace>>
-<<bodyliquid "penis" "goo" 5>><<replace "#statspenisgoo">><<print Math.trunc($player.bodyliquid.penis.goo)>><</replace>>
-<<bodyliquid "anus" "goo" 5>><<replace "#statsanusgoo">><<print Math.trunc($player.bodyliquid.anus.goo)>><</replace>>
-<<bodyliquid "mouth" "goo" 5>><<replace "#statsmouthgoo">><<print Math.trunc($player.bodyliquid.mouth.goo)>><</replace>>
- <<updatesidebarimg>>
+	<<for _type range ["neck","rightarm","leftarm","thigh","bottom","tummy","chest","face","hair","feet","vaginaoutside","vagina","penis","anus","mouth"]>>
+		<<bodyliquid _type "goo" 5>><<run $(`#stats${_type}goo`).html(Math.trunc($player.bodyliquid[_type].goo))>>	
+	<</for>>
+	<<updatesidebarimg>>
 <</link>> |
 
 <<link "Remove all slime">>
-<<bodyliquid "neck" "goo" -5>><<replace "#statsneckgoo">><<print Math.trunc($player.bodyliquid.neck.goo)>><</replace>>
-<<bodyliquid "rightarm" "goo" -5>><<replace "#statsrightarmgoo">><<print Math.trunc($player.bodyliquid.rightarm.goo)>><</replace>>
-<<bodyliquid "leftarm" "goo" -5>><<replace "#statsleftarmgoo">><<print Math.trunc($player.bodyliquid.leftarm.goo)>><</replace>>
-<<bodyliquid "thigh" "goo" -5>><<replace "#statsthighgoo">><<print Math.trunc($player.bodyliquid.thigh.goo)>><</replace>>
-<<bodyliquid "bottom" "goo" -5>><<replace "#statsbottomgoo">><<print Math.trunc($player.bodyliquid.bottom.goo)>><</replace>>
-<<bodyliquid "tummy" "goo" -5>><<replace "#statstummygoo">><<print Math.trunc($player.bodyliquid.tummy.goo)>><</replace>>
-<<bodyliquid "chest" "goo" -5>><<replace "#statschestgoo">><<print Math.trunc($player.bodyliquid.chest.goo)>><</replace>>
-<<bodyliquid "face" "goo" -5>><<replace "#statsfacegoo">><<print Math.trunc($player.bodyliquid.face.goo)>><</replace>>
-<<bodyliquid "hair" "goo" -5>><<replace "#statshairgoo">><<print Math.trunc($player.bodyliquid.hair.goo)>><</replace>>
-<<bodyliquid "feet" "goo" -5>><<replace "#statsfeetgoo">><<print Math.trunc($player.bodyliquid.feet.goo)>><</replace>>
-<<bodyliquid "vaginaoutside" "goo" -5>><<replace "#statsvaginaoutsidegoo">><<print Math.trunc($player.bodyliquid.vaginaoutside.goo)>><</replace>>
-<<bodyliquid "vagina" "goo" -5>><<replace "#statsvaginagoo">><<print Math.trunc($player.bodyliquid.vagina.goo)>><</replace>>
-<<bodyliquid "penis" "goo" -5>><<replace "#statspenisgoo">><<print Math.trunc($player.bodyliquid.penis.goo)>><</replace>>
-<<bodyliquid "anus" "goo" -5>><<replace "#statsanusgoo">><<print Math.trunc($player.bodyliquid.anus.goo)>><</replace>>
-<<bodyliquid "mouth" "goo" -5>><<replace "#statsmouthgoo">><<print Math.trunc($player.bodyliquid.mouth.goo)>><</replace>>
- <<updatesidebarimg>>
+	<<for _type range ["neck","rightarm","leftarm","thigh","bottom","tummy","chest","face","hair","feet","vaginaoutside","vagina","penis","anus","mouth"]>>
+		<<bodyliquid _type "goo" -5>><<run $(`#stats${_type}goo`).html(Math.trunc($player.bodyliquid[_type].goo))>>
+	<</for>>
+	<<updatesidebarimg>>
 <</link>> |
 
 <br>
 
-<<link "<">><<bodyliquid "neck" "semen" -1>><<replace "#statsneckgoo">><<print Math.trunc($player.bodyliquid.neck.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Neck slime: <span id="statsneckgoo"><<print Math.trunc($player.bodyliquid.neck.goo)>></span>
-<<link ">">><<bodyliquid "neck" "goo">><<replace "#statsneckgoo">><<print Math.trunc($player.bodyliquid.neck.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "rightarm" "goo" -1>><<replace "#statsrightarmgoo">><<print Math.trunc($player.bodyliquid.rightarm.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Right arm slime: <span id="statsrightarmgoo"><<print Math.trunc($player.bodyliquid.rightarm.goo)>></span>
-<<link ">">><<bodyliquid "rightarm" "goo">><<replace "#statsrightarmgoo">><<print Math.trunc($player.bodyliquid.rightarm.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "leftarm" "goo" -1>><<replace "#statsleftarmgoo">><<print Math.trunc($player.bodyliquid.leftarm.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Left arm slime: <span id="statsleftarmgoo"><<print Math.trunc($player.bodyliquid.leftarm.goo)>></span>
-<<link ">">><<bodyliquid "leftarm" "goo">><<replace "#statsleftarmgoo">><<print Math.trunc($player.bodyliquid.leftarm.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "thigh" "goo" -1>><<replace "#statsthighgoo">><<print Math.trunc($player.bodyliquid.thigh.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Thigh slime: <span id="statsthighgoo"><<print Math.trunc($player.bodyliquid.thigh.goo)>></span>
-<<link ">">><<bodyliquid "thigh" "goo">><<replace "#statsthighgoo">><<print Math.trunc($player.bodyliquid.thigh.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "bottom" "goo" -1>><<replace "#statsbottomgoo">><<print Math.trunc($player.bodyliquid.bottom.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Bottom slime: <span id="statsbottomgoo"><<print Math.trunc($player.bodyliquid.bottom.goo)>></span>
-<<link ">">><<bodyliquid "bottom" "goo">><<replace "#statsbottomgoo">><<print Math.trunc($player.bodyliquid.bottom.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "tummy" "goo" -1>><<replace "#statstummygoo">><<print Math.trunc($player.bodyliquid.tummy.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Tummy slime: <span id="statstummygoo"><<print Math.trunc($player.bodyliquid.tummy.goo)>></span>
-<<link ">">><<bodyliquid "tummy" "goo">><<replace "#statstummygoo">><<print Math.trunc($player.bodyliquid.tummy.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "chest" "goo" -1>><<replace "#statschestgoo">><<print Math.trunc($player.bodyliquid.chest.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Chest slime: <span id="statschestgoo"><<print Math.trunc($player.bodyliquid.chest.goo)>></span>
-<<link ">">><<bodyliquid "chest" "goo">><<replace "#statschestgoo">><<print Math.trunc($player.bodyliquid.chest.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "face" "goo" -1>><<replace "#statsfacegoo">><<print Math.trunc($player.bodyliquid.face.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Face slime: <span id="statsfacegoo"><<print Math.trunc($player.bodyliquid.face.goo)>></span>
-<<link ">">><<bodyliquid "face" "goo">><<replace "#statsfacegoo">><<print Math.trunc($player.bodyliquid.face.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "hair" "goo" -1>><<replace "#statshairgoo">><<print Math.trunc($player.bodyliquid.hair.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Hair slime: <span id="statshairgoo"><<print Math.trunc($player.bodyliquid.hair.goo)>></span>
-<<link ">">><<bodyliquid "hair" "goo">><<replace "#statshairgoo">><<print Math.trunc($player.bodyliquid.hair.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "feet" "goo" -1>><<replace "#statsfeetgoo">><<print Math.trunc($player.bodyliquid.feet.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Feet slime: <span id="statsfeetgoo"><<print Math.trunc($player.bodyliquid.feet.goo)>></span>
-<<link ">">><<bodyliquid "feet" "goo">><<replace "#statsfeetgoo">><<print Math.trunc($player.bodyliquid.feet.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "vaginaoutside" "goo" -1>><<replace "#statsvaginaoutsidegoo">><<print Math.trunc($player.bodyliquid.vaginaoutside.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Labia slime: <span id="statsvaginaoutsidegoo"><<print Math.trunc($player.bodyliquid.vaginaoutside.goo)>></span>
-<<link ">">><<bodyliquid "vaginaoutside" "goo">><<replace "#statsvaginaoutsidegoo">><<print Math.trunc($player.bodyliquid.vaginaoutside.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "vagina" "goo" -1>><<replace "#statsvaginagoo">><<print Math.trunc($player.bodyliquid.vagina.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Vagina slime: <span id="statsvaginagoo"><<print Math.trunc($player.bodyliquid.vagina.goo)>></span>
-<<link ">">><<bodyliquid "vagina" "goo">><<replace "#statsvaginagoo">><<print Math.trunc($player.bodyliquid.vagina.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "penis" "goo" -1>><<replace "#statspenisgoo">><<print Math.trunc($player.bodyliquid.penis.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Penis slime: <span id="statspenisgoo"><<print Math.trunc($player.bodyliquid.penis.goo)>></span>
-<<link ">">><<bodyliquid "penis" "goo">><<replace "#statspenisgoo">><<print Math.trunc($player.bodyliquid.penis.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "anus" "goo" -1>><<replace "#statsanusgoo">><<print Math.trunc($player.bodyliquid.anus.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Anus slime: <span id="statsanusgoo"><<print Math.trunc($player.bodyliquid.anus.goo)>></span>
-<<link ">">><<bodyliquid "anus" "goo">><<replace "#statsanusgoo">><<print Math.trunc($player.bodyliquid.anus.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "mouth" "goo" -1>><<replace "#statsmouthgoo">><<print Math.trunc($player.bodyliquid.mouth.goo)>><</replace>> <<updatesidebarimg>><</link>>
-Mouth slime: <span id="statsmouthgoo"><<print Math.trunc($player.bodyliquid.mouth.goo)>></span>
-<<link ">">><<bodyliquid "mouth" "goo">><<replace "#statsmouthgoo">><<print Math.trunc($player.bodyliquid.mouth.goo)>><</replace>> <<updatesidebarimg>><</link>>
-|
+<<cheatBodyliquidOnPart "neck" "Neck" "goo">>
+<<cheatBodyliquidOnPart "rightarm" "Right arm" "goo">>
+<<cheatBodyliquidOnPart "leftarm" "Left arm" "goo">>
+<<cheatBodyliquidOnPart "thigh" "Thigh" "goo">>
+<<cheatBodyliquidOnPart "bottom" "Bottom" "goo">>
+<<cheatBodyliquidOnPart "tummy" "Tummy" "goo">>
+<<cheatBodyliquidOnPart "chest" "Chest" "goo">>
+<<cheatBodyliquidOnPart "face" "Face" "goo">>
+<<cheatBodyliquidOnPart "hair" "Hair" "goo">>
+<<cheatBodyliquidOnPart "feet" "Feet" "goo">>
+<<cheatBodyliquidOnPart "vaginaoutside" "Labia" "goo">>
+<<cheatBodyliquidOnPart "vagina" "Vagina" "goo">>
+<<cheatBodyliquidOnPart "penis" "Penis" "goo">>
+<<cheatBodyliquidOnPart "anus" "Anus" "goo">>
+<<cheatBodyliquidOnPart "mouth" "Mouth" "goo">>
 <br><br>
 
 <span class="gold">Nectar</span>
 <br>
 <<link "Add all nectar">>
-<<bodyliquid "neck" "nectar" 5>><<replace "#statsnecknectar">><<print Math.trunc($player.bodyliquid.neck.nectar)>><</replace>>
-<<bodyliquid "rightarm" "nectar" 5>><<replace "#statsrightarmnectar">><<print Math.trunc($player.bodyliquid.rightarm.nectar)>><</replace>>
-<<bodyliquid "leftarm" "nectar" 5>><<replace "#statsleftarmnectar">><<print Math.trunc($player.bodyliquid.leftarm.nectar)>><</replace>>
-<<bodyliquid "thigh" "nectar" 5>><<replace "#statsthighnectar">><<print Math.trunc($player.bodyliquid.thigh.nectar)>><</replace>>
-<<bodyliquid "bottom" "nectar" 5>><<replace "#statsbottomnectar">><<print Math.trunc($player.bodyliquid.bottom.nectar)>><</replace>>
-<<bodyliquid "tummy" "nectar" 5>><<replace "#statstummynectar">><<print Math.trunc($player.bodyliquid.tummy.nectar)>><</replace>>
-<<bodyliquid "chest" "nectar" 5>><<replace "#statschestnectar">><<print Math.trunc($player.bodyliquid.chest.nectar)>><</replace>>
-<<bodyliquid "face" "nectar" 5>><<replace "#statsfacenectar">><<print Math.trunc($player.bodyliquid.face.nectar)>><</replace>>
-<<bodyliquid "hair" "nectar" 5>><<replace "#statshairnectar">><<print Math.trunc($player.bodyliquid.hair.nectar)>><</replace>>
-<<bodyliquid "feet" "nectar" 5>><<replace "#statsfeetnectar">><<print Math.trunc($player.bodyliquid.feet.nectar)>><</replace>>
-<<bodyliquid "vaginaoutside" "nectar" 5>><<replace "#statsvaginaoutsidenectar">><<print Math.trunc($player.bodyliquid.vaginaoutside.nectar)>><</replace>>
-<<bodyliquid "vagina" "nectar" 5>><<replace "#statsvaginanectar">><<print Math.trunc($player.bodyliquid.vagina.nectar)>><</replace>>
-<<bodyliquid "penis" "nectar" 5>><<replace "#statspenisnectar">><<print Math.trunc($player.bodyliquid.penis.nectar)>><</replace>>
-<<bodyliquid "anus" "nectar" 5>><<replace "#statsanusnectar">><<print Math.trunc($player.bodyliquid.anus.nectar)>><</replace>>
-<<bodyliquid "mouth" "nectar" 5>><<replace "#statsmouthnectar">><<print Math.trunc($player.bodyliquid.mouth.nectar)>><</replace>>
- <<updatesidebarimg>>
+	<<for _type range ["neck","rightarm","leftarm","thigh","bottom","tummy","chest","face","hair","feet","vaginaoutside","vagina","penis","anus","mouth"]>>
+		<<bodyliquid _type "nectar" 5>><<run $(`#stats${_type}nectar`).html(Math.trunc($player.bodyliquid[_type].nectar))>>	
+	<</for>>
+	<<updatesidebarimg>>
 <</link>> |
 
 <<link "Remove all nectar">>
-<<bodyliquid "neck" "nectar" -5>><<replace "#statsnecknectar">><<print Math.trunc($player.bodyliquid.neck.nectar)>><</replace>>
-<<bodyliquid "rightarm" "nectar" -5>><<replace "#statsrightarmnectar">><<print Math.trunc($player.bodyliquid.rightarm.nectar)>><</replace>>
-<<bodyliquid "leftarm" "nectar" -5>><<replace "#statsleftarmnectar">><<print Math.trunc($player.bodyliquid.leftarm.nectar)>><</replace>>
-<<bodyliquid "thigh" "nectar" -5>><<replace "#statsthighnectar">><<print Math.trunc($player.bodyliquid.thigh.nectar)>><</replace>>
-<<bodyliquid "bottom" "nectar" -5>><<replace "#statsbottomnectar">><<print Math.trunc($player.bodyliquid.bottom.nectar)>><</replace>>
-<<bodyliquid "tummy" "nectar" -5>><<replace "#statstummynectar">><<print Math.trunc($player.bodyliquid.tummy.nectar)>><</replace>>
-<<bodyliquid "chest" "nectar" -5>><<replace "#statschestnectar">><<print Math.trunc($player.bodyliquid.chest.nectar)>><</replace>>
-<<bodyliquid "face" "nectar" -5>><<replace "#statsfacenectar">><<print Math.trunc($player.bodyliquid.face.nectar)>><</replace>>
-<<bodyliquid "hair" "nectar" -5>><<replace "#statshairnectar">><<print Math.trunc($player.bodyliquid.hair.nectar)>><</replace>>
-<<bodyliquid "feet" "nectar" -5>><<replace "#statsfeetnectar">><<print Math.trunc($player.bodyliquid.feet.nectar)>><</replace>>
-<<bodyliquid "vaginaoutside" "nectar" -5>><<replace "#statsvaginaoutsidenectar">><<print Math.trunc($player.bodyliquid.vaginaoutside.nectar)>><</replace>>
-<<bodyliquid "vagina" "nectar" -5>><<replace "#statsvaginanectar">><<print Math.trunc($player.bodyliquid.vagina.nectar)>><</replace>>
-<<bodyliquid "penis" "nectar" -5>><<replace "#statspenisnectar">><<print Math.trunc($player.bodyliquid.penis.nectar)>><</replace>>
-<<bodyliquid "anus" "nectar" -5>><<replace "#statsanusnectar">><<print Math.trunc($player.bodyliquid.anus.nectar)>><</replace>>
-<<bodyliquid "mouth" "nectar" -5>><<replace "#statsmouthnectar">><<print Math.trunc($player.bodyliquid.mouth.nectar)>><</replace>>
- <<updatesidebarimg>>
+	<<for _type range ["neck","rightarm","leftarm","thigh","bottom","tummy","chest","face","hair","feet","vaginaoutside","vagina","penis","anus","mouth"]>>
+		<<bodyliquid _type "nectar" -5>><<run $(`#stats${_type}nectar`).html(Math.trunc($player.bodyliquid[_type].nectar))>>
+	<</for>>
+	<<updatesidebarimg>>
 <</link>> |
 
 <br>
 
-<<link "<">><<bodyliquid "neck" "semen" -1>><<replace "#statsnecknectar">><<print Math.trunc($player.bodyliquid.neck.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Neck nectar: <span id="statsnecknectar"><<print Math.trunc($player.bodyliquid.neck.nectar)>></span>
-<<link ">">><<bodyliquid "neck" "nectar">><<replace "#statsnecknectar">><<print Math.trunc($player.bodyliquid.neck.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "rightarm" "nectar" -1>><<replace "#statsrightarmnectar">><<print Math.trunc($player.bodyliquid.rightarm.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Right arm nectar: <span id="statsrightarmnectar"><<print Math.trunc($player.bodyliquid.rightarm.nectar)>></span>
-<<link ">">><<bodyliquid "rightarm" "nectar">><<replace "#statsrightarmnectar">><<print Math.trunc($player.bodyliquid.rightarm.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "leftarm" "nectar" -1>><<replace "#statsleftarmnectar">><<print Math.trunc($player.bodyliquid.leftarm.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Left arm nectar: <span id="statsleftarmnectar"><<print Math.trunc($player.bodyliquid.leftarm.nectar)>></span>
-<<link ">">><<bodyliquid "leftarm" "nectar">><<replace "#statsleftarmnectar">><<print Math.trunc($player.bodyliquid.leftarm.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "thigh" "nectar" -1>><<replace "#statsthighnectar">><<print Math.trunc($player.bodyliquid.thigh.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Thigh nectar: <span id="statsthighnectar"><<print Math.trunc($player.bodyliquid.thigh.nectar)>></span>
-<<link ">">><<bodyliquid "thigh" "nectar">><<replace "#statsthighnectar">><<print Math.trunc($player.bodyliquid.thigh.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "bottom" "nectar" -1>><<replace "#statsbottomnectar">><<print Math.trunc($player.bodyliquid.bottom.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Bottom nectar: <span id="statsbottomnectar"><<print Math.trunc($player.bodyliquid.bottom.nectar)>></span>
-<<link ">">><<bodyliquid "bottom" "nectar">><<replace "#statsbottomnectar">><<print Math.trunc($player.bodyliquid.bottom.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "tummy" "nectar" -1>><<replace "#statstummynectar">><<print Math.trunc($player.bodyliquid.tummy.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Tummy nectar: <span id="statstummynectar"><<print Math.trunc($player.bodyliquid.tummy.nectar)>></span>
-<<link ">">><<bodyliquid "tummy" "nectar">><<replace "#statstummynectar">><<print Math.trunc($player.bodyliquid.tummy.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "chest" "nectar" -1>><<replace "#statschestnectar">><<print Math.trunc($player.bodyliquid.chest.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Chest nectar: <span id="statschestnectar"><<print Math.trunc($player.bodyliquid.chest.nectar)>></span>
-<<link ">">><<bodyliquid "chest" "nectar">><<replace "#statschestnectar">><<print Math.trunc($player.bodyliquid.chest.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "face" "nectar" -1>><<replace "#statsfacenectar">><<print Math.trunc($player.bodyliquid.face.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Face nectar: <span id="statsfacenectar"><<print Math.trunc($player.bodyliquid.face.nectar)>></span>
-<<link ">">><<bodyliquid "face" "nectar">><<replace "#statsfacenectar">><<print Math.trunc($player.bodyliquid.face.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "hair" "nectar" -1>><<replace "#statshairnectar">><<print Math.trunc($player.bodyliquid.hair.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Hair nectar: <span id="statshairnectar"><<print Math.trunc($player.bodyliquid.hair.nectar)>></span>
-<<link ">">><<bodyliquid "hair" "nectar">><<replace "#statshairnectar">><<print Math.trunc($player.bodyliquid.hair.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "feet" "nectar" -1>><<replace "#statsfeetnectar">><<print Math.trunc($player.bodyliquid.feet.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Feet nectar: <span id="statsfeetnectar"><<print Math.trunc($player.bodyliquid.feet.nectar)>></span>
-<<link ">">><<bodyliquid "feet" "nectar">><<replace "#statsfeetnectar">><<print Math.trunc($player.bodyliquid.feet.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "vaginaoutside" "nectar" -1>><<replace "#statsvaginaoutsidenectar">><<print Math.trunc($player.bodyliquid.vaginaoutside.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Labia nectar: <span id="statsvaginaoutsidenectar"><<print Math.trunc($player.bodyliquid.vaginaoutside.nectar)>></span>
-<<link ">">><<bodyliquid "vaginaoutside" "nectar">><<replace "#statsvaginaoutsidenectar">><<print Math.trunc($player.bodyliquid.vaginaoutside.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "vagina" "nectar" -1>><<replace "#statsvaginanectar">><<print Math.trunc($player.bodyliquid.vagina.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Vagina nectar: <span id="statsvaginanectar"><<print Math.trunc($player.bodyliquid.vagina.nectar)>></span>
-<<link ">">><<bodyliquid "vagina" "nectar">><<replace "#statsvaginanectar">><<print Math.trunc($player.bodyliquid.vagina.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "penis" "nectar" -1>><<replace "#statspenisnectar">><<print Math.trunc($player.bodyliquid.penis.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Penis nectar: <span id="statspenisnectar"><<print Math.trunc($player.bodyliquid.penis.nectar)>></span>
-<<link ">">><<bodyliquid "penis" "nectar">><<replace "#statspenisnectar">><<print Math.trunc($player.bodyliquid.penis.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "anus" "nectar" -1>><<replace "#statsanusnectar">><<print Math.trunc($player.bodyliquid.anus.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Anus nectar: <span id="statsanusnectar"><<print Math.trunc($player.bodyliquid.anus.nectar)>></span>
-<<link ">">><<bodyliquid "anus" "nectar">><<replace "#statsanusnectar">><<print Math.trunc($player.bodyliquid.anus.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
-<<link "<">><<bodyliquid "mouth" "nectar" -1>><<replace "#statsmouthnectar">><<print Math.trunc($player.bodyliquid.mouth.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-Mouth nectar: <span id="statsmouthnectar"><<print Math.trunc($player.bodyliquid.mouth.nectar)>></span>
-<<link ">">><<bodyliquid "mouth" "nectar">><<replace "#statsmouthnectar">><<print Math.trunc($player.bodyliquid.mouth.nectar)>><</replace>> <<updatesidebarimg>><</link>>
-|
+<<cheatBodyliquidOnPart "neck" "Neck" "nectar">>
+<<cheatBodyliquidOnPart "rightarm" "Right arm" "nectar">>
+<<cheatBodyliquidOnPart "leftarm" "Left arm" "nectar">>
+<<cheatBodyliquidOnPart "thigh" "Thigh" "nectar">>
+<<cheatBodyliquidOnPart "bottom" "Bottom" "nectar">>
+<<cheatBodyliquidOnPart "tummy" "Tummy" "nectar">>
+<<cheatBodyliquidOnPart "chest" "Chest" "nectar">>
+<<cheatBodyliquidOnPart "face" "Face" "nectar">>
+<<cheatBodyliquidOnPart "hair" "Hair" "nectar">>
+<<cheatBodyliquidOnPart "feet" "Feet" "nectar">>
+<<cheatBodyliquidOnPart "vaginaoutside" "Labia" "nectar">>
+<<cheatBodyliquidOnPart "vagina" "Vagina" "nectar">>
+<<cheatBodyliquidOnPart "penis" "Penis" "nectar">>
+<<cheatBodyliquidOnPart "anus" "Anus" "nectar">>
+<<cheatBodyliquidOnPart "mouth" "Mouth" "nectar">>
 <br><br>
 
 <span class="gold">Transformations</span>
-- 
GitLab