From 8632c810e359c22fca2ce547fbd9cf023affdacb Mon Sep 17 00:00:00 2001
From: Purity <purityguydol@gmail.com>
Date: Tue, 21 Dec 2021 20:44:16 +0000
Subject: [PATCH] Persistent NPCs in the settings menu

---
 game/03-JavaScript/UI.js                      |  20 +-
 game/base-system/named-npcs.twee              |   1 +
 game/base-system/persistent-npcs.twee         | 150 +++++++-
 game/base-system/settings.twee                | 320 ++++++++++++------
 game/base-system/statistics.twee              |   2 +-
 game/base-system/text.twee                    |   6 -
 game/base-system/time.twee                    |   1 +
 game/base-system/widgets.twee                 |   3 +
 .../overworld-forest/loc-lake/ivory/main.twee | 150 ++++++++
 .../loc-lake/ivory/schism.twee                |   2 +-
 game/overworld-plains/loc-moor/events.twee    |   4 +-
 game/overworld-town/loc-home/main.twee        |   8 +-
 game/overworld-town/loc-museum/bdsm.twee      |   2 +-
 game/overworld-town/loc-pub/seduction.twee    |   2 +
 .../overworld-town/special-sydney/temple.twee |  12 +-
 15 files changed, 550 insertions(+), 133 deletions(-)

diff --git a/game/03-JavaScript/UI.js b/game/03-JavaScript/UI.js
index cc53a98df2..63f76d8d79 100644
--- a/game/03-JavaScript/UI.js
+++ b/game/03-JavaScript/UI.js
@@ -401,11 +401,11 @@ window.settingsBodywriting = function () {
 	});
 }
 
-window.settingsNamedNpcBreastSize = function () {
+window.settingsNamedNpcBreastSize = function (id, persist) {
 	const breastSizes = ["nipple","budding","tiny","small","pert","modest","full","large","ample","massive","huge","gigantic","enormous"];
 
 	let updateText = () => {
-		const npc = V.NPCName[T.npcId];
+		const npc = persist ? V.per_npc[T.pNPCId] : V.NPCName[T.npcId];
 		const val = npc.breastsize;
 
 		const text = breastSizes[val];
@@ -418,12 +418,12 @@ window.settingsNamedNpcBreastSize = function () {
 			npc.breastsdesc = text + "s";
 		}
 
-		jQuery('#numberslider-value-npcname-npcidbreastsize').text(npc.breastsdesc);
+		jQuery('#numberslider-value-' + id).text(npc.breastsdesc);
 	};
 
 	jQuery(document).ready(() => {
 		updateText();
-		jQuery('#numberslider-input-npcname-npcidbreastsize').on('input change', function (e) { updateText(); });
+		jQuery('#numberslider-input-' + id).on('input change', function (e) { updateText(); });
 	});
 }
 
@@ -438,6 +438,18 @@ window.settingsNamedNpcGenderUpdate = function () {
 	});
 }
 
