From ff0bfaef4815850811f72079f35ad709177956b7 Mon Sep 17 00:00:00 2001
From: Svornost <11434-svornost@users.noreply.gitgud.io>
Date: Wed, 15 Apr 2020 23:02:14 -0700
Subject: [PATCH] 1. Fix family tree not drawing when first arriving on the
 Family tab of the Starting Girls screen. 2. Move starting girls support
 functions out of the global namespace and into App.StartingGirls. 3. Replace
 <<listOfSlavesWithParent>> widget with JS.

---
 src/npc/startingGirls/commitStartingGirl.tw | 26 ++++++-------
 src/npc/startingGirls/startingGirls.js      | 35 +++++++++++++++--
 src/npc/startingGirls/startingGirls.tw      | 22 +++++------
 src/utility/extendedFamilyWidgets.tw        | 42 +++++----------------
 4 files changed, 64 insertions(+), 61 deletions(-)

diff --git a/src/npc/startingGirls/commitStartingGirl.tw b/src/npc/startingGirls/commitStartingGirl.tw
index d22292c5955..dacd8d4ea5d 100644
--- a/src/npc/startingGirls/commitStartingGirl.tw
+++ b/src/npc/startingGirls/commitStartingGirl.tw
@@ -1,6 +1,6 @@
 :: Commit Starting Girl [nobr]
 
-<<run startingGirlCleanup($activeSlave)>>
+<<run App.StartingGirls.cleanup($activeSlave)>>
 
 <<if def $slaveIndices[$activeSlave.ID]>>
 	<div>@@red;Starting Girl ID conflict; slave not committed.  Please report this error with a description of your actions.@@</div>
@@ -17,21 +17,21 @@
 <<if $cash < minimumSlaveCost()>><<goto "Acquisition">><</if>>
 
 <<run cashX(forceNeg(startingSlaveCost($activeSlave)), "slaveTransfer", $activeSlave)>>
-<<run applyCareerBonus(getSlave($activeSlave.ID))>>
+<<run App.StartingGirls.applyCareerBonus(getSlave($activeSlave.ID))>>
 
 <<= SlaveFullName($activeSlave)>> has been added to your starting stable of slaves. You now have <<print cashFormat($cash)>> remaining.
 <br>
 <<if $cash >= minimumSlaveCost()>>
 	<br>
 	<<link "Add another slave, starting from a new slave">>
-		<<set $activeSlave = generateStartingSlave()>>
+		<<set $activeSlave = App.StartingGirls.generate()>>
 		<<goto "Starting Girls">>
 	<</link>>
 	<br>
 	<<link "Add another slave, based on the previous slave">>
 		<<set $activeSlave = clone($activeSlave)>>
 		<<set $activeSlave.ID = generateSlaveID()>>
-		<<run nationalityToName($activeSlave), randomizeUnknowns($activeSlave)>>
+		<<run nationalityToName($activeSlave), App.StartingGirls.randomizeUnknowns($activeSlave)>>
 		<<set $activeSlave.mother = 0, $activeSlave.father = 0>>
 		<<goto "Starting Girls">>
 	<</link>>
@@ -42,7 +42,7 @@
 	<<link "Twin">>
 		<<run setMissingParents(getSlave(_srcID))>>
 		<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "twin")>>
-		<<run randomizeUnknowns($activeSlave)>>
+		<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 		<<goto "Starting Girls">>
 	<</link>>
 	</div>
@@ -51,7 +51,7 @@
 			<div class="indent">
 			<<link "Mother">>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "parent", getSlave(_srcID).genes === "XY")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<set getSlave(_srcID).mother = $activeSlave.ID>>
 				<<goto "Starting Girls">>
 			<</link>>
@@ -61,7 +61,7 @@
 			<div class="indent">
 			<<link "Father">>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "parent", getSlave(_srcID).genes === "XX")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<set getSlave(_srcID).father = $activeSlave.ID>>
 				<<goto "Starting Girls">>
 			<</link>>
@@ -74,7 +74,7 @@
 			<<link "Older Sister">>
 				<<run setMissingParents(getSlave(_srcID))>>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "older sibling", getSlave(_srcID).genes === "XY")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<goto "Starting Girls">>
 			<</link>>
 			</div>
