From 48d65e755504756c792c8a8471abe077afa5f76d Mon Sep 17 00:00:00 2001
From: Vasileios Pasialiokis <whiterocket@outlook.com>
Date: Wed, 28 Mar 2018 21:01:28 +0300
Subject: [PATCH] begin work

---
 src/js/SetBellySize.js       |  22 ++
 src/js/assayJS.tw            |  10 +
 src/js/assignJS.js           | 440 +++++++++++++++++++++++++++++++++++
 src/js/rulesAssistant.js     | 135 +++++++++++
 src/utility/assignWidgets.tw | 229 +-----------------
 src/utility/miscWidgets.tw   |  21 +-
 src/utility/raWidgets.tw     |  53 +----
 7 files changed, 614 insertions(+), 296 deletions(-)
 create mode 100644 src/js/SetBellySize.js
 create mode 100644 src/js/assignJS.js
 create mode 100644 src/js/rulesAssistant.js

diff --git a/src/js/SetBellySize.js b/src/js/SetBellySize.js
new file mode 100644
index 00000000000..ce50faf43da
--- /dev/null
+++ b/src/js/SetBellySize.js
@@ -0,0 +1,22 @@
+:: SetBellySize [script]
+
+window.SetBellySize = function SetBellySize(slave) {
+	let _implantSize
+	WombNormalizePreg(slave) /*now with support for legacy code that advance pregnancy by setting .preg++ */ 
+
+	if (slave.bellyImplant > 0)
+		_implantSize = slave.bellyImplant
+	else
+		_implantSize = 0
+		
+	if (slave.inflation == 3)	
+		slave.bellyFluid = 10000
+	else if (slave.inflation == 2)
+		slave.bellyFluid = 5000
+	else if (slave.inflation == 1)
+		slave.bellyFluid = 2000
+	else
+		slave.bellyFluid = 0
+	
+	slave.belly = slave.bellyPreg+slave.bellyFluid+_implantSize
+}
diff --git a/src/js/assayJS.tw b/src/js/assayJS.tw
index 3aa63c5df81..ea7b8e6c484 100644
--- a/src/js/assayJS.tw
+++ b/src/js/assayJS.tw
@@ -214,3 +214,13 @@ window.supremeRaceP = function supremeRaceP(slave) {
 window.inferiorRaceP = function inferiorRaceP(slave) {
 	return SugarCube.State.variables.arcologies[0].FSSubjugationistRace === slave.race
 }
+
+window.isLeaderP = function isLeaderP(slave) {
+	const V = State.variables;
+	const leaders = [V.HeadGirl, V.Bodyguard, V.Recruiter, V.Concubine, V.Nurse, V.Attendant, V.Madam, V.DJ, V.Milkmaid, V.Stewardess, V.Schoolteacher, V.Wardeness];
+	for (let i = 0; i < leaders.length; i++) {
+		if (leaders[i].ID && leaders[i].ID === slave.ID)
+			return true
+	}
+	return false
+};
diff --git a/src/js/assignJS.js b/src/js/assignJS.js
new file mode 100644
index 00000000000..36e30da1562
--- /dev/null
+++ b/src/js/assignJS.js
@@ -0,0 +1,440 @@
+:: assignJob [script]
+
+window.assignJob = function assignJob(slave, job) {
+	const V = State.variables
+	let r = ""
+
+	if (job === "Pit" || job === "Coursing Association")
+		return r
+	
+	removeJob(slave, slave.assignment)
+	const idx = V.slaves.findIndex(s => s.ID === slave.ID)
+
+	/* use .toLowerCase() to get rid of a few dupe conditions. */
+	switch (job.toLowerCase()) {
+		case "be confined in the arcade":
+		case "arcade":
+			slave.assignment = "be confined in the arcade"
+			slave.assignmentVisible = 0
+			V.arcadeSlaves++
+			V.ArcadeiIDs.push(slave.ID)
+			slave.clothing = "none"
+			slave.shoes = "none"
+			slave.collar = "none"
+			slave.livingRules = "spare"
+			break
+
+		case "work in the brothel":
+		case "brothel":
+			slave.assignment = "work in the brothel"
+			slave.assignmentVisible = 0
+			V.brothelSlaves++
+			V.BrothiIDs.push(slave.ID)
+			switch (V.brothelDecoration) {
+				case "Degradationist":
+				case "standard":
+					slave.livingRules = "spare"
+					break
+				default:
+					slave.livingRules = "normal"
+					break
+			}
+			break
+
+		case "be confined in the cellblock":
+		case "cellblock":
+			slave.assignment = "be confined in the cellblock"
+			slave.assignmentVisible = 0
+			V.cellblockSlaves++
+			V.CellBiIDs.push(slave.ID)
+			switch (V.cellblockDecoration) {
+				case "Paternalist":
+					slave.livingRules = "normal"
+					break
+				default:
+					slave.livingRules = "spare"
+					break
+			}
+			break
+
+		case "get treatment in the clinic":
+		case "clinic":
+			slave.assignment = "get treatment in the clinic"
+			slave.assignmentVisible = 0
+			V.clinicSlaves++
+			V.CliniciIDs.push(slave.ID)
+			switch (V.clinicDecoration) {
+				case "Repopulation Focus":
+				case "Eugenics":
+				case "Gender Radicalist":
+				case "Gender Fundamentalist":
+				case "Paternalist":
+				case "Maturity Preferentialist":
+				case "Youth Preferentialist":
+				case "Slimness Enthusiast":
+				case "Hedonistic":
+					slave.livingRules = "luxurious"
+					break
+				
+				case "Roman Revivalist":
+				case "Aztec Revivalist":
+				case "Egyptian Revivalist":
+				case "Arabian Revivalist":
+				case "Chinese Revivalist":
+				case "Chattel Religionist":
+				case "Edo Revivalist":
+					slave.livingRules = "normal"
+					break
+				
+				default:
+					slave.livingRules = "spare"
+					break
+			}
+			break
+
+		case "serve in the club":
+		case "club":
+			slave.assignment = "serve in the club"
+			slave.assignmentVisible = 0
+			V.clubSlaves++
+			V.ClubiIDs.push(slave.ID)
+			slave.livingRules = "normal"
+			break
+
+		case "work in the dairy":
+		case "dairy":
+			slave.assignment = "work in the dairy"
+			slave.assignmentVisible = 0
+			V.dairySlaves++
+			V.DairyiIDs.push(slave.ID)
+			switch (V.dairyDecoration) {
+				case "Roman Revivalist":
+				case "Aztec Revivalist":
+				case "Chinese Revivalist":
+				case "Chattel Religionist":
+				case "Edo Revivalist":
+				case "Arabian Revivalist":
+				case "Egyptian Revivalist":
+				case "Supremacist":
+				case "Subjugationist":
+				case "Degradationist":
+					slave.livingRules = "spare"
+					break
+				default:
+					slave.livingRules = "normal"
+					break
+			}
+			break
+
+		case "live with your head girl":
+		case "head girl suite":
+		case "hgsuite":
+			slave.assignment = "live with your Head Girl"
+			slave.assignmentVisible = 0
+			V.HGSuiteSlaves++
+			V.HGSuiteiIDs.push(slave.ID)
+			slave.livingRules = "luxurious"
+			break
+
+		case "serve in the master suite":
+		case "master suite":
+		case "mastersuite":
+			slave.assignment = "serve in the master suite"
+			slave.assignmentVisible = 0
+			V.masterSuiteSlaves++
+			V.MastSiIDs.push(slave.ID)
+			break
+
+		case "learn in the schoolroom":
+		case "schoolroom":
+			slave.assignment = "learn in the schoolroom"
+			slave.assignmentVisible = 0
+			V.schoolroomSlaves++
+			V.SchlRiIDs.push(slave.ID)
+			slave.livingRules = "normal"
+			break
+
+		case "work as a servant":
+		case "servants' quarters":
+		case "servantsquarters":
+			slave.assignment = "work as a servant"
+			slave.assignmentVisible = 0
+			V.servantsQuartersSlaves++
+			V.ServQiIDs.push(slave.ID)
+			switch (V.servantsQuartersDecoration) {
+				case "Roman Revivalist":
+				case "Aztec Revivalist":
+				case "Chinese Revivalist":
+				case "Chattel Religionist":
+				case "Edo Revivalist":
+				case "Supremacist":
+				case "Subjugationist":
+				case "Degradationist":
+				case "Arabian Revivalist":
+				case "Egyptian Revivalist":
+					slave.livingRules = "spare"
+					break
+				default:
+					slave.livingRules = "normal"
+					break
+			}
+			break
+
+		case "rest in the spa":
+		case "spa":
+			slave.assignment = "rest in the spa"
+			slave.assignmentVisible = 0
+			V.spaSlaves++
+			V.SpaiIDs.push(slave.ID)
+			switch (V.spaDecoration) {
+				case "Chattel Religionist":
+				case "Chinese Revivalist":
+					slave.livingRules = "normal"
+					break
+				case "Degradationist":
+					slave.livingRules = "spare"
+					break
+				default:
+					slave.livingRules = "luxurious"
+					break
+			}
+			break
+
+		case "be the attendant":
+		case "be your concubine":
+		case "be the dj":
+		case "be the madam":
+		case "be the milkmaid":
+		case "be the nurse":
+		case "be the schoolteacher":
+		case "be the stewardess":
+		case "be the wardeness":
+			slave.assignment = job
+			slave.assignmentVisible = 0     /* non-visible leadership roles */
+			slave.livingRules = "luxurious"
+			break
+
+		case "be your head girl":
+			slave.assignment = job
+			if (V.HGSuite === 1) {
+				slave.livingRules = "luxurious"
+			}
+			break
+
+		case "guard you":
+			slave.assignment = job
+			if (V.dojo > 1) {
+				slave.livingRules = "luxurious"
+			}
+			break
+
+		case "be your agent":
+		case "live with your agent":
+			slave.assignment = job
+			slave.assignmentVisible = 0
+			slave.useRulesAssistant = 0 /* non-visible roles exempt from Rules Assistant */
+			if (job === "be your agent") {
+				V.leaders.push(slave)
+			}
+			break
+
+		case "choose her own job":
+			slave.assignment = job
+			slave.choosesOwnAssignment = 1  /* removeJob already set assignmentVisible = 1 */
+			break
+
+		default:
+			slave.assignment = job /* removeJob already set assignmentVisible = 1 and choosesOwnAssignment = 0 */
+			break
+	}
+
+	if (slave.assignmentVisible === 0 && Array.isArray(V.personalAttention)) {
+		const awi = V.personalAttention.findIndex(function(s) { return s.ID === slave.ID; })
+		if (awi != -1) {
+			V.personalAttention.deleteAt(awi)
+			if (V.personalAttention.length === 0) {
+				if (V.PC.career === "escort") 
+					V.personalAttention = "whoring"
+				else if (V.PC.career === "servant")
+					V.personalAttention = "upkeep"
+				else
+					V.personalAttention = "business"
+				r += `${slave.slaveName} no longer has your personal attention; you plan to focus on ${V.personalAttention}.`
+			} else
+				r += `${slave.slaveName} no longer has your personal attention.`
+		}
+	}
+	return r
+}
+
+window.removeJob = function removeJob(slave, assignment) {
+	const V = State.variables
+	let r = ""
+	
+	const idx = V.slaves.findIndex(function(s) { return s.ID === slave.ID; })
+
+	if (assignment === "Pit")
+		V.fighterIDs.delete(slave.ID)
+
+	else if (assignment === "Coursing Association")
+		V.Lurcher = 0
+
+	else {
+		if (V.HeadGirl !== 0 && slave.ID === V.HeadGirl.ID)
+			V.HeadGirl = 0
+		if (V.Recruiter !== 0 && slave.ID == V.Recruiter.ID)
+			V.Recruiter = 0
+		if (V.Bodyguard !== 0 && slave.ID === V.Bodyguard.ID)
+			V.Bodyguard = 0
+		if (V.Madam !== 0 && slave.ID === V.Madam.ID)
+			V.Madam = 0
+		if (V.DJ !== 0 && slave.ID === V.DJ.ID)
+			V.DJ = 0
+		if (V.Milkmaid !== 0 && slave.ID === V.Milkmaid.ID)
+			V.Milkmaid = 0
+		if (V.Schoolteacher !== 0 && slave.ID === V.Schoolteacher.ID)
+			V.Schoolteacher = 0
+		if (V.Attendant !== 0 && slave.ID === V.Attendant.ID)
+			V.Attendant = 0
+		if (V.Nurse !== 0 && slave.ID === V.Nurse.ID)
+			V.Nurse = 0
+		if (V.Stewardess !== 0 && slave.ID === V.Stewardess.ID)
+			V.Stewardess = 0
+		if (V.Wardeness !== 0 && slave.ID === V.Wardeness.ID)
+			V.Wardeness = 0
+		if (V.Concubine !== 0 && slave.ID === V.Concubine.ID)
+			V.Concubine = 0
+		if (V.Collectrix !== 0 && slave.ID === V.Collectrix.ID)
+			V.Collectrix = 0
+
+		/* use .toLowerCase() to get rid of a few dupe conditions. */
+		switch (assignment.toLowerCase()) {
+		case "be confined in the arcade":
+		case "arcade":
+			slave.assignment = "work a glory hole"
+			V.ArcadeiIDs.delete(slave.ID)
+			V.arcadeSlaves--
+			break
+
+		case "work in the brothel":
+		case "brothel":
+			slave.assignment = "whore"
+			V.BrothiIDs.delete(slave.ID)
+			V.brothelSlaves--
+			break
+
+		case "be confined in the cellblock":
+		case "cellblock":
+			slave.assignment = "rest"
+			if ((V.slaves[idx].inflation > 0)) {
+				slave.inflation = 0
+				slave.inflationType = "none"
+				slave.inflationMethod = 0
+				SetBellySize(slave)
+			}
+			V.CellBiIDs.delete(slave.ID)
+			V.cellblockSlaves--
+			break
+
+		case "get treatment in the clinic":
+		case "clinic":
+			slave.assignment = "rest"
+			V.CliniciIDs.delete(slave.ID)
+			V.clinicSlaves--
+			break
+
+		case "serve in the club":
+		case "club":
+			slave.assignment = "serve the public"
+			V.ClubiIDs.delete(slave.ID)
+			V.clubSlaves--
+			break
+
+		case "work in the dairy":
+		case "dairy":
+			slave.assignment = "get milked"
+			V.DairyiIDs.delete(slave.ID)
+			V.dairySlaves--
+			break
+
+		case "learn in the schoolroom":
+		case "schoolroom":
+			slave.assignment = "rest"
+			V.SchlRiIDs.delete(slave.ID)
+			V.schoolroomSlaves--
+			break
+
+		case "rest in the spa":
+		case "spa":
+			slave.assignment = "rest"
+			V.SpaiIDs.delete(slave.ID)
+			V.spaSlaves--
+			break
+
+		case "work as a servant":
+		case "servants' quarters":
+		case "servantsquarters":
+			slave.assignment = "be a servant"
+			V.ServQiIDs.delete(slave.ID)
+			V.servantsQuartersSlaves--
+			break
+
+		case "serve in the master suite":
+		case "master suite":
+		case "mastersuite":
+			slave.assignment = "please you"
+			V.MastSiIDs.delete(slave.ID)
+			V.masterSuiteSlaves--
+			break
+
+		case "live with your head girl":
+		case "head girl suite":
+		case "hgsuite":
+			slave.assignment = "rest"
+			V.HGSuiteiIDs.delete(slave.ID)
+			V.HGSuiteSlaves--
+			break
+
+		case "be your head girl":
+			slave.assignment = "rest"
+			if (V.HGSuiteEquality === 0 && V.personalAttention === "HG") {
+				if (V.PC.career === "escort")
+					V.personalAttention = "whoring"
+				else if (V.PC.career === "servant")
+					V.personalAttention = "upkeep"
+				else
+					V.personalAttention = "business"
+				
+				r += `You no longer have a slave assigned to be your Head Girl, so you turn your personal attention to focus on ${V.personalAttention}.`
+			}
+			break
+			
+		case "be your agent":
+		case "live with your agent":
+			slave.assignment = "rest"
+			const _leaderIndex = V.leaders.findIndex(function(x) { return x.ID === slave.ID })
+			if (_leaderIndex !== -1)
+				V.leaders.deleteAt(_leaderIndex)
+			
+			if (slave.relationshipTarget > 0) { /* following code assumes there can be at most one companion */
+				const _lover = V.slaves.findIndex(function(s) { return haveRelationshipP(s, slave) && s.assignment === "live with your agent"; })
+				if (_lover !== -1) {
+					V.slaves[_lover].assignment = "rest"
+					V.slaves[_lover].assignmentVisible = 1
+				}
+			}
+			break
+			
+		default:
+			slave.assignment = "rest"
+			break
+		}
+
+		slave.assignmentVisible = 1
+		slave.choosesOwnAssignment = 0
+		slave.sentence = 0
+		if (slave.livingRules === "luxurious")
+			slave.livingRules = "normal"
+	}
+	return r
+}
diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js
new file mode 100644
index 00000000000..a3137dc5d82
--- /dev/null
+++ b/src/js/rulesAssistant.js
@@ -0,0 +1,135 @@
+:: rulesAssistant [script]
+
+// a collection of functions for rules assistant
+
+window.CheckAutoRulesActivate = function CheckAutoRulesActivate(slave) {
+	const V = State.variables
+	let r = ""
+
+	if (slave.currentRules === undefined || slave.currentRules.length < 1)
+		slave.currentRules = []
+
+
+	V.defaultRules.forEach(rule => {
+		let applies = evalExpr(rule.condition, slave)
+		if (applies && rule.excludeSpecialSlaves && isLeaderP(slave)) // TODO: exclusions/inclusions in rule condition
+			applies = false
+		if (applies) {
+			if (rule.assignment.length > 0 || rule.facility.length > 0)
+				applies = ruleAssignmentSelected(slave, rule)
+			else if (rule.excludeAssignment.length > 0 || rule.excludeFacility.length > 0)
+				applies = !ruleAssignmentExcluded(slave, rule)
+			if (rule.selectedSlaves.length > 0)
+				applies = ruleSlaveSelected(slave, rule)
+			else if (rule.excludedSlaves.length > 0)
+				applies = !ruleSlaveExcluded(slave, rule)
+		}
+		if (applies) {
+			if (!ruleApplied(slave, rule.ID)) {
+				slave.currentRules.push(rule.ID)
+				r += `<br><span class="tan">Rule ${rule.ID} (${rule.name}) now applies to ${slave.slaveName}, who is assigned to ${slave.assignment}</span>\n`
+			}
+		} else if (ruleApplied(slave, rule.ID)) {
+			r += RARemoveRule(slave, rule)
+		}
+	})
+	return r
+}
+
+window.RARemoveRule = function RARemoveRule(slave, rule) {
+	let r = ""
+	const idx = slave.currentRules.indexOf(
+	slave.currentRules.some((rule, i) => {
+		if (rule.ID === rule) {
+			slave.currentRules.splice(i, 1)
+			r += `<br><span class="tan">Rule ${rule.ID} (${rule.name}) no longer applies to {slave.slaveName}, who is assignmed to ${slave.assignment}</span>`
+			r += RAFacilityRemove(slave, rule)
+			return true
+		} else return false
+	})
+	return r
+}
+
+window.RAFacilityRemove = function RAFacilityRemove(slave, rule) {
+	const V = State.variables
+	let r = ""
+	if (!rule.facilityRemove) return r
+	switch(rule.setAssignment) {
+	case "be confined in the arcade":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.arcadeName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "work in the brothel":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.brothelName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "serve in the club":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${clubName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "work in the dairy":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.dairyName} and has been assigned to $rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "rest in the spa":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.spaName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "get treatment in the clinic":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>{slave.slaveName} has been removed from ${V.clinicName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "serve in the master suite":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>{slave.slaveName} has been removed from ${V.masterSuiteName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "live with your Head Girl":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${HGSuiteName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "work as a servant":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.servantsQuartersName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "learn in the schoolroom":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.schoolroomName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+
+	case "be confined in the cellblock":
+		if (slave.assignment === rule.setAssignment) {
+			r += `<br>${slave.slaveName} has been removed from ${V.cellblockName} and has been assigned to ${rule.removalAssignment}.`
+			assignJob(slave, rule.removalAssignment)
+		}
+		break;
+	}
+}
diff --git a/src/utility/assignWidgets.tw b/src/utility/assignWidgets.tw
index 909d7578c39..68339781768 100644
--- a/src/utility/assignWidgets.tw
+++ b/src/utility/assignWidgets.tw
@@ -1,133 +1,15 @@
 :: Assign Widgets [widget nobr]
 
-/%
+/*
 	Call as <<assignJob slaveObject $returnTo | _currentRule.facilityRemove | "serve in the master suite"
 	$args[0] slave object. *MUST be present*
 	$args[1] Job to assign slave to. Will accept the $returnTo vars and the _currentRule.assignFacility vars and the actual job assignments "serve in the master suite" etc.
 
 	This is basically a Widget version of assign but will work anywhere, and saves to the slaves[..] array, and changes your $args[0] var sent.
-%/
-<<widget assignJob>>
-<<if ($args[1] != "Pit") && ($args[1] != "Coursing Association")>>
-
-	<<removeJob $args[0] $args[0].assignment>> /* sets _wID and _wi */
+*/
 
-	/% use .toLowerCase() to get rid of a few dupe conditions. %/
-	<<switch $args[1].toLowerCase()>>
-		<<case "be confined in the arcade" "arcade">>
-			<<set $args[0].assignment = "be confined in the arcade",    $args[0].assignmentVisible = 0, $arcadeSlaves++, $ArcadeiIDs.push(_wID)>>
-			<<set $args[0].clothing = "none", $args[0].shoes = "none", $args[0].collar = "none", $args[0].livingRules = "spare">>
-		<<case "work in the brothel" "brothel">>
-			<<set $args[0].assignment = "work in the brothel",          $args[0].assignmentVisible = 0, $brothelSlaves++, $BrothiIDs.push(_wID)>>
-			<<switch $brothelDecoration>>
-			<<case "Degradationist" "standard">>
-				<<set $args[0].livingRules = "spare">>
-			<<default>>
-				<<set $args[0].livingRules = "normal">>
-			<</switch>>
-		<<case "be confined in the cellblock" "cellblock">>
-			<<set $args[0].assignment = "be confined in the cellblock", $args[0].assignmentVisible = 0, $cellblockSlaves++, $CellBiIDs.push(_wID)>>
-			<<switch $cellblockDecoration>>
-			<<case "Paternalist">>
-				<<set $args[0].livingRules = "normal">>
-			<<default>>
-				<<set $args[0].livingRules = "spare">>
-			<</switch>>
-		<<case "get treatment in the clinic" "clinic">>
-			<<set $args[0].assignment = "get treatment in the clinic",  $args[0].assignmentVisible = 0, $clinicSlaves++, $CliniciIDs.push(_wID)>>
-			<<switch $clinicDecoration>>
-			<<case "Repopulation Focus" "Eugenics" "Gender Radicalist" "Gender Fundamentalist" "Paternalist" "Maturity Preferentialist" "Youth Preferentialist" "Slimness Enthusiast" "Hedonistic">>
-				<<set $args[0].livingRules = "luxurious">>
-			<<case "Roman Revivalist" "Aztec Revivalist" "Egyptian Revivalist" "Arabian Revivalist" "Chinese Revivalist" "Chattel Religionist" "Edo Revivalist">>
-				<<set $args[0].livingRules = "normal">>
-			<<default>>
-				<<set $args[0].livingRules = "spare">>
-			<</switch>>
-		<<case "serve in the club" "club">>
-			<<set $args[0].assignment = "serve in the club",            $args[0].assignmentVisible = 0, $clubSlaves++, $ClubiIDs.push(_wID)>>
-			<<set $args[0].livingRules = "normal">>
-		<<case "work in the dairy" "dairy">>
-			<<set $args[0].assignment = "work in the dairy",            $args[0].assignmentVisible = 0, $dairySlaves++, $DairyiIDs.push(_wID)>>
-			<<switch $dairyDecoration>>
-			<<case "Roman Revivalist" "Aztec Revivalist" "Chinese Revivalist" "Chattel Religionist" "Edo Revivalist" "Arabian Revivalist" "Egyptian Revivalist" "Supremacist" "Subjugationist" "Degradationist">>
-				<<set $args[0].livingRules = "spare">>
-			<<default>>
-				<<set $args[0].livingRules = "normal">>
-			<</switch>>
-		<<case "live with your head girl" "head girl suite" "hgsuite">>
-			<<set $args[0].assignment = "live with your Head Girl",     $args[0].assignmentVisible = 0, $HGSuiteSlaves++, $HGSuiteiIDs.push(_wID)>>
-			<<set $args[0].livingRules = "luxurious">>
-		<<case "serve in the master suite" "master suite" "mastersuite">>
-			<<set $args[0].assignment = "serve in the master suite",    $args[0].assignmentVisible = 0, $masterSuiteSlaves++, $MastSiIDs.push(_wID)>>
-		<<case "learn in the schoolroom" "schoolroom">>
-			<<set $args[0].assignment = "learn in the schoolroom",      $args[0].assignmentVisible = 0, $schoolroomSlaves++, $SchlRiIDs.push(_wID)>>
-			<<set $args[0].livingRules = "normal">>
-		<<case "work as a servant" "servants' quarters" "servantsquarters">>
-			<<set $args[0].assignment = "work as a servant",            $args[0].assignmentVisible = 0, $servantsQuartersSlaves++, $ServQiIDs.push(_wID)>>
-			<<switch $servantsQuartersDecoration>>
-			<<case "Roman Revivalist" "Aztec Revivalist" "Chinese Revivalist" "Chattel Religionist" "Edo Revivalist" "Supremacist" "Subjugationist" "Degradationist" "Arabian Revivalist" "Egyptian Revivalist">>
-				<<set $args[0].livingRules = "spare">>
-			<<default>>
-				<<set $args[0].livingRules = "normal">>
-			<</switch>>
-		<<case "rest in the spa" "spa">>
-			<<set $args[0].assignment = "rest in the spa",              $args[0].assignmentVisible = 0, $spaSlaves++, $SpaiIDs.push(_wID)>>
-			<<switch $spaDecoration>>
-			<<case "Chattel Religionist" "Chinese Revivalist">>
-				<<set $args[0].livingRules = "normal">>
-			<<case "Degradationist">>
-				<<set $args[0].livingRules = "spare">>
-			<<default>>
-				<<set $args[0].livingRules = "luxurious">>
-			<</switch>>
-		<<case "be the attendant" "be your concubine" "be the dj" "be the madam" "be the milkmaid" "be the nurse" "be the schoolteacher" "be the stewardess" "be the wardeness">>
-			<<set $args[0].assignment = $args[1],                       $args[0].assignmentVisible = 0>>     /* non-visible leadership roles */
-			<<set $args[0].livingRules = "luxurious">>
-		<<case "be your head girl">>
-			<<set $args[0].assignment = $args[1]>>
-			<<if $HGSuite == 1>>
-				<<set $args[0].livingRules = "luxurious">>
-			<</if>>
-		<<case "guard you">>
-			<<set $args[0].assignment = $args[1]>>
-			<<if $dojo > 1>>
-				<<set $args[0].livingRules = "luxurious">>
-			<</if>>
-		<<case "be your agent" "live with your agent">>
-			<<set $args[0].assignment = $args[1],                       $args[0].assignmentVisible = 0,      $args[0].useRulesAssistant = 0>> /* non-visible roles exempt from Rules Assistant */
-			<<if $args[1] == "be your agent">>
-				<<set $leaders.push($args[0])>>
-			<</if>>
-		<<case "choose her own job">>
-			<<set $args[0].assignment = $args[1],                       $args[0].choosesOwnAssignment = 1>>  /* removeJob already set assignmentVisible = 1 */
-		<<default>>
-			<<set $args[0].assignment = $args[1]>>                      /* removeJob already set assignmentVisible = 1 and choosesOwnAssignment = 0 */
-	<</switch>>
-
-	<<if $args[0].assignmentVisible == 0 && Array.isArray($personalAttention)>>
-		<<set _awi = $personalAttention.findIndex(function(s) { return s.ID == _wID; })>>
-		<<if _awi != -1>>
-			<<set $personalAttention.deleteAt(_awi)>>
-			<<if $personalAttention.length == 0>>
-				<<if $PC.career == "escort">>
-					<<set $personalAttention = "whoring">>
-				<<elseif $PC.career == "servant">>
-					<<set $personalAttention = "upkeep">>
-				<<else>>
-					<<set $personalAttention = "business">>
-				<</if>>
-				$args[0].slaveName no longer has your personal attention; you plan to focus on $personalAttention.
-			<<else>>
-				$args[0].slaveName no longer has your personal attention.
-			<</if>>
-		<</if>>
-	<</if>>
-
-	<<if _wi >= 0>>
-		<<set $slaves[_wi] = $args[0]>> /* save changes to slave array */
-	<</if>>
-
-<</if>> /* not Pit or Coursing Association */
+<<widget assignJob>>
+	<<= assignJob($args[0], $args[1]) >>
 <</widget>>
 
 /%
@@ -139,106 +21,5 @@
 	Retrieve overrides the 'rest' in most cases.
 %/
 <<widget removeJob>>
-<<set _wID = $args[0].ID>>
-<<set _wi = $slaves.findIndex(function(s) { return s.ID === _wID; })>>
-
-<<if ($args[1] == "Pit")>>
-	<<set $fighterIDs.delete(_wID)>>
-
-<<elseif ($args[1] == "Coursing Association")>>
-	<<set $Lurcher = 0>>
-
-<<else>>
-
-	<<if $HeadGirl != 0      && _wID == $HeadGirl.ID>><<set $HeadGirl = 0>><</if>>
-	<<if $Recruiter != 0     && _wID == $Recruiter.ID>><<set $Recruiter = 0>><</if>>
-	<<if $Bodyguard != 0     && _wID == $Bodyguard.ID>><<set $Bodyguard = 0>><</if>>
-	<<if $Madam != 0         && _wID == $Madam.ID>><<set $Madam = 0>><</if>>
-	<<if $DJ != 0            && _wID == $DJ.ID>><<set $DJ = 0>><</if>>
-	<<if $Milkmaid != 0      && _wID == $Milkmaid.ID>><<set $Milkmaid = 0>><</if>>
-	<<if $Schoolteacher != 0 && _wID == $Schoolteacher.ID>><<set $Schoolteacher = 0>><</if>>
-	<<if $Attendant != 0     && _wID == $Attendant.ID>><<set $Attendant = 0>><</if>>
-	<<if $Nurse != 0         && _wID == $Nurse.ID>><<set $Nurse = 0>><</if>>
-	<<if $Stewardess != 0    && _wID == $Stewardess.ID>><<set $Stewardess = 0>><</if>>
-	<<if $Wardeness != 0     && _wID == $Wardeness.ID>><<set $Wardeness = 0>><</if>>
-	<<if $Concubine != 0     && _wID == $Concubine.ID>><<set $Concubine = 0>><</if>>
-	<<if $Collectrix != 0    && _wID == $Collectrix.ID>><<set $Collectrix = 0>><</if>>
-
-	/% use .toLowerCase() to get rid of a few dupe conditions. %/
-	<<switch $args[1].toLowerCase()>>
-		<<case "be confined in the arcade" "arcade">>
-			<<set $args[0].assignment = "work a glory hole">>
-			<<set $ArcadeiIDs.delete(_wID), $arcadeSlaves-->>
-		<<case "work in the brothel" "brothel">>
-			<<set $args[0].assignment = "whore">>
-			<<set $BrothiIDs.delete(_wID), $brothelSlaves-->>
-		<<case "be confined in the cellblock" "cellblock">>
-			<<set $args[0].assignment = "rest">>
-			<<if ($slaves[_wi].inflation > 0)>>
-				<<set $args[0].inflation = 0, $args[0].inflationType = "none", $args[0].inflationMethod = 0>>
-				<<SetBellySize $slaves[$i]>>
-			<</if>>
-			<<set $CellBiIDs.delete(_wID), $cellblockSlaves-->>
-		<<case "get treatment in the clinic" "clinic">>
-			<<set $args[0].assignment = "rest">>
-			<<set $CliniciIDs.delete(_wID), $clinicSlaves-->>
-		<<case "serve in the club" "club">>
-			<<set $args[0].assignment = "serve the public">>
-			<<set $ClubiIDs.delete(_wID), $clubSlaves-->>
-		<<case "work in the dairy" "dairy">>
-			<<set $args[0].assignment = "get milked">>
-			<<set $DairyiIDs.delete(_wID), $dairySlaves-->>
-		<<case "learn in the schoolroom" "schoolroom">>
-			<<set $args[0].assignment = "rest">>
-			<<set $SchlRiIDs.delete(_wID), $schoolroomSlaves-->>
-		<<case "rest in the spa" "spa">>
-			<<set $args[0].assignment = "rest">>
-			<<set $SpaiIDs.delete(_wID), $spaSlaves-->>
-		<<case "work as a servant" "servants' quarters" "servantsquarters">>
-			<<set $args[0].assignment = "be a servant">>
-			<<set $ServQiIDs.delete(_wID), $servantsQuartersSlaves-->>
-		<<case "serve in the master suite" "master suite" "mastersuite">>
-			<<set $args[0].assignment = "please you">>
-			<<set $MastSiIDs.delete(_wID), $masterSuiteSlaves-->>
-		<<case "live with your head girl" "head girl suite" "hgsuite">>
-			<<set $args[0].assignment = "rest">>
-			<<set $HGSuiteiIDs.delete(_wID), $HGSuiteSlaves-->>
-		<<case "be your head girl">>
-			<<set $args[0].assignment = "rest">>
-			<<if $HGSuiteEquality == 0 && $personalAttention == "HG">>
-				<<if $PC.career == "escort">>
-					<<set $personalAttention = "whoring">>
-				<<elseif $PC.career == "servant">>
-					<<set $personalAttention = "upkeep">>
-				<<else>>
-					<<set $personalAttention = "business">>
-				<</if>>
-				You no longer have a slave assigned to be your Head Girl, so you turn your personal attention to focus on $personalAttention.
-			<</if>>
-		<<case "be your agent" "live with your agent">>
-			<<set $args[0].assignment = "rest">>
-			<<set _leaderIndex = $leaders.findIndex(function(x) { return x.ID == $args[0].ID })>>
-			<<if _leaderIndex != -1>>
-				<<set $leaders.deleteAt(_leaderIndex)>>
-			<</if>>
-			<<if $args[0].relationshipTarget > 0>> /* following code assumes there can be at most one companion */
-				<<set _lover = $slaves.findIndex(function(s) { return s.relationshipTarget == $args[0].ID && s.assignment == "live with your agent"; })>>
-				<<if _lover != -1>>
-					<<set $slaves[_lover].assignment = "rest", $slaves[_lover].assignmentVisible = 1>>
-				<</if>>
-			<</if>>
-		<<default>>
-			<<set $args[0].assignment = "rest">>
-	<</switch>>
-
-	<<set $args[0].assignmentVisible = 1, $args[0].choosesOwnAssignment = 0, $args[0].sentence = 0>>
-	<<if $args[0].livingRules == "luxurious">>
-		<<set $args[0].livingRules = "normal">>
-	<</if>>
-
-	<<if _wi >= 0>>
-		<<set $slaves[_wi] = $args[0]>> /* save changes to slave array */
-	<</if>>
-
-<</if>> /* not Pit or Coursing Association */
+	<<= removeJob($args[0], $args[1]) >>
 <</widget>>
diff --git a/src/utility/miscWidgets.tw b/src/utility/miscWidgets.tw
index e40d07d090d..dc8b81daf57 100644
--- a/src/utility/miscWidgets.tw
+++ b/src/utility/miscWidgets.tw
@@ -2504,26 +2504,7 @@ This experience
 
 	This block now relpaced with universal code
 */
-	<<set WombNormalizePreg($args[0])>> /*now with support for legacy code that advance pregnancy by setting .preg++ */ 
-
-	<<if $args[0].bellyImplant > 0>>
-		<<set _implantSize = $args[0].bellyImplant>>
-	<<else>>
-		<<set _implantSize = 0>>
-	<</if>>
-		
-	<<if $args[0].inflation == 3>>	
-		<<set $args[0].bellyFluid = 10000>>
-	<<elseif $args[0].inflation == 2>>
-		<<set $args[0].bellyFluid = 5000>>
-	<<elseif $args[0].inflation == 1>>
-		<<set $args[0].bellyFluid = 2000>>
-	<<else>>
-		<<set $args[0].bellyFluid = 0>>
-	<</if>>
-	
-	<<set $args[0].belly = $args[0].bellyPreg+$args[0].bellyFluid+_implantSize>>
-
+	<<set SetBellySize($args[0])>>
 <</widget>>
 
 /* see how they are on a single line? This permits "."s and other things to be appended directly onto the widget result */
diff --git a/src/utility/raWidgets.tw b/src/utility/raWidgets.tw
index ab3a63ecf43..06095d3ceef 100644
--- a/src/utility/raWidgets.tw
+++ b/src/utility/raWidgets.tw
@@ -4916,58 +4916,7 @@ is now _combinedRule.hLength cm long.
  % Does not use or modify $currentRule
  %/
 <<widget "CheckAutoRulesActivate">>
-	<<if (ndef $args[0].currentRules) || ($args[0].currentRules.length < 1)>>
-		<<set $args[0].currentRules = []>>
-	<</if>>
-
-	<<set _leaders = [$HeadGirl, $Bodyguard, $Recruiter, $Concubine, $Nurse, $Attendant, $Madam, $DJ, $Milkmaid, $Stewardess, $Schoolteacher, $Wardeness]>>
-
-	<<for _r = 0; _r < $defaultRules.length; _r++>>
-		<<set _currentRule = $defaultRules[_r], _rule = _r+1>>
-
-		<<set _ruleAppliesToThisSlave = evalExpr(_currentRule.condition, $args[0])>>
-
-		<<if _ruleAppliesToThisSlave && _currentRule.excludeSpecialSlaves>>
-			<<for _L = 0; _L < _leaders.length; _L++>>
-		<<if (def _leaders[_L].ID && _leaders[_L].ID == $args[0].ID)>>
-					<<set _ruleAppliesToThisSlave = false>>
-					<<break>>
-				<</if>>
-			<</for>>
-		<</if>>
-
-		/% check exclusion/inclusion %/
-		<<if _ruleAppliesToThisSlave>>
-	    <<if (_currentRule.assignment.length > 0 || _currentRule.facility.length > 0)>>
-		<<set _ruleAppliesToThisSlave = ruleAssignmentSelected($args[0], _currentRule)>>
-	    <<elseif (_currentRule.excludeAssignment.length > 0 || _currentRule.excludeFacility.length > 0)>>
-		<<set _ruleAppliesToThisSlave = !ruleAssignmentExcluded($args[0], _currentRule)>>
-			<</if>>
-
-	    /% We then check if a slave is specifically included or
-	     % excluded.  This takes precedence over any assignment
-	     % checks.
-			 %/
-	    <<if (_currentRule.selectedSlaves.length > 0)>>
-				<<set _ruleAppliesToThisSlave = ruleSlaveSelected($args[0], _currentRule)>>
-	    <<elseif (_currentRule.excludedSlaves.length > 0)>>
-				<<set _ruleAppliesToThisSlave = !ruleSlaveExcluded($args[0], _currentRule)>>
-			<</if>>
-		<</if>>
-
-		<<if _ruleAppliesToThisSlave>>
-			<<if !ruleApplied($args[0], _currentRule.ID)>> /* rule applies now, but did not apply before */
-				<<set $args[0].currentRules.push(_currentRule.ID)>>
-				<br>//@@.tan;Rule _rule (_currentRule.name) now applies to $args[0].slaveName, who is assigned to $args[0].assignment.@@//
-			<</if>>
-		<<elseif ruleApplied($args[0], _currentRule.ID)>> /* rule does not apply now, but did before */
-			<<RARemoveRule $args[0] _currentRule>>    /* prints message and calls RAFacilityRemove */
-		<</if>>
-	<</for>>
-
-	/* done checking/applying/removing rules - sort this slave's updated applied rules to match the current priority order in the rules assistant */
-	<<set $args[0].currentRules = $args[0].currentRules.sort(function(a, b) { return a-b; });>>
-
+	<<= CheckAutoRulesActivate($args[0]) >>
 <</widget>>
 
 /*
-- 
GitLab