From 14d577c8017f97a3052d7bf7dc8fc4344b042db6 Mon Sep 17 00:00:00 2001
From: ezsh <ezsh.junk@gmail.com>
Date: Sat, 1 Jun 2019 14:38:24 +0200
Subject: [PATCH] Replace pronouns strings with index of predefined pronoun set

---
 devTools/FC.d.ts                            | 12 +++++
 src/data/utility/pronouns.js                | 45 +++++++++++++++++
 src/endWeek/saWhore.js                      |  2 +-
 src/js/SlaveState.js                        |  7 +--
 src/js/assayJS.js                           | 49 +++++++-----------
 src/js/assignJS.js                          | 12 +++--
 src/js/datatypeCleanupJS.js                 | 37 ++++++++++++++
 src/js/rulesAutosurgery.js                  | 26 +++++-----
 src/js/slaveGenerationJS.js                 | 21 ++------
 src/js/slaveListing.js                      |  4 +-
 src/js/storyJS.js                           | 56 +++------------------
 src/js/utilJS.js                            |  6 +--
 src/npc/fFeelings.tw                        |  2 +-
 src/pregmod/incubatorRetrievalWorkaround.tw |  2 +-
 src/pregmod/rePregInventorText.tw           |  2 +-
 src/pregmod/widgets/pregmodWidgets.tw       | 26 +++++-----
 src/uncategorized/BackwardsCompatibility.tw |  6 +--
 src/uncategorized/seWeddingDouble.tw        |  2 +-
 src/uncategorized/slaveStats.tw             |  7 +--
 19 files changed, 170 insertions(+), 154 deletions(-)
 create mode 100644 src/data/utility/pronouns.js