@@ -84,7 +84,7 @@
 			<<link "Older Brother">>
 				<<run setMissingParents(getSlave(_srcID))>>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "older sibling", getSlave(_srcID).genes === "XX")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<goto "Starting Girls">>
 			<</link>>
 			</div>
@@ -96,7 +96,7 @@
 			<<link "Younger Sister">>
 				<<run setMissingParents(getSlave(_srcID))>>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "younger sibling", getSlave(_srcID).genes === "XY")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<goto "Starting Girls">>
 			<</link>>
 			</div>
@@ -106,7 +106,7 @@
 			<<link "Younger Brother">>
 				<<run setMissingParents(getSlave(_srcID))>>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "younger sibling", getSlave(_srcID).genes === "XX")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<goto "Starting Girls">>
 			<</link>>
 			</div>
@@ -117,7 +117,7 @@
 			<div class="indent">
 			<<link "Daughter">>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "child", getSlave(_srcID).genes === "XY")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<goto "Starting Girls">>
 			<</link>>
 			</div>
@@ -126,7 +126,7 @@
 			<div class="indent">
 			<<link "Son">>
 				<<set $activeSlave = generateRelatedSlave(getSlave(_srcID), "child", getSlave(_srcID).genes === "XX")>>
-				<<run randomizeUnknowns($activeSlave)>>
+				<<run App.StartingGirls.randomizeUnknowns($activeSlave)>>
 				<<goto "Starting Girls">>
 			<</link>>
 			</div>
diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js
index c39e95063bc..e6ce0f7d257 100644
--- a/src/npc/startingGirls/startingGirls.js
+++ b/src/npc/startingGirls/startingGirls.js
@@ -1,5 +1,7 @@
+App.StartingGirls = {};
+
 /* Generate a new slave for the starting girls passage */
