From d2ff309b95d40fb8ee52ebf43ec4aff7e0786f02 Mon Sep 17 00:00:00 2001
From: Svornost <11434-svornost@users.noreply.gitgud.io>
Date: Wed, 8 Apr 2020 20:28:53 -0700
Subject: [PATCH] Implement BC for converting LFM to EFM

---
 js/003-data/gameVariableData.js               |  1 -
 .../backwardsCompatibility.js                 | 14 +++++
 .../updateSlaveObject.js                      | 61 ++++++++++++++++++-
 3 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js
index b41a0b8dd50..0f799788a6d 100644
--- a/js/003-data/gameVariableData.js
+++ b/js/003-data/gameVariableData.js
@@ -66,7 +66,6 @@ App.Data.defaultGameStateVariables = {
 	economy: 100,
 	expansionRequestsAllowed: 1,
 	extremeUnderage: 0,
-	familyTesting: 0,
 	formatNumbers: 1,
 	fucktoyInteractionsPosition: 1,
 	headGirlSoftensFlaws: 1,
diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js
index 9fc833beb01..994337a3bab 100644
--- a/src/data/backwardsCompatibility/backwardsCompatibility.js
+++ b/src/data/backwardsCompatibility/backwardsCompatibility.js
@@ -1240,6 +1240,11 @@ App.Update.slaveRecords = function(node) {
 		}
 		nurseryDiv.append(`Done!`);
 	}
+
+	// if we updated from legacy to extended family mode, reset the EFM controllers
+	if (V.relationLinks) {
+		resetFamilyCounters();
+	}
 };
 
 App.Update.genePoolRecords = function(node) {
@@ -2008,6 +2013,15 @@ App.Update.oldVersions = function(node) {
 		PCdiv.append(`Done!`);
 	}
 
+	if ((typeof V.familyTesting === "undefined") && V.releaseID < 1065) {
+		// possibly vanilla FC; compel V.familyTesting to 0 so that the family upgrade will run on slaves
+		V.familyTesting = 0;
+	}
+	if (V.familyTesting === 0) {
+		alert("Converting family data");
+		V.relationLinks = {}; // init temp structure for mapping relationships from legacy to extended family mode
+	}
+
 	node.append(`Done!`);
 };
 
diff --git a/src/data/backwardsCompatibility/updateSlaveObject.js b/src/data/backwardsCompatibility/updateSlaveObject.js
index 4b74333a5c6..68e893729cf 100644
--- a/src/data/backwardsCompatibility/updateSlaveObject.js
+++ b/src/data/backwardsCompatibility/updateSlaveObject.js
@@ -442,7 +442,7 @@ App.Update.Slave = function(slave, genepool=false) {
 	}
 
 	if (V.releaseID < 1061) {
-		if (slave.boobsImplantType == 1) {
+		if (slave.boobsImplantType === 1) {
 			slave.boobsImplantType = "string";
 		} else if (slave.boobsImplant >= 10000) {
 			slave.boobsImplantType = "hyper fillable";
@@ -455,7 +455,7 @@ App.Update.Slave = function(slave, genepool=false) {
 		} else {
 			slave.boobsImplantType = "none";
 		}
-		if (slave.buttImplantType == 1) {
+		if (slave.buttImplantType === 1) {
 			slave.buttImplantType = "string";
 		} else if (slave.buttImplant > 7) {
 			slave.buttImplantType = "hyper fillable";
@@ -964,4 +964,61 @@ App.Update.Slave = function(slave, genepool=false) {
 	if (slave.rules !== undefined && slave.rules.rest === undefined) {
 		slave.rules.rest = "restrictive";
 	}
+
+	// migrate to extended family mode if we detected it was needed
+	if (V.relationLinks !== undefined) {
+		let link = V.relationLinks[slave.ID];
+		if (link) {
+			// we already know who your parents are
+			slave.mother = link.mother;
+			slave.father = link.father;
+		} else {
+			if (slave.relationTarget > 0) {
+				switch (slave.relation) {
+					case "sister":
+					case "twin": {
+						const otherLink = V.relationLinks[slave.relationTarget];
+						if (otherLink) {
+							// we don't know your parents, but we DO know your sister's parents
+							// this shouldn't happen but might sometimes, and there's an obviously correct thing to do - use your sister's parents for you too
+							slave.mother = otherLink.mother;
+							slave.father = otherLink.father;
+						} else {
+							// don't know your parents, generate new IDs for them
+							slave.mother = V.missingParentID;
+							V.missingParentID--;
+							slave.father = V.missingParentID;
+							V.missingParentID--;
+						}
+						V.relationLinks[slave.ID] = {mother: slave.mother, father: slave.father};
+						// your sister's parents are the same as your parents
+						if (!V.relationLinks[slave.relationTarget]) {
+							V.relationLinks[slave.relationTarget] = V.relationLinks[slave.ID];
+						}
+						break;
+					}
+					case "mother":
+						// we know your mother. that's easy.
+						slave.mother = slave.relationTarget;
+						V.relationLinks[slave.ID] = {mother: slave.mother, father: 0};
+						break;
+					case "daughter":
+						// we know you are your daughter's mother. keep track of that in case she's forgotten somehow.
+						if (!V.relationLinks[slave.relationTarget]) {
+							V.relationLinks[slave.relationTarget] = {mother: slave.ID, father: 0};
+						}
+						break;
+					default:
+						throw `Unrecognized relation for ${SlaveFullName(slave)}.`;
+				}
+			}
+		}
+
+		// if the slave still had a valid recruitment target, allow her to recruit, otherwise don't
+		slave.canRecruit = (slave.recruiter === 0) ? 0 : 1;
+	}
+	delete slave.relation;
+	delete slave.relationTarget;
+	delete slave.recruiter;
+
 };
-- 
GitLab