diff --git a/devTools/FC.d.ts b/devTools/FC.d.ts
index 186f3b3073f..11e6183b2c1 100644
--- a/devTools/FC.d.ts
+++ b/devTools/FC.d.ts
@@ -22,6 +22,18 @@ interface Window {
 }
 
 declare namespace App {
+	namespace Data {
+		namespace Pronouns {
+			class Definition {
+				pronoun: string;
+				possessive: string;
+				possessivePronoun: string;
+				object: string;
+				objectReflexive: string;
+				noun: string;
+			};
+		}
+	}
 	namespace RA {
 		class NumericTarget {
 			cond: string;
diff --git a/src/data/utility/pronouns.js b/src/data/utility/pronouns.js
new file mode 100644
index 00000000000..58186a2338e
--- /dev/null
+++ b/src/data/utility/pronouns.js
@@ -0,0 +1,45 @@
+App.Data.Pronouns = {};
+
+/**
+ * @readonly
+ * @enum {number}
+ */
+App.Data.Pronouns.Kind = Object.freeze({
+	female: 0,
+	male: 1,
+	neutral: 2,
+	toy: 2,
+	epicene: 3,
+	plural: 3,
+	ai: 4,
+	custom: 1000
+});
+
+/**
+ * @param {string} pronoun
+ * @param {string} possessive
+ * @param {string} possessivePronoun
+ * @param {string} object
+ * @param {string} objectReflexive
+ * @param {string} noun
+ * @returns {App.Data.Pronouns.Definition}
+ */
+App.Data.Pronouns.makePronounsData = function(
+	pronoun, possessive, possessivePronoun, object, objectReflexive, noun) {
+	return {
+		pronoun: pronoun,
+		possessive: possessive,
+		possessivePronoun: possessivePronoun,
+		object: object,
+		objectReflexive: objectReflexive,
+		noun: noun
+	};
+};
+
+App.Data.Pronouns.Std = {
+	0: App.Data.Pronouns.makePronounsData("she", "her", "hers", "her",  "herself", "girl"),
+	1: App.Data.Pronouns.makePronounsData("he", "his", "his", "him", "himself", "boy"),
+	2: App.Data.Pronouns.makePronounsData("it", "its", "its", "it", "itself", "toy"),
+	3: App.Data.Pronouns.makePronounsData("they", "their", "theirs", "them", "themselves", "toys"),
+	4: App.Data.Pronouns.makePronounsData("it", "its", "its", "it", "itself", "program"),
+};
diff --git a/src/endWeek/saWhore.js b/src/endWeek/saWhore.js
index 28c5deb6149..b4c35d51199 100644
--- a/src/endWeek/saWhore.js
+++ b/src/endWeek/saWhore.js
@@ -353,7 +353,7 @@ window.saWhore = (function saWhore() {
 							if (slave.devotion <= 20) {
 								r += ` The Madam rapes ${him} when ${he} fails to meet standards.`;
 							} else {
-								r += ` The Madam uses ${madamPronouns.possessive} dick to reward ${him} when ${he} does well and needs some loving.`;
+								r += ` The Madam uses ${madamPronouns.his} dick to reward ${him} when ${he} does well and needs some loving.`;
 							}
 						}
 						if (!canHear(slave)) {
diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
index f6bd01962f5..9ba6705ecb6 100644
--- a/src/js/SlaveState.js
+++ b/src/js/SlaveState.js
@@ -306,12 +306,7 @@ App.Entity.SlaveState = class SlaveState {
 		this.birthSurname = 0;
 		/** slave sex ("XX", "XY") */
 		this.genes = "XX";
-		this.pronoun = "she";
-		this.possessive = "her";
-		this.possessivePronoun = "hers";
-		this.objectReflexive = "herself";
-		this.object = "her";
-		this.noun = "girl";
+		this.pronoun = App.Data.Pronouns.Kind.female;
 		/** game week slave was acquired.
 		*
 		* _0: Obtained prior to game start / at game start_ */
diff --git a/src/js/assayJS.js b/src/js/assayJS.js
index 83d5f4c1048..897c9277802 100644
--- a/src/js/assayJS.js
+++ b/src/js/assayJS.js
@@ -308,26 +308,11 @@ window.newChild = function newChild(child) {
 	}
 
 	if (child.fuckdoll > 0) {
-		child.pronoun = "it";
-		child.possessivePronoun = "its";
-		child.possessive = "its";
-		child.object = "it";
-		child.objectReflexive = "itself";
-		child.noun = "toy";
+		child.pronoun = App.Data.Pronouns.Kind.toy;
 	} else if (child.dick > 0 && child.vagina === -1 && V.diversePronouns === 1) {
-		child.pronoun = "he";
-		child.possessivePronoun = "his";
-		child.possessive = "his";
-		child.object = "him";
-		child.objectReflexive = "himself";
-		child.noun = "boy";
+		child.pronoun = App.Data.Pronouns.Kind.male;
 	} else {
-		child.pronoun = "she";
-		child.possessivePronoun = "hers";
-		child.possessive = "her";
-		child.object = "her";
-		child.objectReflexive = "herself";
-		child.noun = "girl";
+		child.pronoun = App.Data.Pronouns.Kind.female;
 	}
 	State.variables.cribs.push(child);
 	State.variables.nurseryBabies++;
@@ -374,18 +359,21 @@ window.getChild = function getChild(ID) {
 
 App.Utils.Pronouns = class {
 	/**
-	 * @param {App.Entity.SlaveState} slave
+	 * @param {{pronoun: number}} obj
 	 */
-	constructor(slave) {
-		this._slave = slave;
+	constructor(obj) {
+		/** @type {App.Data.Pronouns.Definition} */
+		this._pronouns = obj.pronoun < App.Data.Pronouns.Kind.custom ?
+			App.Data.Pronouns.Std[obj.pronoun] :
+			State.variables.customPronouns[obj.pronoun];
 	}
 
-	get pronoun() { return this._slave.pronoun; }
-	get possessivePronoun() { return this._slave.possessivePronoun; }
-	get possessive() { return this._slave.possessive; }
-	get object() { return this._slave.object; }
-	get objectReflexive() { return this._slave.objectReflexive; }
-	get noun() { return this._slave.noun; }
+	get pronoun() { return this._pronouns.pronoun; }
+	get possessivePronoun() { return this._pronouns.possessivePronoun; }
+	get possessive() { return this._pronouns.possessive; }
+	get object() { return this._pronouns.object; }
+	get objectReflexive() { return this._pronouns.objectReflexive; }
+	get noun() { return this._pronouns.noun; }
 
 	get Pronoun() { return capFirstChar(this.pronoun); }
 	get PossessivePronoun() { return capFirstChar(this.possessivePronoun); }
@@ -394,7 +382,6 @@ App.Utils.Pronouns = class {
 	get ObjectReflexive() { return capFirstChar(this.objectReflexive); }
 	get Noun() { return capFirstChar(this.noun); }
 
-
 	get he() { return this.pronoun; }
 	get him() { return this.object; }
 	get his() { return this.possessive; }
@@ -425,11 +412,11 @@ App.Utils.Pronouns = class {
 };
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {{pronoun: number}} obj
  * @returns {App.Utils.Pronouns}
  */
-window.getPronouns = function(slave) {
-	return new App.Utils.Pronouns(slave);
+window.getPronouns = function(obj) {
+	return new App.Utils.Pronouns(obj);
 };
 
 /**
diff --git a/src/js/assignJS.js b/src/js/assignJS.js
index 71104c7abbf..35d9b8a7bc4 100644
--- a/src/js/assignJS.js
+++ b/src/js/assignJS.js
@@ -585,15 +585,16 @@ App.UI.jobLinks = function() {
 	function assignmentLinks(index, passage, callback) {
 		let penthouseJobs = App.Entity.facilities.penthouse.assignmentLinks(index, undefined, passage, callback);
 		const slave = App.Utils.slaveByIndex(index);
+		const sp = getPronouns(slave);
 
 		if (slave.fuckdoll === 0) {
 			const assignment = "choose her own job";
 			if (slave.assignment !== assignment) {
 				const linkAction = callback !== undefined ? callback(assignment) : '';
-				penthouseJobs.push(`<<link "Let ${slave.object} choose" ${passage !== undefined ? `"${passage}"` : ''}>><<= assignJob(${App.Utils.slaveRefString(index)}, "${assignment}")>>${linkAction}<</link>>`);
+				penthouseJobs.push(`<<link "Let ${sp.object} choose" ${passage !== undefined ? `"${passage}"` : ''}>><<= assignJob(${App.Utils.slaveRefString(index)}, "${assignment}")>>${linkAction}<</link>>`);
 			}
 		} else {
-			penthouseJobs.push(App.UI.disabledLink(`Let ${slave.object} choose`, ["Fuckdolls can't choose their job"]));
+			penthouseJobs.push(App.UI.disabledLink(`Let ${sp.object} choose`, ["Fuckdolls can't choose their job"]));
 		}
 
 		return penthouseJobs.join("&thinsp;|&thinsp;");
@@ -623,6 +624,7 @@ App.UI.SlaveInteract = {
 		let res = "";
 		/** @type {App.Entity.SlaveState} */
 		const slave = State.variables.activeSlave;
+		const {his} = getPronouns(slave);
 		if ((slave.assignment === "please you") || (slave.assignment === "serve in the master suite") || (slave.assignment === "be your Concubine")) {
 			res += `__Fucktoy use preference__: <strong><span id = "hole">${slave.toyHole}</span></strong>.`;
 			/** @type {string[]} */
@@ -633,18 +635,18 @@ App.UI.SlaveInteract = {
 				links.push('<<link "Pussy">><<set $activeSlave.toyHole = "pussy">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
 			} else if (slave.vagina === 0) {
 				links.push(App.UI.disabledLink("Pussy",
-					[`Take ${slave.possessive} virginity before giving ${slave.possessive} pussy special attention`]));
+					[`Take ${his} virginity before giving ${his} pussy special attention`]));
 			}
 			if ((slave.anus > 0) && canDoAnal(slave)) {
 				links.push('<<link "Ass">><<set $activeSlave.toyHole = "ass">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
 			} else {
 				links.push(App.UI.disabledLink("Ass",
-					[`Take ${slave.possessive} anal virginity before giving ${slave.possessive} ass special attention`]));
+					[`Take ${his} anal virginity before giving ${his} ass special attention`]));
 			}
 			if ((slave.dick > 0) && canPenetrate(slave)) {
 				links.push('<<link "Dick">><<set $activeSlave.toyHole = "dick">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
 			}
-			links.push(`<<link "No Preference">><<set $activeSlave.toyHole = "all ${slave.possessive} holes">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>`);
+			links.push(`<<link "No Preference">><<set $activeSlave.toyHole = "all ${his} holes">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>`);
 			res += links.join('&thinsp;|&thinsp;') + '<br>';
 		}
 		App.UI.replace('#fucktoypref', res);
diff --git a/src/js/datatypeCleanupJS.js b/src/js/datatypeCleanupJS.js
index 7cecca0938c..b02747d3c49 100644
--- a/src/js/datatypeCleanupJS.js
+++ b/src/js/datatypeCleanupJS.js
@@ -18,6 +18,7 @@ App.Entity.Utils.SlaveDataSchemeCleanup = (function() {
 		migrateCounters(slave);
 		migrateCustomProperties(slave);
 		migrateBrand(slave);
+		App.Entity.Utils.migratePronouns(slave);
 	}
 
 	/**
@@ -1572,6 +1573,7 @@ window.PCDatatypeCleanup = function PCDatatypeCleanup() {
 	PC.mpreg = 0; /* So knockMeUp() may be used with the PC */
 	PC.lactation = Math.max(+PC.lactation, 0) || 0;
 	PC.lactationDuration = Math.max(+PC.lactationDuration, 0) || 0;
+	App.Entity.Utils.migratePronouns(PC);
 	generatePlayerPronouns(PC);
 
 	if (PC.age !== undefined) {
@@ -1695,6 +1697,8 @@ window.ArcologyDatatypeCleanup = function ArcologyDatatypeCleanup() {
 	if (typeof V.marketAssistantPronouns !== "object") {
 		V.marketAssistantPronouns = {};
 	}
+	App.Entity.Utils.migratePronouns(V.assistantPronouns);
+	App.Entity.Utils.migratePronouns(V.marketAssistantPronouns);
 	generateAssistantPronouns();
 
 	V.foodCost = Math.trunc(2500 / V.economy);
@@ -1749,6 +1753,9 @@ window.FacilityDatatypeCleanup = (function() {
 		CellblockDatatypeCleanup();
 		MasterSuiteDatatypeCleanup();
 		HeadGirlSuiteDatatypeCleanup();
+
+		V.Recruiter = V.slaves.find(s => s.assignment === "recruit girls") || 0;
+		V.Bodyguard = V.slaves.find(s => s.assignment === "guard you") || 0;
 	}
 
 	function FacilityIDArrayCleanup() {
@@ -2172,3 +2179,33 @@ App.Entity.Utils.validateRules = function() {
 		}
 	}
 };
+
+/** @param {Object} subject */
+App.Entity.Utils.migratePronouns = function(subject) {
+	if (subject.pronoun === undefined || typeof subject.pronoun === 'number') {
+		return;
+	}
+
+	switch (subject.pronoun) {
+		case "she":
+			subject.pronoun = App.Data.Pronouns.Kind.female;
+			break;
+		case "he":
+			subject.pronoun = App.Data.Pronouns.Kind.male;
+			break;
+		case "it":
+			subject.pronoun = App.Data.Pronouns.Kind.neutral;
+			break;
+		default:
+			throw `Unrecognized custom pronoun "${subject.pronoun}"`;
+	}
+
+	/* eslint-disable dot-notation */
+	delete subject["possessive"];
+	delete subject["possessivePronoun"];
+	delete subject["possessivePronoun"];
+	delete subject["objectReflexive"];
+	delete subject["object"];
+	delete subject["noun"];
+	/* eslint-enable dot-notation */
+}
diff --git a/src/js/rulesAutosurgery.js b/src/js/rulesAutosurgery.js
index d7413c56fbd..04a3c5e82ba 100644
--- a/src/js/rulesAutosurgery.js
+++ b/src/js/rulesAutosurgery.js
@@ -141,6 +141,8 @@ window.rulesAutosurgery = (function() {
 	 * @param {string[]} surgeries
 	 */
 	function CommitSurgery(slave, thisSurgery, surgeries) {
+		const {his} = getPronouns(slave);
+
 		/**
 		 * Performs an individual surgery procedure
 		 * @param {string} desc
@@ -166,7 +168,7 @@ window.rulesAutosurgery = (function() {
 			let sorter;
 			if (shallShrink) {
 				if (target.val === 0) {
-					commitProcedure(`surgery to remove ${slave.possessive} ${bodyPart} implants`, slave => {
+					commitProcedure(`surgery to remove ${his} ${bodyPart} implants`, slave => {
 						slave[bodyPart] -= slave[`${bodyPart}Implant`];
 						slave[`${bodyPart}Implant`] = 0;
 						slave[`${bodyPart}ImplantType`] = 0;
@@ -200,26 +202,26 @@ window.rulesAutosurgery = (function() {
 		// (reading properties of the 'null' object)
 		if (slave.health > 20 && surgeries.length < 3) {
 			if (slave.eyes === -1 && thisSurgery.eyes === 1) {
-				commitProcedure(`surgery to correct ${slave.possessive} vision`, s => { s.eyes = 1; });
+				commitProcedure(`surgery to correct ${his} vision`, s => { s.eyes = 1; });
 			} else if (slave.eyes === 1 && thisSurgery.eyes === -1) {
-				commitProcedure(`surgery to blur ${slave.possessive} vision`, s => { s.eyes = -1; });
+				commitProcedure(`surgery to blur ${his} vision`, s => { s.eyes = -1; });
 			} else if (slave.hears === -1 && thisSurgery.hears === 0) {
-				commitProcedure(`surgery to correct ${slave.possessive} hearing`, s => { s.hears = 0; });
+				commitProcedure(`surgery to correct ${his} hearing`, s => { s.hears = 0; });
 			} else if (slave.hears === 0 && thisSurgery.hears === -1) {
-				commitProcedure(`surgery to muffle ${slave.possessive} hearing`, s => { s.hears = -1; });
+				commitProcedure(`surgery to muffle ${his} hearing`, s => { s.hears = -1; });
 			} else if (slave.smells === -1 && thisSurgery.smells === 0) {
-				commitProcedure(`surgery to correct ${slave.possessive} sense of smell`, s => { s.smells = 0; });
+				commitProcedure(`surgery to correct ${his} sense of smell`, s => { s.smells = 0; });
 			} else if (slave.smells === 0 && thisSurgery.smells === -1) {
-				commitProcedure(`surgery to muffle ${slave.possessive} sense of smell`, s => { s.smells = -1; });
+				commitProcedure(`surgery to muffle ${his} sense of smell`, s => { s.smells = -1; });
 			} else if (slave.tastes === -1 && thisSurgery.tastes === 0) {
-				commitProcedure(`surgery to correct ${slave.possessive} sense of taste`, s => { s.tastes = 0; });
+				commitProcedure(`surgery to correct ${his} sense of taste`, s => { s.tastes = 0; });
 			} else if (slave.tastes === 0 && thisSurgery.tastes === -1) {
-				commitProcedure(`surgery to muffle ${slave.possessive} sense of taste`, s => { s.tastes = -1; });
+				commitProcedure(`surgery to muffle ${his} sense of taste`, s => { s.tastes = -1; });
 			}
 		}
 		if (slave.health > 20 && surgeries.length < 3) {
 			if (slave.lactation === 2 && thisSurgery.lactation === 0) {
-				commitProcedure(`surgery to remove ${slave.possessive} lactation implants`, s => { s.lactation = 0; });
+				commitProcedure(`surgery to remove ${his} lactation implants`, s => { s.lactation = 0; });
 			} else if (slave.lactation !== 2 && (thisSurgery.lactation === 1)) {
 				commitProcedure("lactation inducing implanted drugs", s => { s.lactation = 2; });
 			} else if ((slave.boobShape === "saggy" || slave.boobShape === "downward-facing") && thisSurgery.cosmetic > 0 && slave.breastMesh !== 1) {
@@ -286,7 +288,7 @@ window.rulesAutosurgery = (function() {
 		}
 		if (slave.health > 20 && surgeries.length < 3) {
 			if (slave.prostate === 2 && thisSurgery.prostate === 0) {
-				commitProcedure(`surgery to remove ${slave.possessive} prostate implant`, s => { s.prostate = 0; });
+				commitProcedure(`surgery to remove ${his} prostate implant`, s => { s.prostate = 0; });
 			} else if (slave.prostate === 1 && thisSurgery.prostate === 1) {
 				commitProcedure("a precum production enhancing drug implant", s => { s.prostate = 2; });
 			} else if (slave.balls > 0 && slave.vasectomy === 0 && thisSurgery.vasectomy === true) {
@@ -338,7 +340,7 @@ window.rulesAutosurgery = (function() {
 					slave.voiceImplant += 1;
 				});
 			} else if (App.RA.shallShrink(slave.lipsImplant, thisSurgery.lips) && thisSurgery.lips.val === 0) {
-				commitProcedure(`surgery to remove ${slave.possessive} lip implants`, slave => {
+				commitProcedure(`surgery to remove ${his} lip implants`, slave => {
 					slave.lips -= slave.lipsImplant;
 					slave.lipsImplant = 0;
 					if (slave.skill.oral > 10) {
diff --git a/src/js/slaveGenerationJS.js b/src/js/slaveGenerationJS.js
index 6a73a072c8d..5a501392505 100644
--- a/src/js/slaveGenerationJS.js
+++ b/src/js/slaveGenerationJS.js
@@ -1506,26 +1506,11 @@ window.BaseSlave = function BaseSlave() {
  * @param {App.Entity.SlaveState} slave*/
 window.generatePronouns = function generatePronouns(slave) {
 	if (slave.fuckdoll > 0) {
-		slave.pronoun = "it";
-		slave.possessivePronoun = "its";
-		slave.possessive = "its";
-		slave.object = "it";
-		slave.objectReflexive = "itself";
-		slave.noun = "toy";
+		slave.pronoun = App.Data.Pronouns.Kind.toy;
 	} else if (slave.dick > 0 && slave.vagina === -1 && State.variables.diversePronouns === 1) {
-		slave.pronoun = "he";
-		slave.possessivePronoun = "his";
-		slave.possessive = "his";
-		slave.object = "him";
-		slave.objectReflexive = "himself";
-		slave.noun = "boy";
+		slave.pronoun = App.Data.Pronouns.Kind.male;
 	} else {
-		slave.pronoun = "she";
-		slave.possessivePronoun = "hers";
-		slave.possessive = "her";
-		slave.object = "her";
-		slave.objectReflexive = "herself";
-		slave.noun = "girl";
+		slave.pronoun = App.Data.Pronouns.Kind.female;
 	}
 };
 
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index 665d43b32eb..7f9b9d32fdd 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -382,7 +382,7 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 		SlaveSort.indices(facilitySlaves);
 		r += App.UI.tabbar.makeTab("remove", App.UI.SlaveList.render(facilitySlaves, [],
 			App.UI.SlaveList.SlaveInteract.stdInteract,
-			(slave, index) => App.UI.passageLink(`Retrieve ${slave.object} from ${facility.name}`, "Retrieve", `$i = ${index}`)));
+			(slave, index) => App.UI.passageLink(`Retrieve ${getPronouns(slave).object} from ${facility.name}`, "Retrieve", `$i = ${index}`)));
 	} else {
 		r += App.UI.tabbar.makeTab("remove", `<em>${capFirstChar(facility.name)} is empty for the moment</em>`);
 	}
@@ -406,7 +406,7 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 		}, []);
 		return App.UI.SlaveList.render(passedSlaves, rejectedSlaves,
 			App.UI.SlaveList.SlaveInteract.stdInteract,
-			(slave, index) => App.UI.passageLink(`Send ${slave.object} to ${facility.name}`, "Assign", `$i = ${index}`));
+			(slave, index) => App.UI.passageLink(`Send ${getPronouns(slave).object} to ${facility.name}`, "Assign", `$i = ${index}`));
 	}
 	if (facility.hasFreeSpace) {
 		// slaves from the penthouse can be transferred here
diff --git a/src/js/storyJS.js b/src/js/storyJS.js
index 3e2cc541529..55e6e472859 100644
--- a/src/js/storyJS.js
+++ b/src/js/storyJS.js
@@ -595,68 +595,28 @@ window.SoftenSexualFlaw = function SoftenSexualFlaw(slave) {
  */
 window.generatePlayerPronouns = function(PC) {
 	if (PC.title === 0) {
-		PC.pronoun = "she";
-		PC.possessivePronoun = "hers";
-		PC.possessive = "her";
-		PC.object = "her";
-		PC.objectReflexive = "herself";
-		PC.noun = "woman";
+		PC.pronoun = App.Data.Pronouns.Kind.female;
 	} else {
-		PC.pronoun = "he";
-		PC.possessivePronoun = "his";
-		PC.possessive = "his";
-		PC.object = "him";
-		PC.objectReflexive = "himself";
-		PC.noun = "man";
+		PC.pronoun = App.Data.Pronouns.Kind.male;
 	}
 };
 
 window.generateAssistantPronouns = function() {
 	const V = State.variables;
 	if (V.assistant === 0) {
-		V.assistantPronouns.pronoun = "it";
-		V.assistantPronouns.possessivePronoun = "its";
-		V.assistantPronouns.possessive = "its";
-		V.assistantPronouns.object = "it";
-		V.assistantPronouns.objectReflexive = "itself";
-		V.assistantPronouns.noun = "program";
+		V.assistantPronouns.pronoun = App.Data.Pronouns.Kind.ai;
 	} else if ((V.assistantAppearance === "incubus") && (V.diversePronouns === 1)) {
-		V.assistantPronouns.pronoun = "he";
-		V.assistantPronouns.possessivePronoun = "his";
-		V.assistantPronouns.possessive = "his";
-		V.assistantPronouns.object = "him";
-		V.assistantPronouns.objectReflexive = "himself";
-		V.assistantPronouns.noun = "boy";
+		V.assistantPronouns.pronoun = App.Data.Pronouns.Kind.male;
 	} else {
-		V.assistantPronouns.pronoun = "she";
-		V.assistantPronouns.possessivePronoun = "hers";
-		V.assistantPronouns.possessive = "her";
-		V.assistantPronouns.object = "her";
-		V.assistantPronouns.objectReflexive = "herself";
-		V.assistantPronouns.noun = "girl";
+		V.assistantPronouns.pronoun = App.Data.Pronouns.Kind.female;
 	}
 
 	if (V.assistant === 0) {
-		V.marketAssistantPronouns.pronoun = "it";
-		V.marketAssistantPronouns.possessivePronoun = "its";
-		V.marketAssistantPronouns.possessive = "its";
-		V.marketAssistantPronouns.object = "it";
-		V.marketAssistantPronouns.objectReflexive = "itself";
-		V.marketAssistantPronouns.noun = "program";
+		V.marketAssistantPronouns.pronoun = App.Data.Pronouns.Kind.ai;
 	} else if ((V.assistantAppearance === "succubus") && (V.diversePronouns === 1)) {
-		V.marketAssistantPronouns.pronoun = "he";
-		V.marketAssistantPronouns.possessivePronoun = "his";
-		V.marketAssistantPronouns.possessive = "his";
-		V.marketAssistantPronouns.object = "him";
-		V.marketAssistantPronouns.objectReflexive = "himself";
-		V.marketAssistantPronouns.noun = "boy";
+		V.marketAssistantPronouns.pronoun = App.Data.Pronouns.Kind.male;
 	} else {
-		V.marketAssistantPronouns.pronoun = "she";
-		V.marketAssistantPronouns.possessivePronoun = "hers";
-		V.marketAssistantPronouns.possessive = "her";
-		V.marketAssistantPronouns.object = "her";
-		V.marketAssistantPronouns.objectReflexive = "herself";
-		V.marketAssistantPronouns.noun = "girl";
+		V.marketAssistantPronouns.pronoun = App.Data.Pronouns.Kind.female;
 	}
 };
 
diff --git a/src/js/utilJS.js b/src/js/utilJS.js
index 1fe4ca0f8e7..727b4743319 100644
--- a/src/js/utilJS.js
+++ b/src/js/utilJS.js
@@ -1703,8 +1703,7 @@ window.removeDuplicates = function removeDuplicates(array) {
  * @returns {string}
  */
 window.induceLactation = function induceLactation(slave) {
-	let pronouns = getPronouns(slave);
-	let His = capFirstChar(pronouns.possessive);
+	const {His} = getPronouns(slave);
 	let r = "";
 	if (slave.induceLactation >= 10) {
 		if (jsRandom(1, 100) < slave.induceLactation) {
@@ -2442,8 +2441,7 @@ window.SkillIncrease = (function() {
 	 * @returns {string}
 	 */
 	function OralSkillIncrease(slave, skillIncrease = 1) {
-		const He = capFirstChar(slave.pronoun);
-		const his = slave.possessivePronoun;
+		const {He, his} = getPronouns(slave)
 		let r = "";
 
 		if (slave.skill.oral <= 10) {
diff --git a/src/npc/fFeelings.tw b/src/npc/fFeelings.tw
index 3f10306a37b..382aff296a0 100644
--- a/src/npc/fFeelings.tw
+++ b/src/npc/fFeelings.tw
@@ -1133,7 +1133,7 @@ My favorite part of my body i<<s>>
 	<<elseif $activeSlave.relationship <= 4>>
 		I really love _partnerName." $He blushes. "Thank you for letting u<<s>> be together, <<Master>>.
 	<<else>>
-		I'm <<s>>o happy with _partnerName." $He blushes. "Thank you for $slaves[_partner].object, <<Master>>.
+		I'm <<s>>o happy with _partnerName." $He blushes. "Thank you for _him2, <<Master>>.
 	<</if>>
 	<<if $activeSlave.relationship >= 3>>
 		<<if $activeSlave.mother == $slaves[_partner].ID>>
diff --git a/src/pregmod/incubatorRetrievalWorkaround.tw b/src/pregmod/incubatorRetrievalWorkaround.tw
index 083cf594fdb..e05ee222b88 100644
--- a/src/pregmod/incubatorRetrievalWorkaround.tw
+++ b/src/pregmod/incubatorRetrievalWorkaround.tw
@@ -100,4 +100,4 @@
 
 	<</for>>
 	<<set $newSlavePool = 0>>
-<</if>>
\ No newline at end of file
+<</if>>
diff --git a/src/pregmod/rePregInventorText.tw b/src/pregmod/rePregInventorText.tw
index 30421c5e3d6..08bc838ef68 100644
--- a/src/pregmod/rePregInventorText.tw
+++ b/src/pregmod/rePregInventorText.tw
@@ -113,7 +113,7 @@
 		<<elseif $activeSlave.amp < 1>>
 			$He signs that $he'd like to give her a "hands-on demonstration" instead.
 		<<else>>
-			One of $his menials pushes _hisU body into the breeder's enormous stomach in a possessive manner, then turns to regard Millie. "My <<if $activeSlave.noun == "girl">>mistress<<else>>master<</if>> would like to give you a 'hands-on' demonstration, instead," _heU says.
+			One of $his menials pushes _hisU body into the breeder's enormous stomach in a possessive manner, then turns to regard Millie. "My <<if getPronouns($activeSlave).noun == "girl">>mistress<<else>>master<</if>> would like to give you a 'hands-on' demonstration, instead," _heU says.
 		<</if>>
 		<br><br>
 		The host quirks an eyebrow, then nods. "Alright," she says. "How about we start with that pool of yours?" She then strips her outer layer of clothing, showing off her own famously heavily pregnant figure in an inadequate bra and panties. She makes her way to the curative jelly filled pool, after your slave has been situated within it. Millie dips a toe into the substance and giggles. "Oh my, it tingles!"
diff --git a/src/pregmod/widgets/pregmodWidgets.tw b/src/pregmod/widgets/pregmodWidgets.tw
index fe2bd89bad2..b1ad071d584 100644
--- a/src/pregmod/widgets/pregmodWidgets.tw
+++ b/src/pregmod/widgets/pregmodWidgets.tw
@@ -284,12 +284,13 @@
 <</widget>>
 
 <<widget "setAssistantPronouns">>
-	<<set _girlA = $assistantPronouns.noun>>
-	<<set _hisA = $assistantPronouns.possessive>>
-	<<set _hersA = $assistantPronouns.possessivePronoun>>
-	<<set _heA = $assistantPronouns.pronoun>>
-	<<set _himA = $assistantPronouns.object>>
-	<<set _himselfA = $assistantPronouns.objectReflexive>>
+	<<set _ap = getPronouns($assistantPronouns)>>
+	<<set _girlA = _ap.noun>>
+	<<set _hisA = _ap.possessive>>
+	<<set _hersA = _ap.possessivePronoun>>
+	<<set _heA = _ap.pronoun>>
+	<<set _himA = _ap.object>>
+	<<set _himselfA = _ap.objectReflexive>>
 	<<if _girlA == "girl">>
 		<<set _womanA = "woman", _loliA = "loli", _womenA = "women">>
 	<<else>>
@@ -303,12 +304,13 @@
 	<<set _HimA = capFirstChar(_himA)>>
 	<<set _HimselfA = capFirstChar(_himselfA)>>
 
-	<<set _girlM = $marketAssistantPronouns.noun>>
-	<<set _hisM = $marketAssistantPronouns.possessive>>
-	<<set _hersM = $marketAssistantPronouns.possessivePronoun>>
-	<<set _heM = $marketAssistantPronouns.pronoun>>
-	<<set _himM = $marketAssistantPronouns.object>>
-	<<set _himselfM = $marketAssistantPronouns.objectReflexive>>
+	<<set _amp = getPronouns($marketAssistantPronouns)>>
+	<<set _girlM = _amp.noun>>
+	<<set _hisM = _amp.possessive>>
+	<<set _hersM = _amp.possessivePronoun>>
+	<<set _heM = _amp.pronoun>>
+	<<set _himM = _amp.object>>
+	<<set _himselfM = _amp.objectReflexive>>
 	<<if _girlM == "girl">>
 		<<set _womanM = "woman", _loliM = "loli", _womenM = "women">>
 	<<else>>
diff --git a/src/uncategorized/BackwardsCompatibility.tw b/src/uncategorized/BackwardsCompatibility.tw
index e9e4c113cdb..ce0fce4bfd4 100644
--- a/src/uncategorized/BackwardsCompatibility.tw
+++ b/src/uncategorized/BackwardsCompatibility.tw
@@ -264,11 +264,7 @@
 	<<set $PC.markings = "none">>
 <</if>>
 <<if ndef $PC.pronoun>>
-	<<if $PC.title == 1>>
-		<<set $PC.pronoun = "he", $PC.possessive = "his", $PC.object = "him">>
-	<<else>>
-		<<set $PC.pronoun = "she", $PC.possessive = "her", $PC.object = "her">>
-	<</if>>
+	<<run generatePlayerPronouns($PC)>>
 <</if>>
 <<if ndef $PC.pregKnown>>
 	<<if $PC.preg > 0>>
diff --git a/src/uncategorized/seWeddingDouble.tw b/src/uncategorized/seWeddingDouble.tw
index 86fa63b160f..f8386ee015e 100644
--- a/src/uncategorized/seWeddingDouble.tw
+++ b/src/uncategorized/seWeddingDouble.tw
@@ -1008,7 +1008,7 @@
 		<<elseif _slave1.devotion < -20 && _slave1.trust > 20>>
 			The slaves are unwilling, so you gather _slave1.slaveName up and hold $him in front of you, pulling $his panties off as you do. $He was crying before, but this causes $him to tremble and tear up in anticipation of what's next. Ignoring this, you maneuver your dick inside $him while holding $him against your <<if $PC.boobs == 1>>breasts<<elseif $PC.title == 0>>flat chest<<else>>strong chest<</if>>.<<if _slave1.amp != 1>> Then you pull $his knees up to give your guests a good view of the consummation.<</if>> $He is left to face them, watching sullenly as you fuck $his fertile <<if _slave1.mpreg == 1>>asshole<<else>>cunt<</if>>. Though $his face is towards the crowd, $his mind is concentrated on your hard cock, pumping in and out of $him at an angle; to $him, this is torture. $He gasps when your seed flows into $him, faking an orgasm to @@.green;applause from your guests.@@ At this, $he shoots you a dirty look, blaming you for this indignity. You've already moved on to _slave2.slaveName, however. _He2 had watched timidly as you had fucked _slave1.slaveName, but when you grab _him2, _he2 begins to cry softly. You ignore this, of course, and instead focus on pushing your already-hard cock into _his2 <<if _slave2.mpreg == 1>>asshole<<else>>pussy<</if>>. You can tell _he2 is trying _his2 hardest not to sob outright, and sure enough, a small sob escapes _his2 lips when you fill _him2 to the brim to the @@.green;applause of your guests.@@ You'll fuck them repeatedly over the next few days, ensuring impregnation, despite their efforts to defy you.
 		<<elseif _slave1.devotion < -20>>
-			The <<if _slave1.noun == _slave2.noun>><<= $girl>>s<<else>>slaves<</if>> are unwilling, so you gather _slave1.slaveName up and hold $him in front of you, pulling $his panties off as you do. $He was crying before, but this causes $him to tremble and sob loudly in anticipation of what's next. Ignoring this, you maneuver your dick inside $him while holding $him against your <<if $PC.boobs == 1>>breasts<<elseif $PC.title == 0>>flat chest<<else>>strong chest<</if>>.<<if _slave1.amp != 1>> Then you pull $his knees up to give your guests a good view of the consummation.<</if>> $He is left to face them, watching sullenly as you fuck $his fertile <<if _slave1.mpreg == 1>>asshole<<else>>cunt<</if>>. Though $his face is towards the crowd, $his mind is concentrated on your hard cock, pumping in and out of $him at an angle; to $him, this is torture. $He gasps when your seed flows into $him, orgasming unwillingly to @@.green;applause from your guests.@@ At this, $he completely breaks down, blubbering like a child at the unwelcome warmth in $his lower belly. You then turn your attention to _slave2.slaveName. _He2 had watched timidly as you had fucked _slave1.slaveName, but when you grab _him2, _he2 begins to cry softly. You ignore this, of course, and instead focus on pushing your already-hard cock into _his2 <<if _slave2.mpreg == 1>>asshole<<else>>pussy<</if>>. You can tell _he2 is trying _his2 hardest not to sob outright, and sure enough, a small sob escapes _his2 lips when you fill _him2 to the brim to the @@.green;applause of your guests.@@ You'll fuck them repeatedly over the next few days, ensuring impregnation, despite their protesting.
+			The <<if _slave1.pronoun == _slave2.pronoun>><<= $girl>>s<<else>>slaves<</if>> are unwilling, so you gather _slave1.slaveName up and hold $him in front of you, pulling $his panties off as you do. $He was crying before, but this causes $him to tremble and sob loudly in anticipation of what's next. Ignoring this, you maneuver your dick inside $him while holding $him against your <<if $PC.boobs == 1>>breasts<<elseif $PC.title == 0>>flat chest<<else>>strong chest<</if>>.<<if _slave1.amp != 1>> Then you pull $his knees up to give your guests a good view of the consummation.<</if>> $He is left to face them, watching sullenly as you fuck $his fertile <<if _slave1.mpreg == 1>>asshole<<else>>cunt<</if>>. Though $his face is towards the crowd, $his mind is concentrated on your hard cock, pumping in and out of $him at an angle; to $him, this is torture. $He gasps when your seed flows into $him, orgasming unwillingly to @@.green;applause from your guests.@@ At this, $he completely breaks down, blubbering like a child at the unwelcome warmth in $his lower belly. You then turn your attention to _slave2.slaveName. _He2 had watched timidly as you had fucked _slave1.slaveName, but when you grab _him2, _he2 begins to cry softly. You ignore this, of course, and instead focus on pushing your already-hard cock into _his2 <<if _slave2.mpreg == 1>>asshole<<else>>pussy<</if>>. You can tell _he2 is trying _his2 hardest not to sob outright, and sure enough, a small sob escapes _his2 lips when you fill _him2 to the brim to the @@.green;applause of your guests.@@ You'll fuck them repeatedly over the next few days, ensuring impregnation, despite their protesting.
 		<<else>>
 			Your wives-to-be aren't particularly excited about what's coming, but they're fully prepared for it and have accepted it as a fact of life. There are worse things one can be than the slave-wife of a wealthy arcology owner. You <<if _slave1.amp == 1>>gather _slave1.slaveName.slaveName up and hold $him in front of you, pulling $his panties off as you do. Showing considerable dexterity, you maneuver your dick inside $him while holding $him against your <<if $PC.boobs == 1>>breasts<<elseif $PC.title == 0>>flat chest<<else>>strong chest<</if>><<else>>take _slave1.slaveName's hand and pull $him to $his feet while $he shimmies out of $his panties. $He cocks $his hips for you and you slide your cock inside $him before taking $his knees and drawing them up to hold $him in midair, impaled on you<</if>>. Though $his face is towards the crowd, their mind is concentrated on your hard cock, pumping in and out of $him at an angle; to $him, it's just another part of being your slave. $He gasps when your seed flows into $him, orgasming shortly after to @@.green;applause from your guests.@@ Next, you turn your attention to _slave2.slaveName. You <<if (_slave1.amp == 1 && _slave2.amp == 1)>>also <</if>><<if _slave2.amp == 1>>pick _him2 up, then <<else>>pull _him2 to _his2 feet and <</if>>pull _his2 g-string off in one swift motion, then maneuver your already-hard cock into _his2 <<if _slave2.mpreg == 1>>asshole<<else>>pussy<</if>>. You fuck _him2, hard, then fill _him2 to the brim @@.green;while your audience gives another round of applause.@@ You'll fuck them repeatedly over the next few days, ensuring impregnation.
 		<</if>>
diff --git a/src/uncategorized/slaveStats.tw b/src/uncategorized/slaveStats.tw
index cc94b31fa09..d6f58b5b1d1 100644
--- a/src/uncategorized/slaveStats.tw
+++ b/src/uncategorized/slaveStats.tw
@@ -11,11 +11,6 @@ slaveName: $activeSlave.slaveName	   /* TODO: figure out why this is being inden
 <br>birthSurname: $activeSlave.birthSurname
 <br>genes: $activeSlave.genes
 <br>pronoun: $activeSlave.pronoun
-<br>possessive: $activeSlave.possessive
-<br>possessivePronoun: $activeSlave.possessivePronoun
-<br>objectReflexive: $activeSlave.objectReflexive
-<br>object: $activeSlave.object
-<br>noun: $activeSlave.noun
 <br>weekAcquired: $activeSlave.weekAcquired
 <br>origin: $activeSlave.origin
 <br>career: $activeSlave.career
@@ -213,7 +208,7 @@ slaveName: $activeSlave.slaveName	   /* TODO: figure out why this is being inden
 <br>nails: $activeSlave.nails
 <br>brand:
 <<for _brandName, _brand range $activeSlave.brand>>
-    _brandName: _brand, 
+    _brandName: _brand,
 <</for>>
 <br>earPiercing: $activeSlave.earPiercing
 <br>nosePiercing: $activeSlave.nosePiercing
-- 
GitLab