-window.generateStartingSlave = function(params) {
+App.StartingGirls.generate = function(params) {
 	let slave = GenerateNewSlave(null, params);
 	setHealth(slave, 0);
 	slave.devotion = 0;
@@ -14,7 +16,7 @@ window.generateStartingSlave = function(params) {
 };
 
 /* Make sure user-entered values aren't crazy for starting girls */
-window.startingGirlCleanup = function(slave) {
+App.StartingGirls.cleanup = function(slave) {
 	slave.actualAge = Math.clamp(slave.actualAge, V.minimumSlaveAge, V.retirementAge-1) || 18;
 	slave.physicalAge = slave.actualAge;
 	slave.visualAge = slave.actualAge;
@@ -89,7 +91,7 @@ window.startingGirlCleanup = function(slave) {
 };
 
 /* Starting girl PC career bonus */
-window.applyCareerBonus = function(slave) {
+App.StartingGirls.applyCareerBonus = function(slave) {
 	function applySexSkillBonus() {
 		let _seed = 2;
 		if (slave.skill.oral < 60) {
@@ -165,7 +167,7 @@ window.applyCareerBonus = function(slave) {
 };
 
 /* randomize things the player doesn't know about the slave */
-window.randomizeUnknowns = function(slave) {
+App.StartingGirls.randomizeUnknowns = function(slave) {
 	if (slave.attrKnown === 0) {
 		slave.attrXX = random(0, 100);
 		slave.attrXY = random(0, 100);
@@ -176,3 +178,28 @@ window.randomizeUnknowns = function(slave) {
 		slave.fetish = either("boobs", "buttslut", "cumslut", "dom", "humiliation", "masochist", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "pregnancy", "sadist", "submissive");
 	}
 };
+
+/**
+ * Generate a pipe-separated list of slaves with a given mother or father
+ * @param {string} parent - "mother" or "father"
+ * @param {number} id - parent's slave ID
+ * @returns {string}
+ */
+App.StartingGirls.listOfSlavesWithParent = function(parent, id) {
+	if (id === 0) {
+		return "";
+	}
+	let slaveNames = [];
+	if (V.PC[parent] === id) {
+		slaveNames.push("You");
+	}
+	const slavesWithParent = V.slaves.filter((s) => s[parent] === id);
+	slaveNames = slaveNames.concat(slavesWithParent.map((s) => s.slaveName));
+	return slaveNames.join(" | ");
+};
+
+/* renders the family tree with an uncommitted slave */
+App.StartingGirls.uncommittedFamilyTree = function(slave) {
+	let tSlaves = V.slaves.concat([slave]); // returns a new array
+	renderFamilyTree(tSlaves, slave.ID);
+};
diff --git a/src/npc/startingGirls/startingGirls.tw b/src/npc/startingGirls/startingGirls.tw
index 41a56aacecc..a72ad04ffec 100644
--- a/src/npc/startingGirls/startingGirls.tw
+++ b/src/npc/startingGirls/startingGirls.tw
@@ -39,7 +39,7 @@
 	<</link>>
 
 	| <<link "Start over with a random slave" "Starting Girls">>
-		<<set $activeSlave = generateStartingSlave()>>
+		<<set $activeSlave = App.StartingGirls.generate()>>
 	<</link>>
 
 	| [[Take control of your arcology|Acquisition]]
@@ -50,10 +50,10 @@
 <<run App.UI.tabbar.handlePreSelectedTab($tabChoice.startingGirls)>>
 
 <<if !$activeSlave>>
-	<<set $activeSlave = generateStartingSlave()>>
+	<<set $activeSlave = App.StartingGirls.generate()>>
 <</if>>
 
-<<run startingGirlCleanup($activeSlave)>>
+<<run App.StartingGirls.cleanup($activeSlave)>>
 <<set _slaveCost = startingSlaveCost($activeSlave)>>
 <<set $saleDescription = 1>>
 
@@ -264,7 +264,7 @@
 <div class="tabbar">
 	<button class="tablinks" onclick="App.UI.tabbar.openTab(event, 'baseStats')" id="tab baseStats">Base stats</button>
 	<button class="tablinks" onclick="App.UI.tabbar.openTab(event, 'Appearance')" id="tab Appearance">Appearance</button>
-	<button class="tablinks" onclick="App.UI.tabbar.openTab(event, 'Family')" id="tab Family">Edit family</button>
+	<button class="tablinks" onclick="App.UI.tabbar.openTab(event, 'Family', App.StartingGirls.uncommittedFamilyTree(V.activeSlave))" id="tab Family">Edit family</button>
 	<button class="tablinks" onclick="App.UI.tabbar.openTab(event, 'customizationOptions')" id="tab customizationOptions">More customization options</button>
 	<<if $cash >= _slaveCost>>
 		<button class="tablinks" onclick="App.UI.tabbar.openTab(event, 'assignRemove')" id="tab assignRemove">Finalize</button>
@@ -1599,7 +1599,7 @@
 	</div>
 	<div class="indent">
 		<<link "Irish Rose">>
-			<<set $activeSlave = generateStartingSlave({ nationality: "Irish", race: "white" })>>
+			<<set $activeSlave = App.StartingGirls.generate({ nationality: "Irish", race: "white" })>>
 			<<set $activeSlave.eye.origColor = "green", $activeSlave.origSkin = "fair", $activeSlave.origHColor = "red", $activeSlave.markings = "heavily freckled">>
 			<<goto "Starting Girls">>
 		<</link>>
@@ -1610,7 +1610,7 @@
 
 	<div class="indent">
 		<<link "Cali Girl">>
-			<<set $activeSlave = generateStartingSlave({ nationality: "American" })>>
+			<<set $activeSlave = App.StartingGirls.generate({ nationality: "American" })>>
 			<<set $activeSlave.eye.origColor = "blue", $activeSlave.skin = "sun tanned", $activeSlave.override_Skin = 1, $activeSlave.origHColor = "blonde", $activeSlave.markings = "none", $activeSlave.face = 95, $activeSlave.muscles = 20, $activeSlave.weight = -20, $activeSlave.height = Math.round(Height.forAge(190, $activeSlave))>>
 			<<goto "Starting Girls">>
 		<</link>>
@@ -1621,7 +1621,7 @@
 
 	<div class="indent">
 		<<link "Novice">>
-			<<set $activeSlave = generateStartingSlave()>>
+			<<set $activeSlave = App.StartingGirls.generate()>>
 			<<set $activeSlave.skill.anal = 0, $activeSlave.skill.oral = 0, $activeSlave.skill.vaginal = 0, $activeSlave.skill.whoring = 0, $activeSlave.skill.entertainment = 0, $activeSlave.skill.combat = 0, $activeSlave.actualAge = 18, $activeSlave.visualAge = 18, $activeSlave.physicalAge = 18, $activeSlave.fetishKnown = 0, $activeSlave.attrKnown = 0>>
 			<<goto "Starting Girls">>
 		<</link>>
@@ -1632,7 +1632,7 @@
 
 	<div class="indent">
 		<<link "Head Girl Prospect">>
-			<<set $activeSlave = generateStartingSlave({ minAge: 36, maxAge: 44 })>>
+			<<set $activeSlave = App.StartingGirls.generate({ minAge: 36, maxAge: 44 })>>
 			<<set $activeSlave.career = setup.HGCareers.random(), $activeSlave.intelligence = 70, $activeSlave.intelligenceImplant = 0>>
 			<<goto "Starting Girls">>
 		<</link>>
@@ -1644,7 +1644,7 @@
 	<<if $seeExtreme != 0>>
 		<div class="indent">
 			<<link "Wellspring">>
-				<<set $activeSlave = generateStartingSlave({ minAge: 18, maxAge: 18 })>>
+				<<set $activeSlave = App.StartingGirls.generate({ minAge: 18, maxAge: 18 })>>
 				<<set $activeSlave.skill.anal = 0, $activeSlave.skill.oral = 0, $activeSlave.skill.vaginal = 0, $activeSlave.skill.whoring = 0, $activeSlave.skill.entertainment = 0, $activeSlave.skill.combat = 0, $activeSlave.fetishKnown = 0, $activeSlave.attrKnown = 0, $activeSlave.health.condition = 10, $activeSlave.intelligence = -100, $activeSlave.intelligenceImplant = 0, $activeSlave.vagina = 3, $activeSlave.anus = 3, $activeSlave.ovaries = 1, $activeSlave.dick = 5, $activeSlave.balls = 5, $activeSlave.prostate = 1, $activeSlave.lactation = 2, $activeSlave.lactationDuration = 2, $activeSlave.nipples = "huge", $activeSlave.boobs = 10000>>
 				<<goto "Starting Girls">>
 			<</link>>
@@ -1655,7 +1655,7 @@
 
 		<div class="indent">
 			<<link "Onahole">>
-				<<set $activeSlave = generateStartingSlave()>>
+				<<set $activeSlave = App.StartingGirls.generate()>>
 				<<set $activeSlave.skill.anal = 0, $activeSlave.skill.oral = 0, $activeSlave.skill.vaginal = 0, $activeSlave.skill.whoring = 0, $activeSlave.skill.entertainment = 0, $activeSlave.skill.combat = 0, $activeSlave.fetish = "mindbroken", $activeSlave.voice = 0, $activeSlave.hears = 0>>
 				<<run removeLimbs($activeSlave, "all"), eyeSurgery($activeSlave, "both", "normal")>>
 				<<goto "Starting Girls">>
@@ -1673,7 +1673,7 @@
 				<<set _nation = setup.baseNationalities[_sg]>>
 				<<capture _nation>>
 				<<link _nation>>
-					<<set $activeSlave = generateStartingSlave({ nationality: _nation })>>
+					<<set $activeSlave = App.StartingGirls.generate({ nationality: _nation })>>
 					<<goto "Starting Girls">>
 				<</link>>
 				<</capture>>
diff --git a/src/utility/extendedFamilyWidgets.tw b/src/utility/extendedFamilyWidgets.tw
index 1349aaf6cb1..35b9463db47 100644
--- a/src/utility/extendedFamilyWidgets.tw
+++ b/src/utility/extendedFamilyWidgets.tw
@@ -15,35 +15,14 @@
 
 <<widget "redisplayFamily">>
 <<replace '#dontBeDumb'>><br> //You will break things by making impossible relations such as being your own father. If you do this, clearing all PC relations will fix it. Probably.//<</replace>>
-<<replace '#fatheredNames'>><<listOfSlavesWithParent "father" $activeSlave.ID>><</replace>>
-<<replace '#motheredNames'>><<listOfSlavesWithParent "mother" $activeSlave.ID>><</replace>>
+<<replace '#fatheredNames'>><<= App.StartingGirls.listOfSlavesWithParent("father", $activeSlave.ID)>><</replace>>
+<<replace '#motheredNames'>><<= App.StartingGirls.listOfSlavesWithParent("mother", $activeSlave.ID)>><</replace>>
 <<replace '#familySummary'>><<= App.Desc.family($activeSlave)>><</replace>>
 <<replace '#motherName'>><<parentName "mother">><</replace>>
 <<replace '#fatherName'>><<parentName "father">><</replace>>
-<<replace '#sameMotherNames'>><<listOfSlavesWithParent "mother" $activeSlave.mother>><</replace>>
-<<replace '#sameFatherNames'>><<listOfSlavesWithParent "father" $activeSlave.father>><</replace>>
-/* <<run updateFamilyTree($activeSlave, $slaves, $PC)>> */
-<<set _tSlaveList = [$activeSlave]>>
-<<set _tSlaveList.push.apply(_tSlaveList, $slaves)>>
-<<run renderFamilyTree(_tSlaveList, $activeSlave.ID)>>
-<</widget>>
-
-/* First parameter is e.g. "father" or "mother" and second parameter is the ID to match */
-<<widget "listOfSlavesWithParent">>
-<<if $args[1] != 0>>
-	<<set _printSeperator = false>>
-	<<if $args[1] == $PC[$args[0]]>>
-		You
-		<<set _printSeperator = true>>
-	<</if>>
-	<<for _j = 0; _j < $slaves.length; _j++>>
-		<<if $slaves[_j][$args[0]] == $args[1]>>
-			<<if _printSeperator>> | <</if>>
-			<<set _printSeperator = true>>
-			<<print $slaves[_j].slaveName>>
-		<</if>>
-	<</for>>
-<</if>>
+<<replace '#sameMotherNames'>><<= App.StartingGirls.listOfSlavesWithParent("mother", $activeSlave.mother)>><</replace>>
+<<replace '#sameFatherNames'>><<= App.StartingGirls.listOfSlavesWithParent("father", $activeSlave.father)>><</replace>>
+<<run App.StartingGirls.uncommittedFamilyTree($activeSlave)>>
 <</widget>>
 
 <<widget "editFamily">>
@@ -95,7 +74,7 @@
 	<</if>>
 <</for>>
 
-<br>''Same mother as:'' <span id="sameMotherNames"><<listOfSlavesWithParent 'mother' $activeSlave.mother>></span>
+<br>''Same mother as:'' <span id="sameMotherNames"><<= App.StartingGirls.listOfSlavesWithParent('mother', $activeSlave.mother)>></span>
 <<link "Reset">>
 	<<set $activeSlave.mother = 0>>
 	<<redisplayFamily>>
@@ -139,7 +118,7 @@
 	<</if>>
 <</for>>
 
-<br>''Same father as:'' <span id="sameFatherNames"><<listOfSlavesWithParent 'father' $activeSlave.father>></span>
+<br>''Same father as:'' <span id="sameFatherNames"><<= App.StartingGirls.listOfSlavesWithParent('father', $activeSlave.father)>></span>
 <<link "Reset">>
 	<<set $activeSlave.father = 0>>
 	<<replace '#fatherName'>><</replace>>
@@ -185,7 +164,7 @@
 	<</if>>
 <</for>>
 
-<br>''Mother of the children:'' <span id="motheredNames"><<listOfSlavesWithParent "mother" $activeSlave.ID>></span>
+<br>''Mother of the children:'' <span id="motheredNames"><<= App.StartingGirls.listOfSlavesWithParent("mother", $activeSlave.ID)>></span>
 <<link "Reset">>
 	<<for _efw = 0; _efw < $slaves.length; _efw++>>
 		<<if $slaves[_efw].mother == $activeSlave.ID && $slaves[_efw].newGamePlus == 0>>
@@ -230,7 +209,7 @@
 	<</for>>
 <</if>>
 
-<br>''Father of the children:'' <span id="fatheredNames"><<listOfSlavesWithParent "father" $activeSlave.ID>></span>
+<br>''Father of the children:'' <span id="fatheredNames"><<= App.StartingGirls.listOfSlavesWithParent("father", $activeSlave.ID)>></span>
 <<link "Reset">>
 	<<for _efw = 0; _efw < $slaves.length; _efw++>>
 		<<if $slaves[_efw].father == $activeSlave.ID && $slaves[_efw].newGamePlus == 0>>
@@ -322,9 +301,6 @@
 <br>
 </div>
 <div id="familyTree"></div>
-	<<set _tSlaveList = [$activeSlave]>>
-	<<set _tSlaveList.push.apply(_tSlaveList, $slaves)>>
-	<<run renderFamilyTree(_tSlaveList, $activeSlave.ID)>>
 </div>
 
 <</widget>>
-- 
GitLab