From 68fe2daa27a135bf1584d97d8dcdd116f5fa1c81 Mon Sep 17 00:00:00 2001
From: Svornost <11434-svornost@users.noreply.gitgud.io>
Date: Wed, 3 Mar 2021 14:40:14 -0800
Subject: [PATCH] Revise parent generation to allow a broader age range.  Spin
 out age range determination so it can be checked early, and check it before
 attempting to generate parents in RE Relative Recruiter and Starting Girls.

---
 src/events/reRelativeRecruiter.js           | 22 +++++++++----
 src/npc/generate/generateRelatedSlave.js    | 34 +++++++++++++++------
 src/npc/startingGirls/commitStartingGirl.tw | 10 ++++--
 3 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/src/events/reRelativeRecruiter.js b/src/events/reRelativeRecruiter.js
index bcd01a834ad..f1405dfab40 100644
--- a/src/events/reRelativeRecruiter.js
+++ b/src/events/reRelativeRecruiter.js
@@ -27,7 +27,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba
 			slave.canRecruit = 0;
 			return false;
 		}
-		const choices = this._getTargetRelativeChoices(slave);
+		const choices = this._getTargetRelativeChoices(slave, gp);
 		if (choices.length === 0) {
 			slave.canRecruit = 0; // slave has exhausted possible relatives, can't recruit any longer
 			return false;
@@ -38,18 +38,28 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba
 
 	/** find all eligible target relatives for a slave; one will be selected randomly (or by cheating)
 	 * @param {App.Entity.SlaveState} slave who's doing the recruiting (should be first actor)
+	 * @param {App.Entity.SlaveState} [gp] genepool entry for this slave, if known
 	 * @returns {string[]}
 	 */
-	_getTargetRelativeChoices(slave) {
+	_getTargetRelativeChoices(slave, gp) {
 		let recruit = [];
+		if (!gp) {
+			gp = V.genePool.find(s => s.ID === slave.ID);
+		}
 
 		const pushWeight = (value, weight=1) => recruit.push(...Array(weight).fill(value));
 
-		if (slave.mother === 0 && slave.actualAge + V.fertilityAge < V.retirementAge - 2 && V.seeDicks !== 100) {
-			pushWeight("mother", 3);
+		if (slave.mother === 0 && V.seeDicks !== 100) {
+			const momAge = getParentAgeRange(slave, false);
+			if (momAge.max >= momAge.min) {
+				pushWeight("mother", 3);
+			}
 		}
-		if (slave.father === 0 && slave.actualAge + V.potencyAge < V.retirementAge - 2 && V.seeDicks !== 0) {
-			pushWeight("father");
+		if (slave.father === 0 && V.seeDicks !== 0) {
+			const dadAge = getParentAgeRange(slave, true);
+			if (dadAge.max >= dadAge.min) {
+				pushWeight("father");
+			}
 		}
 
 		// TODO: age should probably be checking genepool, not current state, since the child would have been born before the event slave was in your possession
diff --git a/src/npc/generate/generateRelatedSlave.js b/src/npc/generate/generateRelatedSlave.js
index acc2cfe5e97..6230dbd8c7f 100644
--- a/src/npc/generate/generateRelatedSlave.js
+++ b/src/npc/generate/generateRelatedSlave.js
@@ -17,7 +17,8 @@ globalThis.generateRelatedSlave = (function() {
 		} else if (relationship === "child") {
 			makeChild(relative, slave.genes);
 		} else if (relationship === "parent") {
-			makeParent(relative);
+			const father = (slave.genes === "XX" && oppositeSex) || (slave.genes === "XY" && !oppositeSex);
+			makeParent(relative, father);
 		} else if (relationship === "younger sibling") {
 			makeYoungerSibling(relative);
 		} else if (relationship === "older sibling") {
@@ -211,20 +212,19 @@ globalThis.generateRelatedSlave = (function() {
 	/**
 	 * Finish configuring a parent
 	 * @param {App.Entity.SlaveState} slave - the new parent
+	 * @param {boolean} father - is the parent going to be a father or a mother?
 	 */
-	function makeParent(slave) {
+	function makeParent(slave, father) {
 		slave.mother = 0;
 		slave.father = 0;
 
 		// select age
-		const childAge = slave.actualAge;
-		let minAge = childAge + Math.max(11, V.minimumSlaveAge - 2);
-		let maxAge = Math.min(V.retirementAge - 1, childAge + 42);
-		if (maxAge < minAge) {
+		const ageRange = getParentAgeRange(slave, father);
+		if (ageRange.min > ageRange.max) {
 			throw "Cannot generate parent (slave too old)";
 		}
-		const targetAge = random(minAge, maxAge);
-		fastForward(slave, targetAge - childAge);
+		const targetAge = random(ageRange.min, ageRange.max);
+		fastForward(slave, targetAge - slave.actualAge);
 		slave.birthWeek = random(0, 51);
 
 		// parent always has less devotion/trust
@@ -232,7 +232,7 @@ globalThis.generateRelatedSlave = (function() {
 		slave.trust -= 10;
 
 		// mother always has more boobs/butt
-		if (slave.genes === "XX") {
+		if (!father) {
 			slave.boobs += 100;
 			slave.butt += 1;
 		}
@@ -240,7 +240,7 @@ globalThis.generateRelatedSlave = (function() {
 		fuzzPhysicalTraits(slave);
 
 		// mother has had one child (at least)
-		if (slave.genes === "XX") {
+		if (!father) {
 			slave.vagina = Math.max(slave.vagina, 1);
 			slave.counter.birthsTotal = 1;
 		}
@@ -557,3 +557,17 @@ globalThis.generateRelatedSlave = (function() {
 
 	return generateRelative;
 })();
+
+/** Return the valid age range for a parent for the given slave
+ * NOTE: If minimum age is GREATER than maximum age, the parent cannot be generated. Check first!
+ * @param {App.Entity.SlaveState} slave
+ * @param {boolean} maleParent - true if the desired parent is a father
+ * @returns {{min: number, max: number}}
+ */
+globalThis.getParentAgeRange = function(slave, maleParent) {
+	const childAge = slave.actualAge;
+	const min = childAge + (maleParent ? V.potencyAge : V.fertilityAge) + 1;
+	const lastFertileYear = maleParent ? 75 : 45;
+	const max = Math.min(V.retirementAge - 1, childAge + lastFertileYear);
+	return {min, max};
+};
diff --git a/src/npc/startingGirls/commitStartingGirl.tw b/src/npc/startingGirls/commitStartingGirl.tw
index 8ce20e177e3..5a9c3c4ce7d 100644
--- a/src/npc/startingGirls/commitStartingGirl.tw
+++ b/src/npc/startingGirls/commitStartingGirl.tw
@@ -48,8 +48,9 @@
 		<<goto "Starting Girls">>
 	<</link>>
 	</div>
-	<<if $activeSlave.actualAge + $minimumSlaveAge < $retirementAge - 1>>
-		<<if $seeDicks !== 100 && $activeSlave.mother === 0>>
+	<<if $seeDicks !== 100 && $activeSlave.mother === 0>>
+		<<set _ageRange = getParentAgeRange($activeSlave, false)>>
+		<<if _ageRange.min <= _ageRange.max>>
 			<div class="indent">
 			<<link "Mother">>
 				<<set $activeSlave = generateRelatedSlave(_beforeCareerBonus, "parent", _beforeCareerBonus.genes === "XY")>>
@@ -59,7 +60,10 @@
 			<</link>>
 			</div>
 		<</if>>
-		<<if $seeDicks !== 0 && $activeSlave.father === 0>>
+	<</if>>
+	<<if $seeDicks !== 0 && $activeSlave.father === 0>>
+		<<set _ageRange = getParentAgeRange($activeSlave, true)>>
+		<<if _ageRange.min <= _ageRange.max>>
 			<div class="indent">
 			<<link "Father">>
 				<<set $activeSlave = generateRelatedSlave(_beforeCareerBonus, "parent", _beforeCareerBonus.genes === "XX")>>
-- 
GitLab