From d37d37d023130e15da1f4b2e14c98db2170f3a67 Mon Sep 17 00:00:00 2001
From: Svornost <11434-svornost@users.noreply.gitgud.io>
Date: Sun, 12 Jan 2020 18:28:21 -0800
Subject: [PATCH] Improve assignJob to do a bit more housekeeping, allow
 removeJob to be run on nobody, configure facilitySlaveList to automatically
 handle assignment, and set up AttendantSelect as a POC for facility leader
 selection without the Workaround passage.

---
 src/js/assignJS.js                      | 66 +++++++++++++++++++++++++
 src/js/slaveListing.js                  |  7 ++-
 src/npc/asDump.tw                       | 19 -------
 src/uncategorized/attendantSelect.tw    |  4 +-
 src/uncategorized/bgSelect.tw           |  4 +-
 src/uncategorized/nextWeek.tw           |  3 +-
 src/uncategorized/reHGReplacement.tw    |  3 --
 src/uncategorized/surgeryDegradation.tw | 29 ++---------
 8 files changed, 80 insertions(+), 55 deletions(-)

diff --git a/src/js/assignJS.js b/src/js/assignJS.js
index 0a6502f1662..428af35e86a 100644
--- a/src/js/assignJS.js
+++ b/src/js/assignJS.js
@@ -8,6 +8,14 @@ window.assignJob = function assignJob(slave, job) {
 	removeJob(slave, slave.assignment);
 	const idx = V.slaveIndices[slave.ID];
 
+	const uniqueJob = function(propName) {
+		// this helper makes sure global references ($HeadGirl, etc) are set correctly
+		if (V[propName] !== 0 && V[propName].ID !== slave.ID) {
+			removeJob(V[propName], job);
+		}
+		V[propName] = slave;
+	};
+
 	/* use .toLowerCase() to get rid of a few dupe conditions. */
 	switch (job.toLowerCase()) {
 		case "be confined in the arcade":
@@ -240,20 +248,67 @@ window.assignJob = function assignJob(slave, job) {
 			break;
 
 		case "be the attendant":
+			uniqueJob("Attendant");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the matron":
+			uniqueJob("Matron");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the dj":
+			uniqueJob("DJ");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the madam":
+			uniqueJob("Madam");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the milkmaid":
+			uniqueJob("Milkmaid");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the farmer":
+			uniqueJob("Farmer");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the nurse":
+			uniqueJob("Nurse");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the schoolteacher":
+			uniqueJob("Schoolteacher");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the stewardess":
+			uniqueJob("Stewardess");
+			slave.assignment = job;
+			slave.rules.living = "luxurious";
+			break;
+
 		case "be the wardeness":
+			uniqueJob("Wardeness");
 			slave.assignment = job;
 			slave.rules.living = "luxurious";
 			break;
 
 		case "be your concubine":
+			uniqueJob("Concubine");
 			slave.assignment = job;
 			if (V.masterSuiteUpgradeLuxury > 0) {
 				slave.rules.living = "luxurious";
@@ -263,13 +318,16 @@ window.assignJob = function assignJob(slave, job) {
 			break;
 
 		case "be your head girl":
+			uniqueJob("HeadGirl");
 			slave.assignment = job;
 			if (V.HGSuite === 1) {
 				slave.rules.living = "luxurious";
 			}
+			V.HGTimeInGrade = 0;
 			break;
 
 		case "guard you":
+			uniqueJob("Bodyguard");
 			slave.assignment = job;
 			if (V.dojo > 1) {
 				slave.rules.living = "luxurious";
@@ -326,6 +384,13 @@ window.removeJob = function removeJob(slave, assignment) {
 	"use strict";
 	let r = "";
 
+	if (slave === 0) {
+		// it is well-formed, but does nothing, to remove an assignment from nobody.
+		// this lets us call <<run removeJob($HeadGirl, "be your Head Girl")>> and similar,
+		// without first checking to see whether a slave is really assigned to $HeadGirl or not.
+		return r;
+	}
+
 	const idx = V.slaveIndices[slave.ID];
 
 	if (assignment === "Pit") {
@@ -484,6 +549,7 @@ window.removeJob = function removeJob(slave, assignment) {
 
 					r += `You no longer have a slave assigned to be your Head Girl, so you turn your personal attention to focus on ${V.personalAttention}.`;
 				}
+				V.HGTimeInGrade = 0;
 				break;
 
 			case "be your agent":
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index 455da6979e7..9ab9e6ea1d4 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -1180,13 +1180,12 @@ App.UI.SlaveList.slaveSelectionList = function() {
 
 /**
  * @param {App.Entity.Facilities.Facility} facility
- * @param {string} [passage] one of the *Workaround passages. Will be composed from the position name if omitted
+ * @param {string} passage go here after the new facility manager is selected
  * @returns {string}
  */
 App.UI.SlaveList.facilityManagerSelection = function(facility, passage) {
-	passage = passage || capFirstChar(facility.manager.desc.position) + " Workaround";
 	return this.slaveSelectionList(slave => facility.manager.canEmploy(slave),
-		(slave, index) => App.UI.DOM.passageLink(SlaveFullName(slave), passage,
-			() => { variables().i = index; }),
+		(slave) => App.UI.DOM.passageLink(SlaveFullName(slave), passage,
+			() => { assignJob(slave, facility.manager.desc.assignment); }),
 		slave => facility.manager.slaveHasExperience(slave));
 };
diff --git a/src/npc/asDump.tw b/src/npc/asDump.tw
index 3e0c69edeb9..d30230405a7 100644
--- a/src/npc/asDump.tw
+++ b/src/npc/asDump.tw
@@ -23,25 +23,6 @@
 		<</if>>
 	<</if>>
 
-	<<switch _ID>>
-		<<case $HeadGirl.ID>><<set $HeadGirl = $activeSlave>>
-		<<case $Recruiter.ID>><<set $Recruiter = $activeSlave>>
-		<<case $Bodyguard.ID>><<set $Bodyguard = $activeSlave>>
-		<<case $Madam.ID>><<set $Madam = $activeSlave>>
-		<<case $DJ.ID>><<set $DJ = $activeSlave>>
-		<<case $Milkmaid.ID>><<set $Milkmaid = $activeSlave>>
-		<<case $Farmer.ID>><<set $Farmer = $activeSlave>>
-		<<case $Schoolteacher.ID>><<set $Schoolteacher = $activeSlave>>
-		<<case $Attendant.ID>><<set $Attendant = $activeSlave>>
-		<<case $Matron.ID>><<set $Matron = $activeSlave>>
-		<<case $Nurse.ID>><<set $Nurse = $activeSlave>>
-		<<case $Stewardess.ID>><<set $Stewardess = $activeSlave>>
-		<<case $Wardeness.ID>><<set $Wardeness = $activeSlave>>
-		<<case $Concubine.ID>><<set $Concubine = $activeSlave>>
-		<<case $Collectrix.ID>><<set $Collectrix = $activeSlave>>
-		<<case $Matron.ID>><<set $Matron = $activeSlave>>
-	<</switch>>
-
 	<<run clearSummaryCache($activeSlave)>>
 
 	<</silently>>
diff --git a/src/uncategorized/attendantSelect.tw b/src/uncategorized/attendantSelect.tw
index e9c6661f612..f9c31d5fdd1 100644
--- a/src/uncategorized/attendantSelect.tw
+++ b/src/uncategorized/attendantSelect.tw
@@ -10,6 +10,6 @@
 <</if>>
 
 <br><br>''Appoint an Attendant from your devoted slaves:''
-<br><br>[[None|Attendant Workaround][$i = -1]]
+<br><br>[[None|Spa][removeJob($Attendant, "be the Attendant")]]
 <br><br>
-<<print App.UI.SlaveList.facilityManagerSelection(App.Entity.facilities.spa)>>
+<<print App.UI.SlaveList.facilityManagerSelection(App.Entity.facilities.spa, "Spa")>>
diff --git a/src/uncategorized/bgSelect.tw b/src/uncategorized/bgSelect.tw
index b132f2ba294..b705ac6c4b0 100644
--- a/src/uncategorized/bgSelect.tw
+++ b/src/uncategorized/bgSelect.tw
@@ -17,6 +17,6 @@
 <</if>>
 
 <br><br>''Appoint a bodyguard from your devoted slaves:''
-<br><br>[[None|Bodyguard Workaround][$i = -1]]
+<br><br>[[None|Main][removeJob($Bodyguard, "guard you")]]
 <br><br>
-<<print App.UI.SlaveList.facilityManagerSelection(App.Entity.facilities.armory, "Bodyguard Workaround")>>
+<<print App.UI.SlaveList.facilityManagerSelection(App.Entity.facilities.armory, "Main")>>
diff --git a/src/uncategorized/nextWeek.tw b/src/uncategorized/nextWeek.tw
index b06cd839999..3de6a6fbc77 100644
--- a/src/uncategorized/nextWeek.tw
+++ b/src/uncategorized/nextWeek.tw
@@ -278,10 +278,11 @@
 <<set $enduringDevotion = ($averageDevotion+($enduringDevotion*3))/4>>
 
 <<if (_OldHG != -1) && (_NewHG != -1)>>
+	<<set _oldTimeInGrade = $HGTimeInGrade>> /* preserve time in grade during HG swaps */
 	<<= removeJob($slaves[_NewHG], "live with your Head Girl")>>
 	<<= assignJob($slaves[_OldHG], "live with your Head Girl")>>
 	<<= assignJob($slaves[_NewHG], "be your Head Girl")>>
-	<<set $HeadGirl = $slaves[_NewHG], $slaves[_NewHG].diet = "healthy">>
+	<<set $slaves[_NewHG].diet = "healthy", $HGTimeInGrade = _oldTimeInGrade>>
 <</if>>
 
 <<if WombBirthReady($PC, 38) > 0 && random(1,100) > 50>>
diff --git a/src/uncategorized/reHGReplacement.tw b/src/uncategorized/reHGReplacement.tw
index fbd61ef18ac..b7c4efd7639 100644
--- a/src/uncategorized/reHGReplacement.tw
+++ b/src/uncategorized/reHGReplacement.tw
@@ -44,11 +44,8 @@ When $HeadGirl.slaveName leaves, $he clears $his throat nervously. $He gathers $
 		<<EventNameDelink $activeSlave>>
 		<<replace "#result">>
 			After giving the matter some consideration, you agree, instructing $assistantName that $activeSlave.slaveName is now the Head Girl. $activeSlave.slaveName is @@.hotpink;overjoyed,@@ and bounces to $his feet, clearly very eager to begin. You caution $him that $he is not to undermine $HeadGirl.slaveName by letting anyone know why you decided to change Head Girls. $He nods obediently. As far as $HeadGirl.slaveName knows, it's just a standard change of Head Girls, and _he2's too good a slave to let it affect _him2 seriously.
-			<<set $i = $slaveIndices[$HeadGirl.ID]>>
-			<<= assignJob($slaves[$i], "rest")>>
 			<<set $activeSlave.devotion += 5>>
 			<<= assignJob($activeSlave, "be your Head Girl")>>
-			<<set $HeadGirl = $activeSlave>>
 		<</replace>>
 	<</link>>
 	<br><<link "Pretend you didn't hear $him">>
diff --git a/src/uncategorized/surgeryDegradation.tw b/src/uncategorized/surgeryDegradation.tw
index 2fa63b12bf8..d25bf416674 100644
--- a/src/uncategorized/surgeryDegradation.tw
+++ b/src/uncategorized/surgeryDegradation.tw
@@ -106,30 +106,11 @@
 <<else>>
 	<<switch $surgeryType>>
 	<<case "amp" "amp1" "ampA2" "ampL2" "blind" "fuckdoll" "mindbreak" "PLimb interface1" "PLimb interface2" "PLimb interface3" "remove eyes" "removeLimbs">>
-	<<set _ID = $activeSlave.ID>>
-	<<if _ID == $Lurcher.ID>><<set $Lurcher = 0>><</if>>
-	<<if _ID == $Recruiter.ID>><<set $Recruiter = 0>><</if>>
-	<<if _ID == $HeadGirl.ID>><<set $HeadGirl = 0>><</if>>
-	<<if _ID == $Bodyguard.ID>><<set $Bodyguard = 0>><</if>>
-	/% These break as you can't select or deselect a boss till the following week. %/
-	<<if _ID == $Madam.ID>><<set $Madam = 0>><</if>>
-	<<if _ID == $DJ.ID>><<set $DJ = 0>><</if>>
-	<<if _ID == $Milkmaid.ID>><<set $Milkmaid = 0>><</if>>
-	<<if _ID == $Farmer.ID>><<set $Farmer = 0>><</if>>
-	<<if _ID == $Schoolteacher.ID>><<set $Schoolteacher = 0>><</if>>
-	<<if _ID == $Attendant.ID>><<set $Attendant = 0>><</if>>
-	<<if _ID == $Matron.ID>><<set $Matron = 0>><</if>>
-	<<if _ID == $Nurse.ID>><<set $Nurse = 0>><</if>>
-	<<if _ID == $Stewardess.ID>><<set $Stewardess = 0>><</if>>
-	<<if _ID == $Wardeness.ID>><<set $Wardeness = 0>><</if>>
-	<<if _ID == $Concubine.ID>><<set $Concubine = 0>><</if>>
-	<<for _y = 0; _y < $fighterIDs.length; _y++>>
-		<<if _ID == $fighterIDs[_y]>>
-			<<run $fighterIDs.deleteAt(_y), _y-->>
-		<</if>>
-	<</for>>
-	/% Remove from facility array if assigned. %/
-	<<= removeJob($activeSlave, $activeSlave.assignment)>>
+		/* unassign if necessary */
+		<<set _ID = $activeSlave.ID>>
+		<<if _ID == $Lurcher.ID>><<set $Lurcher = 0>><</if>>
+		<<run $fighterIDs.deleteWith((f) => f === _ID)>>
+		<<= removeJob($activeSlave, $activeSlave.assignment)>>
 	<</switch>>
 
 As the remote surgery's long recovery cycle completes,
-- 
GitLab