+window.settingsPersistentNpcGenderUpdate = function () {
+	let updateButtonsActive = () => {
+		jQuery('[id*=radiobutton-' + Util.slugify('$per_npc[_pNPCId].penissize') + ']').prop("disabled", V.per_npc[T.pNPCId].gender == "f");
+		jQuery('[id*=radiobutton-' + Util.slugify('$per_npc[_pNPCId].pronoun') + ']').prop("disabled", V.per_npc[T.pNPCId].pronoun == "i");
+	};
+
+	jQuery(document).ready(() => {
+		updateButtonsActive();
+		jQuery('[id*=radiobutton-' + Util.slugify('$per_npc[_pNPCId].gender') + ']').on('change', function (e) { updateButtonsActive(); });
+	});
+}
+
 window.settingsPCGenderUpdate = function () {
 	let updateButtonsActive = () => {
 		jQuery('[id*=radiobutton-penissize]').prop("disabled", V.player.gender == "f");
diff --git a/game/base-system/named-npcs.twee b/game/base-system/named-npcs.twee
index 5d1234ee59..2d230a8f10 100644
--- a/game/base-system/named-npcs.twee
+++ b/game/base-system/named-npcs.twee
@@ -350,6 +350,7 @@ alternative way to write that:
 	<<case "Avery">> <<set $NPCName[_i].title to ($NPCName[_i].pronoun is "m" ? "businessman" : "businesswoman")>>
 <</switch>>
 
+<<generatePronouns $NPCName[_i]>>
 <</for>>
 
 <</widget>>
diff --git a/game/base-system/persistent-npcs.twee b/game/base-system/persistent-npcs.twee
index dc3aca224a..565a5a6086 100644
--- a/game/base-system/persistent-npcs.twee
+++ b/game/base-system/persistent-npcs.twee
@@ -38,15 +38,157 @@
 <<if $args[0]>>
 	<<set _temp0 to $args[0]>>
 	/*Adds name back into name pool */
-	<<if $per_npc[_temp0].pronoun is "f">>
-		<<set $NPC_names_f.pushUnique($per_npc[_temp0].name)>>
-	<<else>>
-		<<set $NPC_names_m.pushUnique($per_npc[_temp0].name)>>
+	<<if $per_npc[_temp0].name>>
+		<<if $per_npc[_temp0].pronoun is "f">>
+			<<set $NPC_names_f.pushUnique($per_npc[_temp0].name)>>
+		<<else>>
+			<<set $NPC_names_m.pushUnique($per_npc[_temp0].name)>>
+		<</if>>
 	<</if>>
 	<<run delete $per_npc[_temp0]>>
 <</if>>
 <</widget>>
 
+<<widget "updatePersistentNPCs">>
+<<if $passage isnot "start" and $per_npc and Object.keys($per_npc).length gt 0>>
+	<<for $_i, $_value range $per_npc>>
+		<!-- Set Pronoun -->
+		<<if $per_npc[$_i].pronoun is "none" or $args[0] is "genders">>
+			<<if $malechance lt random(1, 100)>>
+				<<set $per_npc[$_i].pronoun to "f">><<set $test to $per_npc[$_i].pronoun>>
+			<<else>>
+				<<set $per_npc[$_i].pronoun to "m">>
+			<</if>>
+		<</if>>
+		<!-- Set Gender -->
+		<<if $per_npc[$_i].gender is "none" or $args[0] is "genders">>
+			<<if $per_npc[$_i].pronoun is "m">>
+				<<if random(0, 99) gte $cbchance>>
+					<<set $per_npc[$_i].gender to "m">>
+				<<else>>
+					<<set $per_npc[$_i].gender to "f">>
+				<</if>>
+			<<elseif $per_npc[$_i].pronoun is "f">>
+				<<if random(0, 99) gte $dgchance>>
+					<<set $per_npc[$_i].gender to "f">>
+				<<else>>
+					<<set $per_npc[$_i].gender to "m">>
+				<</if>>
+			<</if>>
+		<</if>>
+
+		<!-- Set Genital Existence -->
+		<<if $per_npc[$_i].type isnot "human">>
+			<<set $per_npc[$_i].penis to  ($per_npc[$_i].gender !== "f" ? 0 : "none")>>
+			<<set $per_npc[$_i].vagina to ($per_npc[$_i].gender !== "m" ? 0 : "none")>>
+		<<else>>
+			<<set $per_npc[$_i].penis to  ($per_npc[$_i].gender !== "f" ? "clothed" : "none")>>
+			<<set $per_npc[$_i].vagina to ($per_npc[$_i].gender !== "m" ? "clothed" : "none")>>
+		<</if>>
+
+		<!-- Set breast defaults-->
+
+		<<set _b_mod_lower to Math.clamp($breast_mod, 0, 12)>>
+		<<set _b_mod_upper to Math.clamp($breast_mod + 12, 0, 12)>>
+
+		<!-- can't use breastsize, since that would either break the numberslider
+		or make one of the sizes always be randomized,
+		but can use breastdesc not being changed from 0 as a substitute -->
+		<<if $per_npc[$_i].breastdesc is 0 or $args[0] is "breasts">>
+			<<if $per_npc[$_i].pronoun is "m">>
+				<<set $per_npc[$_i].breastsize to 0>>
+			<<else>>
+				<<set $per_npc[$_i].breastsize to random (_b_mod_lower, _b_mod_upper)>>
+			<</if>>
+		<</if>>
+		<<if $per_npc[$_i].breastsize gt 0>>
+			<<set _brdes to ["nipple","budding","tiny","small","pert","modest","full","large","ample","massive","huge","gigantic","enormous"]>>
+			<<set $per_npc[$_i].breastdesc to _brdes[$per_npc[$_i].breastsize]+" breast">>
+		<<else>>
+			<<set $per_npc[$_i].breastdesc to "nipple">>
+		<</if>>
+		<<set $per_npc[$_i].breastsdesc to $per_npc[$_i].breastdesc + "s">>
+
+		<!-- Set pp to defaults-->
+
+		/* New way to set upper and lower bounds.
+		* This method makes use of all other slider positions, but does nothing when slider is between -1 and 1, 
+		* for a total of 15 unique positions vs the current method's 9. (max would be 17)
+		* Changing the penis_mod slider to range from -7 to 7 would work to make every slider position unique here, but potentially affects unnamed npc generation. 
+		*/
+
+		/*
+		<<set _p_mod_upper to 8>><<set _p_mod_lower to 1>>
+		<<if $penis_mod gt 0>>
+			<<set _p_mod_lower += $penis_mod - 1>>
+		<<elseif $penis_mod lt 0>>
+			<<set _p_mod_upper += $penis_mod + 1>>
+		<</if>>
+
+		alternative way to write that:
+		<<set _p_mod_lower to ($penis_mod > 0 ? $penis_mod : 1)>>
+		<<set _p_mod_upper to ($penis_mod < 0 ? 9 + $penis_mod : 8)>>
+		*/
+
+		<<if $penis_mod is 8>>
+			<<set _p_mod_upper to 8>><<set _p_mod_lower to 8>>
+		<<elseif $penis_mod gte 6>>
+			<<set _p_mod_upper to 8>><<set _p_mod_lower to 7>>
+		<<elseif $penis_mod gte 4>>
+			<<set _p_mod_upper to 8>><<set _p_mod_lower to 5>>
+		<<elseif $penis_mod gte 2>>
+			<<set _p_mod_upper to 8>><<set _p_mod_lower to 3>>
+		<<elseif $penis_mod gte 0>>
+			<<set _p_mod_upper to 8>><<set _p_mod_lower to 1>>
+		<<elseif $penis_mod gte -2>>
+			<<set _p_mod_upper to 7>><<set _p_mod_lower to 1>>
+		<<elseif $penis_mod gte -4>>
+			<<set _p_mod_upper to 5>><<set _p_mod_lower to 1>>
+		<<elseif $penis_mod gte -6>>
+			<<set _p_mod_upper to 3>><<set _p_mod_lower to 1>>
+		<<else>>
+			<<set _p_mod_upper to 1>><<set _p_mod_lower to 1>>
+		<</if>>
+
+		<<if $per_npc[$_i].penissize is 0 or $args[0] is "penis">>
+			<<if $per_npc[$_i].gender is "f">>
+				<<set $per_npc[$_i].penissize to 0>>
+				<<set $per_npc[$_i].penisdesc to "none">>
+			<<else>>
+				<<switch random (_p_mod_lower, _p_mod_upper)>>
+				<<case 8>>
+					<<set $per_npc[$_i].penisdesc to either("massive cock","huge cock","humongous cock","immense cock","gigantic cock","enormous cock")>>
+					<<set $per_npc[$_i].penissize to 4>>
+				<<case 5 6 7>>
+					<<set $per_npc[$_i].penisdesc to either("thick cock","hefty cock","big cock","large cock","veiny cock","meaty cock")>>
+					<<set $per_npc[$_i].penissize to 3>>
+				<<case 2 3 4>>
+					<<set $per_npc[$_i].penisdesc to "penis">>
+					<<set $per_npc[$_i].penissize to 2>>
+				<<default>>
+					<<set $per_npc[$_i].penisdesc to either("tiny penis","pathetic cock","little penis","small penis","mini penis","micro penis")>>
+					<<set $per_npc[$_i].penissize to 1>>
+				<</switch>>
+			<</if>>
+		<</if>>
+		<!-- Set pp to size in case PC selected it-->
+		<<if $per_npc[$_i].penissize isnot 0>>
+			<<switch $per_npc[$_i].penissize>>
+			<<case 4>>
+				<<set $per_npc[$_i].penisdesc to either("massive cock","huge cock","humongous cock","immense cock","gigantic cock","enormous cock")>>
+			<<case 3>>
+				<<set $per_npc[$_i].penisdesc to either("thick cock","hefty cock","big cock","large cock","veiny cock","meaty cock")>>
+			<<case 1>>
+				<<set $per_npc[$_i].penisdesc to either("tiny penis","pathetic cock","little penis","small penis","mini penis","micro penis")>>
+			<<default>>
+				<<set $per_npc[$_i].penisdesc to "penis">>
+			<</switch>>
+		<</if>>
+		<<generatePronouns $per_npc[$_i]>>
+	<</for>>
+<</if>>
+<</widget>>
+
 <<widget "updateNPCsFirst">>/*Adds new variables to saved NPCs.*/
 <<for _per_keys range Object.keys($per_npc)>>
 	<<set $per_npc[_per_keys][$args[0]] to $args[1]>>
diff --git a/game/base-system/settings.twee b/game/base-system/settings.twee
index c8c0b062f6..5e155a9ba7 100644
--- a/game/base-system/settings.twee
+++ b/game/base-system/settings.twee
@@ -60,7 +60,7 @@
 <<else>>
 	<<set $debugdisable to "t">>
 <</if>>
-	<<set $cheatdisable to "t">>
+<<set $cheatdisable to "t">>
 <<set $watersportsdisable to "f">>
 <<set $timestyle to "military">>
 <<set $saveName to "">>
@@ -284,7 +284,7 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<</if>>
 	<<updatehistorycontrols>>
 	<<initnpcgender>>
-	<<updatePronouns>>
+	<<updatePersistentNPCs>>
 	<<hirsuteHideCheck>>
 	<<generateTipsList>>
 	<<tanned 0 "ignoreCoverage">>
@@ -1287,16 +1287,19 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 <</if>>
 <<link "Generate all genders based on game settings">>
 	<<initnpcgender "genders">>
+	<<updatePersistentNPCs "genders">>
 	<<displaySettings>>
 <</link>>
 <br>
 <<link "Generate all penis sizes based on game settings">>
 	<<initnpcgender "penis">>
+	<<updatePersistentNPCs "penis">>
 	<<displaySettings>>
 <</link>>
 <br>
 <<link "Generate all breast sizes based on game settings">>
 	<<initnpcgender "breasts">>
+	<<updatePersistentNPCs "breasts">>
 	<<displaySettings>>
 <</link>>
 <<if $debug is 1>>
@@ -1335,6 +1338,30 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 	<<npcSettingsMenu>>
 </div>
 
+<<if $passage isnot "start" and $per_npc and Object.keys($per_npc).length gt 0>>
+	<<run
+		if (!T.perNPCLock) {
+			$("#passages").on('change', '#perNPCSettingsMenu .macro-listbox', function (e) {
+				new Wikifier(null, '<<replace #perNPCSettingsMenu>><<perNPCSettingsMenu>><</replace>>');
+			});
+
+			T.keys = {};
+			T.keyNames = [];
+			Object.keys(V.per_npc).forEach(k => {
+				if (k.includes('steed') || k.includes('guard') || k.includes('inmate') || k.includes('panty_thief') || k.includes('tower_creature') || k.includes('wraith')) {
+					T.keyNames.push(k);
+					T.keys[k.toUpperFirst().replaceAll('_', ' ')] = k;
+				}
+			});
+			T.perNPCLock = true;
+		}
+	>>
+
+	<div id="perNPCSettingsMenu">
+		<<perNPCSettingsMenu>>
+	</div>
+<</if>>
+
 <<if _listActive isnot true>>
 	<<NPCSettingsReset>>
 	<<set _listActive to true>>
@@ -1344,135 +1371,214 @@ Values above 5 can lead to errors when creating new saves! Make sure you know wh
 
 <<widget "exportsettings">>
 
-<span class="yellow">Will also import/export settings found in the "SAVE/OPTIONS" overlay.</span>
-
-<h4>Settings 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>>
-	Load from file: <input id="saveImport" type="file" value="Load from file" onchange="importSettings(this.files, 'file')">
-	<br><br>
-	<input type="button" value="Save to file" onclick="exportSettings(null,'file')">
-<</if>>
+	<span class="yellow">Will also import/export settings found in the "SAVE/OPTIONS" overlay.</span>
 
-<h4>Settings Text Import/Export</h4>
+	<h4>Settings File Import/Export</h4>
 
-To save your current settings, click on "Get Settings Data", then copy and paste the save data where required.
-<br>
-To load your current settings, paste in the settings data then click "Load Settings Data".
-<br>
-To transfer to and from Android, it is recommended to use email or a service such as pastebin. Please ensure that the start and the end of the save is exact to prevent issues.
-<br>
-Click on "Copy Text Area" to copy the current contents for you. The button name will change to "Copying Error" if your device or browser does not support it.
-<br><br>
-<textarea id="settingsDataInput" rows="4" cols="40" onClick="if(V.disableAutoSelect == false)this.select();" onfocus="V.tempDisable = true;" onblur="V.tempDisable = false;"></textarea>
-<br>
-<input type="button" value="Clear Text Box" onclick="clearTextBox('settingsDataInput')"/>
-<input type="button" value="Top of Text Box" onclick="topTextArea('settingsDataInput')"/>
-<input type="button" value="Bottom of Text Box" onclick="bottomTextArea('settingsDataInput')"/>
-<input type="button" value="Get Settings Data" onclick="exportSettings(null,'text')"/>
-<input type="button" value="Load Settings Data" onclick="importSettings(null,'text')"/>
-<input id="CopyTextArea" type="button" value="Copy Text Area" onclick="copySavedata('settingsDataInput')">
-<input id="LoadExternalExportFile" type="button" value="Load External Export File" onclick="loadExternalExportFile()">
+	<<if SugarCube.Browser.isMobile.any() is true>>
+		Note that saving and loading from file does not work on Android currently.
+	<<else>>
+		Load from file: <input id="saveImport" type="file" value="Load from file" onchange="importSettings(this.files, 'file')">
+		<br><br>
+		<input type="button" value="Save to file" onclick="exportSettings(null,'file')">
+	<</if>>
 
-<br><br>
+	<h4>Settings Text Import/Export</h4>
 
-<label>
-	<<checkbox "$disableAutoSelect" false true autocheck>>
-	Disables auto select.
-</label>
+	To save your current settings, click on "Get Settings Data", then copy and paste the save data where required.
+	<br>
+	To load your current settings, paste in the settings data then click "Load Settings Data".
+	<br>
+	To transfer to and from Android, it is recommended to use email or a service such as pastebin. Please ensure that the start and the end of the save is exact to prevent issues.
+	<br>
+	Click on "Copy Text Area" to copy the current contents for you. The button name will change to "Copying Error" if your device or browser does not support it.
+	<br><br>
+	<textarea id="settingsDataInput" rows="4" cols="40" onClick="if(V.disableAutoSelect == false)this.select();" onfocus="V.tempDisable = true;" onblur="V.tempDisable = false;"></textarea>
+	<br>
+	<input type="button" value="Clear Text Box" onclick="clearTextBox('settingsDataInput')"/>
+	<input type="button" value="Top of Text Box" onclick="topTextArea('settingsDataInput')"/>
+	<input type="button" value="Bottom of Text Box" onclick="bottomTextArea('settingsDataInput')"/>
+	<input type="button" value="Get Settings Data" onclick="exportSettings(null,'text')"/>
+	<input type="button" value="Load Settings Data" onclick="importSettings(null,'text')"/>
+	<input id="CopyTextArea" type="button" value="Copy Text Area" onclick="copySavedata('settingsDataInput')">
+	<input id="LoadExternalExportFile" type="button" value="Load External Export File" onclick="loadExternalExportFile()">
 
-<</widget>>
+	<br><br>
 
-<<widget "npcSettingsMenu">>
-<<listbox "_npcId" autoselect>>
-	<<optionsfrom _npcList>>
-<</listbox>>
-| <<link Previous>>
-	<<if _npcId is 0>>
-		<<set _npcId to $NPCNameList.length - 1>>
-	<<else>>
-		<<set _npcId-->>
-	<</if>>
-	<<replace #npcSettingsMenu>><<npcSettingsMenu>><</replace>>
-<</link>> |
-<<link Next>>
-	<<set _npcId++>>
-	<<replace #npcSettingsMenu>><<npcSettingsMenu>><</replace>>
-<</link>>
-<br><br>
-<span class="gold">$NPCName[_npcId].nam the $NPCName[_npcId].title</span>
-<br>
-<label><<radiobutton "$NPCName[_npcId].pronoun" "f" autocheck>> Female</label> |
-<label><<radiobutton "$NPCName[_npcId].pronoun" "m" autocheck>> Male</label>
-<br>
-<<if $NPCName[_npcId].pregnancy[0] is null>>
-	<label><<radiobutton "$NPCName[_npcId].gender" "f" autocheck>> Vagina</label> |
-	<label><<radiobutton "$NPCName[_npcId].gender" "m" autocheck>> Penis</label>
-	<<run settingsNamedNpcGenderUpdate()>>
-<<else>>
-	Unable to change the npc genitals due to their pregnancy.
-<</if>>
-<br><br>
-Penis size - if applicable:
-<br>
-<<set _penisNames to ["", "Tiny", "Average", "Thick", "Huge"]>> /* the empty first element is necessary because _j starts at 1 */
-<<for _j to 1; _j lt _penisNames.length; _j++>>
 	<label>
-		<<radiobutton "$NPCName[_npcId].penissize" _j autocheck>>
-		<<print _penisNames[_j]>>
+		<<checkbox "$disableAutoSelect" false true autocheck>>
+		Disables auto select.
 	</label>
-	<<if _j isnot _penisNames.length -1>>|<</if>>
-<</for>>
-<br><br>
 
-<div class="settingsToggle" style="display: inline-flex;">
-Breast size
-<<numberslider "$NPCName[_npcId].breastsize" $NPCName[_npcId].breastsize 0 12 1>>
-<<run settingsNamedNpcBreastSize()>>
-</div>
-<div style="clear:both;">/*Keep at end of toggles*/</div>
+<</widget>>
 
-<<if $NPCName[_npcId].nam is "Black Wolf">>
-	Beast Type:
-	<br>
-	<label><<radiobutton "$blackwolfmonster" 0 autocheck>> Always a beast</label> |
-	<label><<radiobutton "$blackwolfmonster" 1 autocheck>> Monster girl or boy when requirements met</label> |
-	<label><<radiobutton "$blackwolfmonster" 2 autocheck>> Always a monster girl or boy</label>
+<<widget "npcSettingsMenu">>
+	<<listbox "_npcId" autoselect>>
+		<<optionsfrom _npcList>>
+	<</listbox>>
+	| <<link Previous>>
+		<<if _npcId is 0>>
+			<<set _npcId to $NPCNameList.length - 1>>
+		<<else>>
+			<<set _npcId-->>
+		<</if>>
+		<<replace #npcSettingsMenu>><<npcSettingsMenu>><</replace>>
+	<</link>> |
+	<<link Next>>
+		<<set _npcId++>>
+		<<replace #npcSettingsMenu>><<npcSettingsMenu>><</replace>>
+	<</link>>
 	<br><br>
-<<elseif $NPCName[_npcId].nam is "Great Hawk">>
-	Beast Type:
+	<span class="gold">$NPCName[_npcId].nam the $NPCName[_npcId].title</span>
 	<br>
-	<label><<radiobutton "$greathawkmonster" 0 autocheck>> Always a beast</label> |
-	<label><<radiobutton "$greathawkmonster" 1 autocheck>> Monster girl or boy when requirements met</label> |
-	<label><<radiobutton "$greathawkmonster" 2 autocheck>> Always a monster girl or boy</label>
+	<label><<radiobutton "$NPCName[_npcId].pronoun" "f" autocheck>> Female</label> |
+	<label><<radiobutton "$NPCName[_npcId].pronoun" "m" autocheck>> Male</label>
+	<br>
+	<<if $NPCName[_npcId].pregnancy[0] is null>>
+		<label><<radiobutton "$NPCName[_npcId].gender" "f" autocheck>> Vagina</label> |
+		<label><<radiobutton "$NPCName[_npcId].gender" "m" autocheck>> Penis</label>
+		<<run settingsNamedNpcGenderUpdate()>>
+	<<else>>
+		Unable to change the npc genitals due to their pregnancy.
+	<</if>>
 	<br><br>
-<</if>>
-<<if $debug is 1>>
-	Hair Colour:
+	Penis size - if applicable:
 	<br>
-	<<for _j to 0; _j lt _hairColorNPC.length; _j++>>
+	<<set _penisNames to ["", "Tiny", "Average", "Thick", "Huge"]>> /* the empty first element is necessary because _j starts at 1 */
+	<<for _j to 1; _j lt _penisNames.length; _j++>>
 		<label>
-			<<print '<<radiobutton "$NPCName['+_npcId+'].hairColour" "'+_hairColorNPCData[_j]+'" ' + ($NPCName[_npcId].hairColour is _hairColorNPCData[_j] ? "checked" : "") + '>>'>>
-			<span @class="_hairColorNPCText[_j]">_hairColorNPC[_j]</span>
-		</label> |
+			<<radiobutton "$NPCName[_npcId].penissize" _j autocheck>>
+			<<print _penisNames[_j]>>
+		</label>
+		<<if _j isnot _penisNames.length -1>>|<</if>>
 	<</for>>
 	<br><br>
 
-	Eye Colour:
+	<div class="settingsToggle" style="display: inline-flex;">
+	Breast size
+	<<numberslider "$NPCName[_npcId].breastsize" $NPCName[_npcId].breastsize 0 12 1>>
+	<<run settingsNamedNpcBreastSize(Util.slugify('$NPCName[_npcId].breastsize'), false)>>
+	</div>
+	<div style="clear:both;">/*Keep at end of toggles*/</div>
 	<br>
-	<<for _j to 0; _j lt _eyeColorNPC.length; _j++>>
+
+	<<if $NPCName[_npcId].nam is "Black Wolf">>
+		Beast Type:
+		<br>
+		<label><<radiobutton "$blackwolfmonster" 0 autocheck>> Always a beast</label> |
+		<label><<radiobutton "$blackwolfmonster" 1 autocheck>> Monster girl or boy when requirements met</label> |
+		<label><<radiobutton "$blackwolfmonster" 2 autocheck>> Always a monster girl or boy</label>
+		<br><br>
+	<<elseif $NPCName[_npcId].nam is "Great Hawk">>
+		Beast Type:
+		<br>
+		<label><<radiobutton "$greathawkmonster" 0 autocheck>> Always a beast</label> |
+		<label><<radiobutton "$greathawkmonster" 1 autocheck>> Monster girl or boy when requirements met</label> |
+		<label><<radiobutton "$greathawkmonster" 2 autocheck>> Always a monster girl or boy</label>
+		<br><br>
+	<</if>>
+	<<if $debug is 1>>
+		Hair Colour:
+		<br>
+		<<for _j to 0; _j lt _hairColorNPC.length; _j++>>
+			<label>
+				<<print '<<radiobutton "$NPCName['+_npcId+'].hairColour" "'+_hairColorNPCData[_j]+'" ' + ($NPCName[_npcId].hairColour is _hairColorNPCData[_j] ? "checked" : "") + '>>'>>
+				<span @class="_hairColorNPCText[_j]">_hairColorNPC[_j]</span>
+			</label> |
+		<</for>>
+		<br><br>
+
+		Eye Colour:
+		<br>
+		<<for _j to 0; _j lt _eyeColorNPC.length; _j++>>
+			<label>
+				<<print '<<radiobutton "$NPCName['+_npcId+'].eyeColour" "'+_eyeColorNPCData[_j]+'" ' + ($NPCName[_npcId].eyeColour is _eyeColorNPCData[_j] ? "checked" : "") + '>>'>>
+				<span @class="_eyeColorNPCText[_j]">_eyeColorNPC[_j]</span>
+			</label> |
+		<</for>>
+		<br><br>
+	<</if>>
+<</widget>>
+
+<<widget "perNPCSettingsMenu">>
+	<span class="gold">Persistent NPCs:</span>
+	<br>
+	<<listbox "_pNPCId" autoselect>>
+		<<optionsfrom _keys>>
+	<</listbox>>
+	<<switch _pNPCId>>
+		<<case "scarred_inmate">>
+			<<if $per_npc[_pNPCId].description isnot "scarred">>
+				<<generate_scarred_inmate 0>>
+				<<clearsinglenpc 0>>
+			<</if>>
+		<<case "veteran_guard">>
+			<<if $per_npc[_pNPCId].description isnot "veteran">>
+				<<generate_veteran_guard 0>>
+				<<clearsinglenpc 0>>
+			<</if>>
+	<</switch>>
+	<<set _index to _keyNames.indexOf(_pNPCId)>>
+	| <<link Previous>>
+		<<set _index to (_index is 0 ? _keyNames.length - 1 : --_index)>>
+		<<set _pNPCId to _keyNames[_index]>>
+		<<replace #perNPCSettingsMenu>><<perNPCSettingsMenu>><</replace>>
+	<</link>> |
+	<<link Next>>
+		<<set _index++>>
+		<<set _pNPCId to _keyNames[_index]>>
+		<<replace #perNPCSettingsMenu>><<perNPCSettingsMenu>><</replace>>
+	<</link>>
+	<br><br>
+	<<if $per_npc[_pNPCId].name_known>>
+		<span class="gold">$per_npc[_pNPCId].name the <<print _pNPCId.replaceAll('_', ' ')>></span>
+	<<elseif $per_npc[_pNPCId].name is "Ivory Wraith">>
+		<span class="wraith">The Ivory Wraith</span>
+	<<elseif _pNPCId is "tower_creature">>
+		<span class="gold">The Night Monster</span>
+	<<else>>
+		<span class="gold"><<print _pNPCId.toUpperFirst().replaceAll('_', ' ')>></span>
+	<</if>>
+	<<if $per_npc[_pNPCId].name_known and $debug is 1>>
+		| <<link Rename>>
+			<<if $per_npc[_pNPCId].pronoun is "f">>
+				<<set $per_npc[_pNPCId].name to $NPC_names_f.random()>>
+			<<else>>
+				<<set $per_npc[_pNPCId].name to $NPC_names_m.random()>>
+			<</if>>
+			<<replace #perNPCSettingsMenu>><<perNPCSettingsMenu>><</replace>>
+		<</link>>
+	<</if>>
+	<br>
+	<label><<radiobutton "$per_npc[_pNPCId].pronoun" "f" autocheck>> Female</label> |
+	<label><<radiobutton "$per_npc[_pNPCId].pronoun" "m" autocheck>> Male</label>
+	<br>
+	<label><<radiobutton "$per_npc[_pNPCId].gender" "f" autocheck>> Vagina</label> |
+	<label><<radiobutton "$per_npc[_pNPCId].gender" "m" autocheck>> Penis</label>
+	<<run settingsPersistentNpcGenderUpdate()>>
+	<br><br>
+	Penis size - if applicable:
+	<br>
+	<<set _penisNames to ["", "Tiny", "Average", "Thick", "Huge"]>> /* the empty first element is necessary because _j starts at 1 */
+	<<for _j to 1; _j lt _penisNames.length; _j++>>
 		<label>
-			<<print '<<radiobutton "$NPCName['+_npcId+'].eyeColour" "'+_eyeColorNPCData[_j]+'" ' + ($NPCName[_npcId].eyeColour is _eyeColorNPCData[_j] ? "checked" : "") + '>>'>>
-			<span @class="_eyeColorNPCText[_j]">_eyeColorNPC[_j]</span>
-		</label> |
+			<<radiobutton "$per_npc[_pNPCId].penissize" _j autocheck>>
+			<<print _penisNames[_j]>>
+		</label>
+		<<if _j isnot _penisNames.length -1>>|<</if>>
 	<</for>>
 	<br><br>
-<</if>>
-
+	<div class="settingsToggle" style="display: inline-flex;">
+		Breast size
+		<<numberslider "$per_npc[_pNPCId].breastsize" $per_npc[_pNPCId].breastsize 0 12 1>>
+		<<run settingsNamedNpcBreastSize(Util.slugify('$per_npc[_pNPCId].breastsize'), true)>>
+	</div>
+	<div style="clear:both;">
+		/*Keep at end of toggles*/
+	</div>
 <</widget>>
 
+
 :: Settings
 <<settings>>
 
diff --git a/game/base-system/statistics.twee b/game/base-system/statistics.twee
index dffd6933ab..593b0b1f4f 100644
--- a/game/base-system/statistics.twee
+++ b/game/base-system/statistics.twee
@@ -24,7 +24,7 @@ __Virginities taken__
 <br>
 <<set _total to 0>>
 <<for _slot, _list range $virginTaken>>
-  <<set _total += _list.length>>
+	<<set _total += _list.length>>
 <</for>>
 Total: _total
 <br>
diff --git a/game/base-system/text.twee b/game/base-system/text.twee
index 941acb5559..c8e936d1fc 100644
--- a/game/base-system/text.twee
+++ b/game/base-system/text.twee
@@ -250,12 +250,6 @@
 <</if>>
 <</widget>>
 
-<<widget "updatePronouns">>
-	<<for _i to 0; _i lt $NPCNameList.length; _i++>>
-		<<generatePronouns $NPCName[_i]>>
-	<</for>>
-<</widget>>
-
 <<widget "clearPronouns">>
 <<if $args[0]>>
 	<<set $args[0].pronouns.he = 0>>
diff --git a/game/base-system/time.twee b/game/base-system/time.twee
index 5e455e5875..da15112b11 100644
--- a/game/base-system/time.twee
+++ b/game/base-system/time.twee
@@ -665,6 +665,7 @@
 		<<unset $christmas_gift_eden_given>>
 		<<unset $edenmeal>>
 		<<unset $eden_christmas_dinner>>
+		<<unset $christmas_wraith>>
 	<</if>>
 	<<if $bell_timer>>
 		<<set $bell_timer -= 1>>
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 7b796a74a3..7eea1b13f5 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -3516,6 +3516,9 @@ __Map__<br>
 		<br>
 	<</if>>
 <</if>>
+<<if $christmas is 1 and !$christmas_wraith>>
+	<<rngWraith 1>>
+<</if>>
 <</widget>>
 
 
diff --git a/game/overworld-forest/loc-lake/ivory/main.twee b/game/overworld-forest/loc-lake/ivory/main.twee
index 051c8abb1c..7e759d00f5 100644
--- a/game/overworld-forest/loc-lake/ivory/main.twee
+++ b/game/overworld-forest/loc-lake/ivory/main.twee
@@ -997,3 +997,153 @@ Your eyes snap open. The figure is gone, but you hear laughter echo in your head
 		<br>
 	<</if>>
 <</if>>
+
+:: Christmas Mirror
+<<set $outside to 0>><<set $location to "home">><<effects>>
+You walk up to the mirror and gaze into its depths. It no longer reflects, but glows with a curious light. It's a bright white. Like snow.
+<br><br>
+The light begins to take shape. A pale hand gently presses up against the surface from the other side. A pale figure stares back, smiling. Its <<wraithEyes>> eyes hold your gaze.
+<<if $wraith.seen gte 3 or $wraithPrison>>
+	<span class="red">You recognise it.</span> You feel as though you should be full of dread, but you aren't.
+<<else>>
+	You feel like you should be scared, but you aren't.
+<</if>>
+<br><br>
+<<link [[Reach out|Christmas Mirror Reach]]>><</link>><<handholdingvirginitywarning>>
+<br>
+<<link [[Watch|Christmas Mirror Watch]]>><</link>>
+<br>
+<<link [[Step Away|Christmas Mirror Leave]]>><</link>>
+<br>
+
+:: Christmas Mirror Leave
+You step away from the mirror. The next time you blink, it's returned to normal.
+<br><br>
+<<link [[Next|Bedroom]]>><<endevent>><</link>>
+<br>
+
+:: Christmas Mirror Watch
+You keep your eyes fixed on the hand. Its fingers slowly creep through the surface, revealing gnarled claws as they gingerly grip the frame.
+<br><br>
+The shape behind it flickers. The claws vanish, replaced by supple skin. You look up to see the figure still smiling warmly at you. It holds out its other hand, without a word.
+<br><br>
+<<link [[Take the hand|Christmas Mirror Reach]]>><</link>><<handholdingvirginitywarning>>
+<br>
+<<link [[Step Away|Christmas Mirror Leave]]>><</link>>
+<br>
+
+:: Christmas Mirror Reach
+<<effects>>
+<<generateWraith 1 true>><<rainWraith>><<set $pronoun to $per_npc.wraith.gender>>
+You reach forward, taking the hand in yours. <<takeHandholdingVirginity "Ivory Wraith" "consensual">>
+<br><br>
+The skin ripples, changing between a ghastly pale and a normal tone.
+<br><br>
+<span class="teal"><<He>> hums a familiar tune.</span>
+<br><br>
+<<Hes>> cloaked in a white robe, standing under a red moon. <<He>> has <<his>> other arm spread out to you in a welcoming gesture. You feel profoundly calm as you take a step forward.
+<br><br>
+<<link [[Step In|Christmas Mirror 2]]>><<pass 5>><<set $christmas_wraith to true>><</link>>
+<br>
+
+:: Christmas Mirror 2
+<<effects>><<set $location to "temple">><<set $outside to 0>>
+You're surrounded by trees, all covered in snow. You look down to see a bed of coals at your feet. The red moon vanishes. Your feet burn. You collapse forward, into <<his>> arms.
+<<He>> embraces you. <<Hes>> congratulating you, smiling and laughing. You're crying.
+<br><br>
+"You did it! I knew you could do it!" <<He>> speaks in a language you don't know, and yet, you find yourself understanding the words. Another voice speaks in unison.
+<br><br>
+<span class="wraith">"We may never reach the bottom. We can only hope."</span>
+<br><br>
+The pale figure holds you close.
+<<if $wraith.state is "haunt">>
+	<<His>> eyes flicker red for a brief moment, before returning to a calm blue.
+<<else>>
+	<<His>> deep blue eyes fill you with an inner peace.
+<</if>>
+<span class="wraith">"No one deserves to die in a cage."</span>
+<br><br>
+The world around you begins to shift.
+<br><br>
+<<link [[Next|Christmas Mirror 3]]>><<pass 5>><</link>>
+<br>
+
+:: Christmas Mirror 3
+<<effects>>
+You're in the middle of a large cathedral. Tables are set up for a great feast.
+All around you, faces you 
+<<if $wraithPrison and $wraithPrison.vision is true>>
+	vaguely
+<<else>>
+	don't
+<</if>>
+recognise smile and make merriments.
+They're all surrounded by a pale glow. The longer you look, the more translucent they become.
+<br><br>
+<span class="wraith">But for now, we are whole again. Enjoy it. Like sand slipping through our fingers."</span>
+<br><br>
+You find yourself returning the embrace. You don't want to let go. The inner warmth begins to fade, and the faces around you become unrecognisable. They begin to distort into unnatural shapes. You're instantly filled with panic. The pale figure slips backwards, out of your reach.
+<br><br>
+The tapestries on the walls peel away, revealing utter emptiness as the figures fall to the ground, cluthing the sides of their heads where their ears used to be. A bell tolls.
+<br><br>
+<<His>> skin turns marble white once again, and <<he>> begins to fade away. The faint <<wraithEyes>> light of <<his>> eyes flicker out in a rapidly expanding darkness.
+<br><br>
+<span class="wraith">"Remember us, not as we are, but as how we were."</span>
+<br><br>
+As the light draws away, you begin to fall. You can't hear wind in your ears, or against your skin, but somehow you know you're falling. Snowflakes and shards of glass brush past, mingling and dissolving.
+<br><br>
+<<link [[Reach out|Christmas Mirror 4]]>><</link>>
+<br>
+<<link [[Fall|Christmas Mirror Fall]]>><</link>>
+
+:: Christmas Mirror 4
+<<effects>>
+You reach your arm out. You're not sure what you're reaching for, but you feel a presence approach. It doesn't beckon you, but neither does it push you away.
+<br><br>
+
+<<if $wraithPrison and $wraithPrison.vision is true>>
+	<<link [[Apologise|Christmas Mirror 5]]>><<set $phase to 1>><</link>>
+<<else>>
+	<<link [[Ask|Christmas Mirror 5]]>><</link>>
+<</if>>
+<br>
+<<link [[Fall|Christmas Mirror Fall]]>><<set $phase to 1>><</link>>
+<br>
+
+:: Christmas Mirror 5
+<<effects>>
+You open your mouth.
+<<if $phase is 1>>
+	You try to apologise. For what it's been through, for what it's lived through, for all the ways it's suffered. For all the things you've done.
+<<else>>
+	You try to ask why. Why it follows you, why it torments you. Why it seeks you specifically, and why it brought you here.
+<</if>>
+<br><br>
+The words fail to form. But still, a response comes.
+<br><br>
+"<span class="wraith">I can't answer,</span>" <<he>> murmurs. <<He>> remains silent for a long time. "<span class="wraith">I would be wrong.</span>"
+<br><br>
+<<link [[Fall|Christmas Mirror Fall]]>><<set $phase to 1>><</link>>
+<br>
+
+:: Christmas Mirror Fall
+<<effects>>
+<<if $phase is 1>>
+	You let your arm drop back to your side.
+<</if>>
+You fall, and you fall, and further you fall still. You're not sure if you're falling down anymore. You're not sure where down is.
+<br><br>
+Your descent is beautiful.
+<br><br>
+
+<<link [[Wake up|Christmas Mirror End]]>><</link>>
+<br>
+
+:: Christmas Mirror End
+<<set $location to "home">><<set $outside to 0>><<effects>>
+You cry out, and shoot up. You're in your bed, sweating, and breathing heavily.
+<br><br>
+You rub the tiredness out of your eyes. You catch a glimpse of yourself in the mirror. You look pale. <<trauma 4>><<gtrauma>>
+<br><br>
+<<link [[Next|Bedroom]]>><<endevent>><<endWraith>><</link>>
+<br>
\ No newline at end of file
diff --git a/game/overworld-forest/loc-lake/ivory/schism.twee b/game/overworld-forest/loc-lake/ivory/schism.twee
index 7252b5c52c..dc284ac95a 100644
--- a/game/overworld-forest/loc-lake/ivory/schism.twee
+++ b/game/overworld-forest/loc-lake/ivory/schism.twee
@@ -21,7 +21,7 @@ All you can do now is wait, and pray.
 	<br><br>
 	You think about what happened. It's blurred together. You remember making preparations for a ritual, and then screaming. The <<people>> in black robes.
 	<br><br>
-	You decide not think so much, after all. You clutch your necklace.
+	You decide to not think so much, after all. You clutch your necklace.
 <<else>>
 	You kneel in the cell. It's spacious. You wonder why they aren't keeping multiple people in each cell.
 	<br><br>
diff --git a/game/overworld-plains/loc-moor/events.twee b/game/overworld-plains/loc-moor/events.twee
index e200539e3b..db0c5f300d 100644
--- a/game/overworld-plains/loc-moor/events.twee
+++ b/game/overworld-plains/loc-moor/events.twee
@@ -373,7 +373,7 @@ The creatures disappear into the mire.
 
 
 :: Moor Quicksand
-<<effects>><<rngWraith 2>><<if _wraithEvent>><<set $quicksandWraith to true>><</if>>
+<<effects>><<rngWraith 1>><<if _wraithEvent>><<set $quicksandWraith to true>><</if>>
 <<if $quicksandWraith>><<if $wraith.state is "haunt">><<set _drown to "Drown">><<else>><<set _drown to "Calm">><</if>><<ind>><<ind>><<ind>><span class="flicker">_drown</span><br><</if>>
 
 You are up to your
@@ -1045,7 +1045,7 @@ The water is cold, and deep. You swim away from shore. You can see nothing ahead
 <</if>>
 
 :: Moor Passage Swim 2
-<<effects>><<rngWraith 2>>
+<<effects>><<rngWraith 1>>
 
 Faced with an impenetrable darkness, you turn and swim back to the glowing shore. You search, until you find another exit. This one slopes upwards, and leads you back into the <<daylight>>
 <br><br>
diff --git a/game/overworld-town/loc-home/main.twee b/game/overworld-town/loc-home/main.twee
index d643c2cfa6..da89126b90 100644
--- a/game/overworld-town/loc-home/main.twee
+++ b/game/overworld-town/loc-home/main.twee
@@ -115,7 +115,13 @@ You are in your bedroom.
 	<br>
 	<<if $nextPassageCheck is "Mirror">>
 		<span class="nextLink"><<mirroricon>>[[Mirror]]</span>
-		<br>	
+		<br>
+	<<elseif $christmas is 1 and !$christmas_wraith and _wraithEvent>>
+		<br>
+		<span class="purple">You catch a strange glint in your mirror.</span>
+		<br>
+		<<bloodmirroricon>><<link [[Mirror|Christmas Mirror]]>><</link>>
+		<br>
 	<<elseif $hour is 3 and $hallucinations gte 2 and $mirrortentacles isnot 1 and $tentacledisable is "f">>
 		<br>
 		<span class="purple">An eerie light spills from your mirror.</span>
diff --git a/game/overworld-town/loc-museum/bdsm.twee b/game/overworld-town/loc-museum/bdsm.twee
index 263b1e5f81..9e2e985fee 100644
--- a/game/overworld-town/loc-museum/bdsm.twee
+++ b/game/overworld-town/loc-museum/bdsm.twee
@@ -175,7 +175,7 @@ With a final push of the lever, the chair lowers the rest of the way, submerging
 
 
 :: Museum Duck Extreme 3
-<<effects>><<rngWraith 2>>
+<<effects>><<rngWraith 1>>
 
 <<if $swimmingSuccess>>
 
diff --git a/game/overworld-town/loc-pub/seduction.twee b/game/overworld-town/loc-pub/seduction.twee
index 52bc41b01b..b85d873873 100644
--- a/game/overworld-town/loc-pub/seduction.twee
+++ b/game/overworld-town/loc-pub/seduction.twee
@@ -890,6 +890,8 @@ You knock <<him>> into the stall door, which <<he>> crashes through. <<tearful>>
 		You disappear with <<him>> into the forest. Shortly after <<he>> turns to you. "I always loved this forest," <<he>> says. "I have something for you." <<He>> holds out <<his>> hand, showing you a pink pill. "You'll like it. I promise."
 		<br><br>
 
+		<<link [[Eat the pill|Pub Wraith Mimic Hallucinogen]]>><<set $hallucinogen += 240>><<drugs 180>><</link>>
+		<br>
 		<<if $hallucinations gte 1>>
 			<<link [[Refuse|Pub Wraith Mimic Refuse]]>><</link>>
 		<<else>>
diff --git a/game/overworld-town/special-sydney/temple.twee b/game/overworld-town/special-sydney/temple.twee
index 3ae87eee28..9869e1bb4c 100644
--- a/game/overworld-town/special-sydney/temple.twee
+++ b/game/overworld-town/special-sydney/temple.twee
@@ -415,7 +415,7 @@ The two of you walk back to the main area of the temple. It takes some time, but
 			Realisation dawns as you lean back. Your <<penis>> is beautiful. Why should you care what other people say about it? You've gained the <span class="green">Acceptance: Tiny Penis</span> trait.
 			<br><br>
 		<</if>>
-		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>relevation<<else>>thoughts<</if>>.
+		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>revelation<<else>>thoughts<</if>>.
 	<<case 5>>
 		Your thoughts turn to your <<penis>>, and the mocking way people regard it. The torment returns. You pray for a bigger penis.
 		<br><br>
@@ -426,7 +426,7 @@ The two of you walk back to the main area of the temple. It takes some time, but
 			Realisation dawns as you lean back. Your <<penis>> is beautiful. Why should you care what other people say about it? You've gained the <span class="green">Acceptance: Small Penis</span> trait.
 			<br><br>
 		<</if>>
-		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>relevation<<else>>thoughts<</if>>.
+		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>revelation<<else>>thoughts<</if>>.
 	<<case 6>>
 		Your thoughts turn to your <<penis>>, and the mocking way people regard it. The torment returns. You pray for a smaller penis.
 		<br><br>
@@ -437,7 +437,7 @@ The two of you walk back to the main area of the temple. It takes some time, but
 			Realisation dawns as you lean back. Your <<penis>> is beautiful. Why should you care what other people say about it? You've gained the <span class="green">Acceptance: Big Penis</span> trait.
 			<br><br>
 		<</if>>
-		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>relevation<<else>>thoughts<</if>>.
+		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>revelation<<else>>thoughts<</if>>.
 	<<case 7>>
 		Your thoughts turn to your flat chest, and the mocking way people regard it. The torment returns. You pray for bigger breasts.
 		<br><br>
@@ -448,7 +448,7 @@ The two of you walk back to the main area of the temple. It takes some time, but
 			Realisation dawns as you lean back. Your chest is beautiful. Why should you care what other people say about it? You've gained the <span class="green">Acceptance: Tiny Breasts</span> trait.
 			<br><br>
 		<</if>>
-		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>relevation<<else>>thoughts<</if>>.
+		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>revelation<<else>>thoughts<</if>>.
 	<<case 8>>
 		Your thoughts turn to your <<breasts>>, and the mocking way people regard them. The torment returns. You try to remain detached.
 		<br><br>
@@ -459,7 +459,7 @@ The two of you walk back to the main area of the temple. It takes some time, but
 			Realisation dawns as you lean back. Your <<breasts>> are beautiful. Why should you care what other people say about them? You've gained the <span class="green">Acceptance: Small Breasts</span> trait.
 			<br><br>
 		<</if>>
-		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>relevation<<else>>thoughts<</if>>.
+		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>revelation<<else>>thoughts<</if>>.
 	<<case 9>>
 		Your thoughts turn to your <<breasts>>, and the mocking way people regard them. The torment returns. You pray for smaller breasts.
 		<br><br>
@@ -470,7 +470,7 @@ The two of you walk back to the main area of the temple. It takes some time, but
 			Realisation dawns as you lean back. Your <<breasts>> are beautiful. Why should you care what other people say about them? You've gained the <span class="green">Acceptance: Big Breasts</span> trait.
 			<br><br>
 		<</if>>
-		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>relevation<<else>>thoughts<</if>>.
+		Sydney keeps <<his>> head bowed, unaware of your <<if _acceptMessage>>revelation<<else>>thoughts<</if>>.
 <</switch>>
 <<npcincr Sydney purity 1>><<gspurity>>
 <br><br>
-- 
GitLab