From d6c5bc40b313eb4bdbe1796d96578a5c22aec75e Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@gmail.com>
Date: Tue, 19 Jan 2021 16:25:06 +0100
Subject: [PATCH] Move organ farm data to js/ and convert to Map

---
 js/002-config/fc-js-init.js                   |   2 -
 .../medicine/1-organFarmBase.js               |   6 +-
 .../medicine/2-reproductiveOrgans.js          |  40 +-
 js/medicine/3-organMap.js                     | 432 +++++++++++++++++
 src/interaction/multiImplant.js               |   6 +-
 src/npc/surgery/organFarm.js                  |  48 +-
 src/npc/surgery/organs.js                     | 442 ------------------
 src/zz1-last/init.js                          |   1 -
 8 files changed, 482 insertions(+), 495 deletions(-)
 rename src/004-base/organFarmBase.js => js/medicine/1-organFarmBase.js (92%)
 rename src/npc/surgery/reproductiveOrgans.js => js/medicine/2-reproductiveOrgans.js (93%)
 create mode 100644 js/medicine/3-organMap.js
 delete mode 100644 src/npc/surgery/organs.js

diff --git a/js/002-config/fc-js-init.js b/js/002-config/fc-js-init.js
index 1710cf940df..a9df5e5e41e 100644
--- a/js/002-config/fc-js-init.js
+++ b/js/002-config/fc-js-init.js
@@ -57,8 +57,6 @@ App.Medicine.Modification = {};
 App.Medicine.Modification.Brands = {};
 App.Medicine.Modification.Select = {};
 App.Medicine.OrganFarm = {};
-/** @type {Object.<string, App.Medicine.OrganFarm.Organ>} */
-App.Medicine.OrganFarm.Organs = {};
 App.Medicine.Salon = {};
 App.Medicine.Surgery = {};
 App.RA = {};
diff --git a/src/004-base/organFarmBase.js b/js/medicine/1-organFarmBase.js
similarity index 92%
rename from src/004-base/organFarmBase.js
rename to js/medicine/1-organFarmBase.js
index 9913f2fdd1a..03051204f3c 100644
--- a/src/004-base/organFarmBase.js
+++ b/js/medicine/1-organFarmBase.js
@@ -1,7 +1,6 @@
 App.Medicine.OrganFarm.Organ = class {
 	/**
 	 * @param {Object} params
-	 * @param {string} params.type - unique type of organ, used as key
 	 * @param {string} params.name - display name
 	 * @param {string|function(App.Entity.SlaveState):string} [params.tooltip] - full sentence, uncapitalized and unpunctuated
 	 * @param {number} params.cost - how much it costs to grow the organ
@@ -12,10 +11,9 @@ App.Medicine.OrganFarm.Organ = class {
 	 * @param {boolean} [params.displayMultipleActions=false] allow multiple implant links to be displayed
 	 */
 	constructor({
-		type, name, tooltip = "", cost, time, canGrow = () => true, dependencies = [],
+		name, tooltip = "", cost, time, canGrow = () => true, dependencies = [],
 		displayMultipleActions = false, actions = []
 	}) {
-		this.type = type;
 		this.name = name;
 		this.tooltip = tooltip;
 		this.cost = cost;
@@ -27,8 +25,6 @@ App.Medicine.OrganFarm.Organ = class {
 		this.displayMultipleActions = displayMultipleActions;
 		/** @type {App.Medicine.OrganFarm.OrganImplantAction[]} */
 		this.implantActions = actions;
-
-		App.Medicine.OrganFarm.Organs[type] = this;
 	}
 };
 
diff --git a/src/npc/surgery/reproductiveOrgans.js b/js/medicine/2-reproductiveOrgans.js
similarity index 93%
rename from src/npc/surgery/reproductiveOrgans.js
rename to js/medicine/2-reproductiveOrgans.js
index 9d0ac8edfe9..97afc0e7d72 100644
--- a/src/npc/surgery/reproductiveOrgans.js
+++ b/js/medicine/2-reproductiveOrgans.js
@@ -4,17 +4,27 @@ App.Medicine.OrganFarm.TesticlesImplantAction = class extends App.Medicine.Organ
 	 * @param {string} params.name
 	 * @param {string} [params.tooltip]
 	 * @param {boolean} params.animal
+	 * @param {string} [params.surgeryType]
 	 * @param {boolean} [params.autoImplant]
 	 * @param {function(App.Entity.SlaveState):boolean} params.canImplant
 	 * @param {function(App.Entity.SlaveState):string} params.implantError
 	 * @param {function(App.Entity.SlaveState):void} params.implant
 	 */
-	constructor({name, tooltip = "", animal, autoImplant = true, canImplant, implantError, implant}) {
+	constructor({
+		name,
+		tooltip = "",
+		animal,
+		surgeryType = animal ? "addAnimalBalls" : "addBalls",
+		autoImplant = true,
+		canImplant,
+		implantError,
+		implant
+	}) {
 		super({
 			name: name,
 			tooltip: tooltip,
 			healthImpact: 20,
-			surgeryType: animal ? "addAnimalBalls" : "addBalls",
+			surgeryType: surgeryType,
 			autoImplant: autoImplant,
 			canImplant: s => (!this.animal || V.animalTesticles > 0) && canImplant(s),
 			implantError: s => (this.animal && V.animalTesticles === 0) ? "" : implantError(s),
@@ -27,13 +37,12 @@ App.Medicine.OrganFarm.TesticlesImplantAction = class extends App.Medicine.Organ
 App.Medicine.OrganFarm.Testicles = class extends App.Medicine.OrganFarm.Organ {
 	/**
 	 * @param {Object} params
-	 * @param {string} params.type
 	 * @param {string} params.name
 	 * @param {FC.AnimalKind} params.ballType
 	 */
-	constructor({type, name, ballType}) {
+	constructor({name, ballType}) {
 		super({
-			type: type, name: name,
+			name: name,
 			tooltip: "will add a prostate if one is not already present; requires a penis for successful implantation",
 			cost: 5000, time: 10,
 			canGrow: () => (this.ballType === "human" || V.animalTesticles > 0), dependencies: ["penis"],
@@ -71,7 +80,9 @@ App.Medicine.OrganFarm.Testicles = class extends App.Medicine.OrganFarm.Organ {
 				new App.Medicine.OrganFarm.TesticlesImplantAction({
 					name: "Implant",
 					tooltip: "you can forgo standard procedure and implant testicles directly into their abdomen",
-					animal: ballType !== "human", surgeryType: "addTesticles", autoImplant: false,
+					animal: ballType !== "human",
+					surgeryType: "addTesticles",
+					autoImplant: false,
 					canImplant: slave => (slave.dick === 0 && slave.balls <= 0),
 					implantError: slave => ((slave.balls > 0) ? "This slave already has testicles." : ""),
 					implant: slave => {
@@ -94,11 +105,8 @@ App.Medicine.OrganFarm.Testicles = class extends App.Medicine.OrganFarm.Organ {
 					}
 				}),
 				new App.Medicine.OrganFarm.TesticlesImplantAction({
-					name: "Replace",
-					tooltip: "you can replace the existing testicles with a new pair",
-					healthImpact: 20,
-					surgeryType: "addTesticles",
-					autoImplant: false,
+					name: "Replace", tooltip: "you can replace the existing testicles with a new pair",
+					animal: ballType !== "human", surgeryType: "addTesticles", autoImplant: false,
 					canImplant: slave => (slave.balls > 0 && slave.ballType !== this.ballType),
 					implantError: slave => (slave.balls > 0 ? `This slave already has ${this.ballType} testicles.` : ""),
 					implant: slave => {
@@ -149,14 +157,13 @@ App.Medicine.OrganFarm.OvariesImplantAction = class extends App.Medicine.OrganFa
 App.Medicine.OrganFarm.Ovaries = class extends App.Medicine.OrganFarm.Organ {
 	/**
 	 * @param {object} params
-	 * @param {string} params.type
 	 * @param {string} params.name
 	 * @param {FC.AnimalKind} params.eggType
 	 * @param {string} params.pregData
 	 */
-	constructor({type, name, eggType, pregData}) {
+	constructor({name, eggType, pregData}) {
 		super({
-			type: type, name: name, tooltip: "requires a vagina for successful implantation",
+			name: name, tooltip: "requires a vagina for successful implantation",
 			cost: 10000, time: 10,
 			canGrow: () => (this.eggType === "human" || V.animalOvaries > 0),
 			actions: [
@@ -247,14 +254,13 @@ App.Medicine.OrganFarm.AnalWombImplantAction = class extends App.Medicine.OrganF
 App.Medicine.OrganFarm.AnalWomb = class extends App.Medicine.OrganFarm.Organ {
 	/**
 	 * @param {object} params
-	 * @param {string} params.type
 	 * @param {string} params.name
 	 * @param {FC.AnimalKind} params.eggType
 	 * @param {string} params.pregData
 	 */
-	constructor({type, name, eggType, pregData}) {
+	constructor({name, eggType, pregData}) {
 		super({
-			type: type, name: name,
+			name: name,
 			tooltip: "the slave must not have female reproductive organs for successful implantation",
 			cost: 20000, time: 10,
 			canGrow: () => (V.arcologies[0].FSGenderRadicalistResearch === 1 && (eggType === "human" || V.animalMpreg > 0)),
diff --git a/js/medicine/3-organMap.js b/js/medicine/3-organMap.js
new file mode 100644
index 00000000000..1a4efe93585
--- /dev/null
+++ b/js/medicine/3-organMap.js
@@ -0,0 +1,432 @@
+/**
+ * Organs will usually be displayed in this order.
+ *
+/** @type {Map<string, App.Medicine.OrganFarm.Organ>} */
+App.Medicine.OrganFarm.Organs = new Map([
+	["penis",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Penis", cost: 5000, time: 5,
+			canGrow: () => (V.seeDicks !== 0 || V.makeDicks === 1),
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 20, surgeryType: "addDick",
+					canImplant: slave => (slave.dick <= 0),
+					implantError: () => "this slave already has a penis",
+					implant: slave => {
+						if (slave.prostate === 0) {
+							slave.prostate = 1;
+						}
+						slave.dick = 2;
+						slave.clit = 0;
+						slave.foreskin = slave.dick;
+					}
+				})
+			]
+		})],
+	["testicles",
+		new App.Medicine.OrganFarm.Testicles({
+			name: "Testicles", ballType: "human"
+		})],
+	["pigTesticles",
+		new App.Medicine.OrganFarm.Testicles({
+			name: "Pig testicles", ballType: "pig"
+		})],
+	["dogTesticles",
+		new App.Medicine.OrganFarm.Testicles({
+			name: "Dog testicles", ballType: "dog"
+		})],
+	["horseTesticles",
+		new App.Medicine.OrganFarm.Testicles({
+			name: "Horse testicles", ballType: "horse"
+		})],
+	["cowTesticles",
+		new App.Medicine.OrganFarm.Testicles({
+			name: "Cow testicles", ballType: "cow"
+		})],
+	["scrotum",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Scrotum", tooltip: "requires balls for successful implantation", cost: 2500, time: 5,
+			dependencies: ["testicles", "pigTesticles", "dogTesticles", "horseTesticles", "cowTesticles"],
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Graft on", healthImpact: 10, surgeryType: "addScrotum",
+					canImplant: slave => (slave.scrotum <= 0 && slave.balls > 0),
+					implantError: slave => (slave.scrotum > 0) ? "This slave already has a scrotum." : "This slave lacks the balls necessary to accept a scrotum.",
+					implant: slave => {
+						slave.scrotum = slave.balls;
+					}
+				})
+			]
+		})],
+	["foreskin",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Foreskin", cost: 2500, time: 5,
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Graft on", healthImpact: 10, surgeryType: "addForeskin",
+					canImplant: slave => (slave.foreskin <= 0),
+					implantError: slave => `This slave already has a ${slave.dick > 0 ? "foreskin" : "clitoral hood"}.`,
+					implant: slave => {
+						if (slave.dick > 0) {
+							slave.foreskin = slave.dick;
+						} else if (slave.clit > 0) {
+							slave.foreskin = slave.clit;
+						} else {
+							slave.foreskin = 1;
+						}
+					}
+				})
+			]
+		})],
+	["prostate",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Prostate", cost: 5000, time: 5,
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 20, surgeryType: "addProstate",
+					canImplant: s => (s.prostate === 0),
+					implantError: () => "This slave already has a prostate.",
+					implant: s => {
+						s.prostate = 1;
+					}
+				})
+			]
+		})],
+	["ovaries",
+		new App.Medicine.OrganFarm.Ovaries({
+			name: "Ovaries", eggType: "human", pregData: "human"
+		})],
+	["freshOvaries",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Younger Ovaries",
+			tooltip: "requires a womb for successful implantation",
+			cost: 10000, time: 10,
+			canGrow: () => (V.youngerOvaries === 1),
+			dependencies: ["ovaries", "pigOvaries", "dogOvaries", "horseOvaries", "cowOvaries", "mpreg", "mpregPig", "mpregDog", "mpregHorse", "mpregCow"],
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 20, surgeryType: "freshOvaries",
+					canImplant: s => ((s.mpreg !== 0 || s.ovaries !== 0) && s.bellyImplant === -1 && s.physicalAge < 70),
+					implantError: s => (s.physicalAge >= 70) ? "This slave's body is too old to handle pregnancy." : "This slave lacks a viable womb.",
+					implant: s => {
+						if (s.ovaryAge >= 47) {
+							s.ovaryAge = 45;
+						} else {
+							s.ovaryAge = -2; // It shouldn't matter if this goes negative as it is just a signal for menopause to occur.
+						}
+						if (s.preg < 0) {
+							s.preg = 0;
+						}
+						if (s.pubertyXX === 0 && s.physicalAge >= V.fertilityAge) {
+							if (V.precociousPuberty === 1) {
+								s.pubertyAgeXX = s.physicalAge + 1;
+							} else {
+								s.pubertyXX = 1;
+							}
+						}
+					}
+				})
+			]
+		})],
+	["asexualReproOvaries",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Asexual reproduction modification",
+			tooltip: "requires existing ovaries for successful implantation",
+			cost: 10000, time: 10,
+			canGrow: () => (V.asexualReproduction === 1),
+			dependencies: ["ovaries", "pigOvaries", "dogOvaries", "horseOvaries", "cowOvaries", "mpreg", "mpregPig", "mpregDog", "mpregHorse", "mpregCow"],
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 20, surgeryType: "asexualReproOvaries",
+					canImplant: s => (s.mpreg !== 0 || s.ovaries !== 0),
+					implantError: () => "This slave lacks ovaries.",
+					implant: s => {
+						if (s.preg < 0) {
+							s.preg = 0;
+						}
+						s.eggType = "human";
+						s.pregData = clone(setup.pregData.human);
+						if (s.pubertyXX === 0 && s.physicalAge >= V.fertilityAge) {
+							if (V.precociousPuberty === 1) {
+								s.pubertyAgeXX = s.physicalAge + 1;
+							} else {
+								s.pubertyXX = 1;
+							}
+						}
+						s.ovaImplant = "asexual";
+					}
+				})
+			]
+		})],
+	["pigOvaries",
+		new App.Medicine.OrganFarm.Ovaries({
+			name: "Pig ovaries", eggType: "pig", pregData: "pig"
+		})],
+	["dogOvaries",
+		new App.Medicine.OrganFarm.Ovaries({
+			name: "Dog ovaries", eggType: "dog", pregData: "canineM",
+		})],
+	["horseOvaries",
+		new App.Medicine.OrganFarm.Ovaries({
+			name: "Horse ovaries", eggType: "horse", pregData: "equine",
+		})],
+	["cowOvaries",
+		new App.Medicine.OrganFarm.Ovaries({
+			name: "Cow ovaries", eggType: "cow", pregData: "cow"
+		})],
+	["leftEye",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Left Eye", cost: 5000, time: 10,
+			tooltip: s => getLeftEyeVision(s) === 2 ? "would not improve this slave" : "",
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 10, surgeryType: "newEyes",
+					canImplant: s => (getLeftEyeVision(s) === 0 && getBestVision(s) !== 0 && getLeftEyeType(s) !== 2),
+					implantError: s => getLeftEyeVision(s) !== 0 ? "Slave has a working left eye." : "",
+					implant: s => {
+						eyeSurgery(s, "left", "normal");
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 10, surgeryType: "unblind",
+					canImplant: s => (getBestVision(s) === 0 && getLeftEyeType(s) !== 2),
+					implantError: () => "",
+					implant: s => {
+						eyeSurgery(s, "left", "normal");
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Replace", tooltip: "replace the existing ocular implant with an organic eye",
+					healthImpact: 10, surgeryType: "newEyes", autoImplant: false,
+					canImplant: s => (getLeftEyeType(s) === 2),
+					implantError: () => "",
+					implant: s => {
+						eyeSurgery(s, "left", "normal");
+					}
+				})
+			]
+		})],
+	["rightEye",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Right Eye", cost: 5000, time: 10,
+			tooltip: s => getRightEyeVision(s) === 2 ? "would not improve this slave" : "",
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 10, surgeryType: "newEyes",
+					canImplant: s => (getRightEyeVision(s) === 0 && getBestVision(s) !== 0 && getRightEyeType(s) !== 2),
+					implantError: s => getRightEyeVision(s) !== 0 ? "Slave has a working right eye." : "",
+					implant: s => {
+						eyeSurgery(s, "right", "normal");
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 10, surgeryType: "unblind",
+					canImplant: s => (getBestVision(s) === 0 && getRightEyeType(s) !== 2),
+					implantError: () => "",
+					implant: s => {
+						eyeSurgery(s, "right", "normal");
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Replace", tooltip: "replace the existing ocular implant with an organic eye",
+					healthImpact: 20, surgeryType: "newEyes", autoImplant: false,
+					canImplant: s => (getRightEyeType(s) === 2),
+					implantError: () => "",
+					implant: s => {
+						eyeSurgery(s, "right", "normal");
+					}
+				})
+			]
+		})],
+	["ears",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Normal Ears", cost: 1000, time: 2,
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Attach", healthImpact: 15, surgeryType: "earMinor",
+					canImplant: s => (s.earShape === "none"),
+					implantError: () => "This slave already has ears.",
+					implant: s => {
+						s.earShape = "normal";
+						if (s.hears === -1) {
+							s.hears = 0;
+						}
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Replace", tooltip: "replace current ears with normal human ears",
+					healthImpact: 20, surgeryType: "earMinor", autoImplant: false,
+					canImplant: s => (s.earShape !== "normal"),
+					implantError: () => "This slave already has normal ears.",
+					implant: s => {
+						s.earShape = "normal";
+					}
+				})
+			]
+		})],
+	["topEars",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Top Ears", cost: 1000, time: 2,
+			canGrow: () => (V.surgeryUpgrade >= 1),
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Attach", healthImpact: 10, surgeryType: "earMinor",
+					canImplant: s => (s.earT === "none"),
+					implantError: () => "This slave already has ears at the top of the head.",
+					implant: s => {
+						s.earT = "normal";
+						s.earTColor = "hairless";
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Replace", tooltip: "replace current top ears with normal ears",
+					healthImpact: 20, surgeryType: "earMinor", autoImplant: false,
+					canImplant: s => (s.earT !== "normal"),
+					implantError: () => "This slave already has normal ears at the top of the head.",
+					implant: s => {
+						s.earT = "normal";
+						s.earTColor = "hairless";
+					}
+				})
+			]
+		})],
+	["cochleae",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Cochleae", cost: 8000, time: 6,
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 20, surgeryType: "undeafen",
+					canImplant: s => (s.hears <= -2 && s.earImplant === 0),
+					implantError: () => "This slave already has working ears.",
+					implant: s => {
+						s.hears = 0;
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Replace", tooltip: "remove cochlear implants before implanting organic cochleae",
+					healthImpact: 20, surgeryType: "newEars", autoImplant: false,
+					canImplant: s => (s.earImplant === 1),
+					implantError: () => "",
+					implant: s => {
+						s.hears = 0;
+						s.earImplant = 0;
+					}
+				})
+			]
+		})],
+	["voicebox",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Vocal Cords", cost: 5000, time: 5,
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Implant", healthImpact: 10, surgeryType: "restoreVoice",
+					canImplant: s => (s.voice === 0 && s.electrolarynx === 0),
+					implantError: () => "This slave is not mute.",
+					implant: s => {
+						if (s.ovaries === 1 && s.hormoneBalance >= 200) {
+							s.voice = 3;
+						} else if (s.balls > 0 || s.hormoneBalance < -20) {
+							s.voice = 1;
+						} else {
+							s.voice = 2;
+						}
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Replace", tooltip: "remove electrolarynx and implant organic vocal cords",
+					healthImpact: 20, surgeryType: "newVoice", autoImplant: false,
+					canImplant: s => (s.electrolarynx === 1),
+					implantError: () => "",
+					implant: s => {
+						s.electrolarynx = 0;
+						if (s.ovaries === 1 && s.hormoneBalance >= 200) {
+							s.voice = 3;
+						} else if (s.balls > 0 || s.hormoneBalance < -20) {
+							s.voice = 1;
+						} else {
+							s.voice = 2;
+						}
+					}
+				})
+			]
+		})],
+	["hair",
+		new App.Medicine.OrganFarm.Organ({
+			name: "Hair Follicles", cost: 500, time: 2, displayMultipleActions: true,
+			actions: [
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Scalp", healthImpact: 10, surgeryType: "restoreHairHead",
+					canImplant: s => (s.bald !== 0),
+					implantError: () => "This slave already has hair.",
+					implant: s => {
+						s.bald = 0;
+						s.hLength = 1;
+						s.hStyle = "neat";
+						s.hColor = getGeneticHairColor(s);
+					}
+				}),
+				/* So apparently hair is tracked via the .earTColor variable with no differential between possible hair origin. Not worth the variable, currently.
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Ears", healthImpact: 5,
+					surgeryType: "addHairEarsH", autoImplant: false,
+					canImplant: s => (s.earTShape !== "normal"),
+					implantError: "",
+					implant: s => {
+						s.earTColor = getGeneticHairColor(s);
+					}
+				}),
+				*/
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Brow", healthImpact: 5,
+					surgeryType: "restoreHairBrow", autoImplant: false,
+					canImplant: s => (s.eyebrowHStyle === "bald"),
+					implantError: () => "",
+					implant: s => {
+						s.eyebrowHStyle = "natural";
+						s.eyebrowFullness = "natural";
+						s.eyebrowHColor = getGeneticHairColor(s);
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Axillary", healthImpact: 5,
+					surgeryType: "restoreHairPits", autoImplant: false,
+					canImplant: s => (s.underArmHStyle === "bald" || s.underArmHStyle === "hairless"),
+					implantError: () => "",
+					implant: s => {
+						s.underArmHStyle = "bushy";
+						s.underArmHColor = getGeneticHairColor(s);
+					}
+				}),
+				new App.Medicine.OrganFarm.OrganImplantAction({
+					name: "Pubic", healthImpact: 5,
+					surgeryType: "restoreHairPubes", autoImplant: false,
+					canImplant: s => (s.pubicHStyle === "bald" || s.pubicHStyle === "hairless"),
+					implantError: () => "",
+					implant: s => {
+						s.pubicHStyle = "very bushy";
+						s.pubicHColor = getGeneticHairColor(s);
+					}
+				})
+			]
+		})],
+	["mpreg",
+		new App.Medicine.OrganFarm.AnalWomb({
+			name: "Anal womb and ovaries", eggType: "human", pregData: "human",
+		})],
+	["mpregPig",
+		new App.Medicine.OrganFarm.AnalWomb({
+			name: "Anal pig womb and ovaries", eggType: "pig", pregData: "pig",
+		})],
+	["mpregDog",
+		new App.Medicine.OrganFarm.AnalWomb({
+			name: "Anal dog womb and ovaries", eggType: "dog", pregData: "canineM",
+		})],
+	["mpregHorse",
+		new App.Medicine.OrganFarm.AnalWomb({
+			name: "Anal horse womb and ovaries", eggType: "horse", pregData: "equine",
+		})],
+	["mpregCow",
+		new App.Medicine.OrganFarm.AnalWomb({
+			name: "Anal cow womb and ovaries", eggType: "cow", pregData: "cow",
+		})],
+]);
diff --git a/src/interaction/multiImplant.js b/src/interaction/multiImplant.js
index d37d59fcfd3..be65676c7da 100644
--- a/src/interaction/multiImplant.js
+++ b/src/interaction/multiImplant.js
@@ -30,9 +30,9 @@ App.UI.multiImplant = function() {
 		App.UI.DOM.appendNewElement("h2", frag, slave.slaveName);
 
 		for (let j = 0; j < sortedOrgans.length; j++) {
-			App.UI.DOM.appendNewElement("h3", frag, F.Organs[sortedOrgans[j]].name);
+			App.UI.DOM.appendNewElement("h3", frag, F.Organs.get(sortedOrgans[j]).name);
 
-			let actions = F.Organs[sortedOrgans[j]].implantActions;
+			let actions = F.Organs.get(sortedOrgans[j]).implantActions;
 			let manual = false, success = false, cancel = false;
 			for (let k = 0; k < actions.length; k++) {
 				if (!actions[k].autoImplant) {
@@ -58,7 +58,7 @@ App.UI.multiImplant = function() {
 			}
 			if (cancel) { break; }
 			if (!success && manual) {
-				App.UI.Dom.appendNewElement("div", frag, `Cannot implant ${F.Organs[sortedOrgans[j]].name.toLowerCase()} automatically, try implanting manually in the remote surgery.`, "note");
+				App.UI.Dom.appendNewElement("div", frag, `Cannot implant ${F.Organs.get(sortedOrgans[j]).name.toLowerCase()} automatically, try implanting manually in the remote surgery.`, "note");
 			}
 		}
 	}
diff --git a/src/npc/surgery/organFarm.js b/src/npc/surgery/organFarm.js
index b5f8925104a..80536aa8b0d 100644
--- a/src/npc/surgery/organFarm.js
+++ b/src/npc/surgery/organFarm.js
@@ -3,12 +3,11 @@
  * @returns {string}
  */
 App.Medicine.OrganFarm.growActions = function(slave) {
-	const organOrder = App.Medicine.OrganFarm.organDisplayOrder;
 	const O = App.Medicine.OrganFarm.Organs;
 
 	// find already being grown/ready to implant organs
 	const slaveOrgans = {};
-	organOrder.forEach(organ => slaveOrgans[organ] = 0);
+	O.forEach((organ, key) => slaveOrgans[key] = 0);
 	V.completedOrgans.forEach(organ => {
 		if (organ.ID === slave.ID) {
 			slaveOrgans[organ.type] = -1;
@@ -35,22 +34,21 @@ App.Medicine.OrganFarm.growActions = function(slave) {
 	// create entries for each organ
 	let grow = "";
 	let wait = [];
-	for (const organId of organOrder) {
-		if (slaveOrgans[organId] === 0) {
-			const organ = O[organId];
+	O.forEach((organ, key) => {
+		if (slaveOrgans[key] === 0) {
 			if (organ.canGrow(slave)) {
-				grow += `<div>${App.UI.link(organ.name, App.Medicine.OrganFarm.growOrgan, [slave, organId], "Remote Surgery")}</div>`;
+				grow += `<div>${App.UI.link(organ.name, App.Medicine.OrganFarm.growOrgan, [slave, key], "Remote Surgery")}</div>`;
 				const tooltip = typeof organ.tooltip === "string" ? organ.tooltip : organ.tooltip(slave);
 				grow += `<div class="detail">Costs ${cashFormat(organ.cost)}${tooltip !== "" ? ` and ${tooltip}` : ""}.</div>`;
 			}
-		} else if (slaveOrgans[organId] > 0) {
+		} else if (slaveOrgans[key] > 0) {
 			// in growth organs at the end of the list
 			wait.push({
-				time: slaveOrgans[organId],
-				text: `${His} ${O[organId].name.toLowerCase()} will be ready for implantation in ${weeksLeft(slaveOrgans[organId])} weeks.`
+				time: slaveOrgans[key],
+				text: `${His} ${organ.name.toLowerCase()} will be ready for implantation in ${weeksLeft(slaveOrgans[key])} weeks.`
 			});
 		}
-	}
+	});
 
 	// put everything in one string
 	let r = "";
@@ -73,7 +71,7 @@ App.Medicine.OrganFarm.growActions = function(slave) {
  * @param {string} organType
  */
 App.Medicine.OrganFarm.growOrgan = function(slave, organType) {
-	const organ = App.Medicine.OrganFarm.Organs[organType];
+	const organ = App.Medicine.OrganFarm.Organs.get(organType);
 
 	V.organs.push({type: organType, weeksToCompletion: organ.time, ID: slave.ID});
 
@@ -85,7 +83,7 @@ App.Medicine.OrganFarm.growOrgan = function(slave, organType) {
  * @param {string} organType
  */
 App.Medicine.OrganFarm.growIncubatorOrgan = function(slave, organType) {
-	const organ = App.Medicine.OrganFarm.Organs[organType];
+	const organ = App.Medicine.OrganFarm.Organs.get(organType);
 
 	V.incubatorOrgans.push({type: organType, weeksToCompletion: organ.time, ID: slave.ID});
 
@@ -105,11 +103,11 @@ App.Medicine.OrganFarm.implantActions = function(slave) {
 	grid.classList.add("grid-2columns-auto");
 
 	for (const organ of slaveOrgans) {
-		App.UI.DOM.appendNewElement("div", grid, F.Organs[organ.type].name);
+		App.UI.DOM.appendNewElement("div", grid, F.Organs.get(organ.type).name);
 
 		let links = [];
-		for (let i = 0; i < F.Organs[organ.type].implantActions.length; i++) {
-			const action = F.Organs[organ.type].implantActions[i];
+		for (let i = 0; i < F.Organs.get(organ.type).implantActions.length; i++) {
+			const action = F.Organs.get(organ.type).implantActions[i];
 			if (action.canImplant(slave)) {
 				const link = App.UI.DOM.link(
 					action.name,
@@ -126,7 +124,7 @@ App.Medicine.OrganFarm.implantActions = function(slave) {
 					link.classList.add("hasTooltip");
 				}
 				links.push(link);
-				if (!F.Organs[organ.type].displayMultipleActions) {
+				if (!F.Organs.get(organ.type).displayMultipleActions) {
 					break; // there can only be one implant action
 				}
 			} else {
@@ -161,7 +159,7 @@ App.Medicine.OrganFarm.implantActions = function(slave) {
  * @param {number} actionIndex
  */
 App.Medicine.OrganFarm.implant = function(slave, type, actionIndex) {
-	const A = App.Medicine.OrganFarm.Organs[type].implantActions[actionIndex];
+	const A = App.Medicine.OrganFarm.Organs.get(type).implantActions[actionIndex];
 
 	A.implant(slave);
 	surgeryDamage(slave, A.healthImpact);
@@ -201,10 +199,10 @@ App.Medicine.OrganFarm.getSortedOrgans = function(slave) {
 			organs.push(organ.type);
 		}
 	});
-	organs.forEach(o => {
-		F.Organs[o].dependencies.forEach(d => {
-			if (organs.includes(d)) { /* inefficient, is there a better way? */
-				dependencies.push([d, o]);
+	organs.forEach(organKey => {
+		F.Organs.get(organKey).dependencies.forEach(dependencyKey => {
+			if (organs.includes(dependencyKey)) { /* inefficient, is there a better way? */
+				dependencies.push([dependencyKey, organKey]);
 			}
 		});
 	});
@@ -269,7 +267,7 @@ App.Medicine.OrganFarm.currentlyGrowing = function() {
 	V.organs.forEach(o => {
 		const slave = getSlave(o.ID);
 		if (slave !== undefined) {
-			growLines.push(`${slave.slaveName}'s ${App.Medicine.OrganFarm.Organs[o.type].name}, ${
+			growLines.push(`${slave.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}, ${
 				weeksToCompletion(o.weeksToCompletion)} week(s) left.`);
 		} else {
 			growLines.push(`<span class="error">ERROR: No slave with ID ${o.ID} found.</span>`);
@@ -279,9 +277,9 @@ App.Medicine.OrganFarm.currentlyGrowing = function() {
 		const tank = V.tanks.find((t) => t.ID === o.ID);
 		if (tank !== undefined) {
 			if (o.weeksToCompletion <= 0) {
-				finishLines.push(`${tank.slaveName}'s ${App.Medicine.OrganFarm.Organs[o.type].name}.`);
+				finishLines.push(`${tank.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}.`);
 			} else {
-				growLines.push(`${tank.slaveName}'s ${App.Medicine.OrganFarm.Organs[o.type].name}, ${
+				growLines.push(`${tank.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}, ${
 					weeksToCompletion(o.weeksToCompletion)} week(s) left.`);
 			}
 		} else {
@@ -292,7 +290,7 @@ App.Medicine.OrganFarm.currentlyGrowing = function() {
 	V.completedOrgans.forEach(o => {
 		const slave = getSlave(o.ID);
 		if (slave !== undefined) {
-			finishLines.push(`${slave.slaveName}'s ${App.Medicine.OrganFarm.Organs[o.type].name}.`);
+			finishLines.push(`${slave.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}.`);
 		} else {
 			finishLines.push(`<span class="error">ERROR: No slave with ID ${o.ID} found.</span>`);
 		}
diff --git a/src/npc/surgery/organs.js b/src/npc/surgery/organs.js
deleted file mode 100644
index 1d3fe6ac61f..00000000000
--- a/src/npc/surgery/organs.js
+++ /dev/null
@@ -1,442 +0,0 @@
-/**
- * Organs will usually be displayed in this order.
- * If an organ is not part of this array, it will be unreachable.
- *
- * @type {string[]}
- */
-App.Medicine.OrganFarm.organDisplayOrder = ["penis", "testicles", "scrotum", "pigTesticles", "dogTesticles", "horseTesticles", "cowTesticles", "foreskin", "prostate", "ovaries", "asexualReproOvaries", "pigOvaries", "dogOvaries", "horseOvaries", "cowOvaries", "freshOvaries", "leftEye", "rightEye", "ears", "topEars", "cochleae", "voicebox", "hair", "mpreg", "mpregPig", "mpregDog", "mpregHorse", "mpregCow"];
-
-App.Medicine.OrganFarm.init = function() {
-	new App.Medicine.OrganFarm.Organ({
-		type: "penis", name: "Penis", cost: 5000, time: 5,
-		canGrow: () => (V.seeDicks !== 0 || V.makeDicks === 1),
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 20, surgeryType: "addDick",
-				canImplant: slave => (slave.dick <= 0),
-				implantError: () => "this slave already has a penis",
-				implant: slave => {
-					if (slave.prostate === 0) {
-						slave.prostate = 1;
-					}
-					slave.dick = 2;
-					slave.clit = 0;
-					slave.foreskin = slave.dick;
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "foreskin", name: "Foreskin", cost: 2500, time: 5,
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Graft on", healthImpact: 10, surgeryType: "addForeskin",
-				canImplant: slave => (slave.foreskin <= 0),
-				implantError: slave => `This slave already has a ${slave.dick > 0 ? "foreskin" : "clitoral hood"}.`,
-				implant: slave => {
-					if (slave.dick > 0) {
-						slave.foreskin = slave.dick;
-					} else if (slave.clit > 0) {
-						slave.foreskin = slave.clit;
-					} else {
-						slave.foreskin = 1;
-					}
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Testicles({
-		type: "testicles", name: "Testicles", ballType: "human"
-	});
-	new App.Medicine.OrganFarm.Testicles({
-		type: "pigTesticles", name: "Pig testicles", ballType: "pig"
-	});
-	new App.Medicine.OrganFarm.Testicles({
-		type: "dogTesticles", name: "Dog testicles", ballType: "dog"
-	});
-	new App.Medicine.OrganFarm.Testicles({
-		type: "horseTesticles", name: "Horse testicles", ballType: "horse"
-	});
-	new App.Medicine.OrganFarm.Testicles({
-		type: "cowTesticles", name: "Cow testicles", ballType: "cow"
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "scrotum", name: "Scrotum", tooltip: "requires balls for successful implantation", cost: 2500, time: 5,
-		dependencies: ["testicles", "pigTesticles", "dogTesticles", "horseTesticles", "cowTesticles"],
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Graft on", healthImpact: 10, surgeryType: "addScrotum",
-				canImplant: slave => (slave.scrotum <= 0 && slave.balls > 0),
-				implantError: slave => (slave.scrotum > 0) ? "This slave already has a scrotum." : "This slave lacks the balls necessary to accept a scrotum.",
-				implant: slave => {
-					slave.scrotum = slave.balls;
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Ovaries({
-		type: "ovaries", name: "Ovaries", eggType: "human", pregData: "human"
-	});
-	new App.Medicine.OrganFarm.Ovaries({
-		type: "pigOvaries", name: "Pig ovaries", eggType: "pig", pregData: "pig"
-	});
-	new App.Medicine.OrganFarm.Ovaries({
-		type: "dogOvaries",
-		name: "Dog ovaries",
-		eggType: "dog",
-		pregData: "canineM",
-	});
-	new App.Medicine.OrganFarm.Ovaries({
-		type: "horseOvaries",
-		name: "Horse ovaries",
-		eggType: "horse",
-		pregData: "equine",
-	});
-	new App.Medicine.OrganFarm.Ovaries({
-		type: "cowOvaries", name: "Cow ovaries", eggType: "cow", pregData: "cow"
-	});
-
-	new App.Medicine.OrganFarm.AnalWomb({
-		type: "mpreg",
-		name: "Anal womb and ovaries",
-		eggType: "human",
-		pregData: "human",
-	});
-	new App.Medicine.OrganFarm.AnalWomb({
-		type: "mpregPig",
-		name: "Anal pig womb and ovaries",
-		eggType: "pig",
-		pregData: "pig",
-	});
-	new App.Medicine.OrganFarm.AnalWomb({
-		type: "mpregDog",
-		name: "Anal dog womb and ovaries",
-		eggType: "dog",
-		pregData: "canineM",
-	});
-	new App.Medicine.OrganFarm.AnalWomb({
-		type: "mpregHorse",
-		name: "Anal horse womb and ovaries",
-		eggType: "horse",
-		pregData: "equine",
-	});
-	new App.Medicine.OrganFarm.AnalWomb({
-		type: "mpregCow",
-		name: "Anal cow womb and ovaries",
-		eggType: "cow",
-		pregData: "cow",
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "freshOvaries", name: "Younger Ovaries",
-		tooltip: "requires a womb for successful implantation",
-		cost: 10000, time: 10,
-		canGrow: () => (V.youngerOvaries === 1),
-		dependencies: ["ovaries", "pigOvaries", "dogOvaries", "horseOvaries", "cowOvaries", "mpreg", "mpregPig", "mpregDog", "mpregHorse", "mpregCow"],
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 20, surgeryType: "freshOvaries",
-				canImplant: s => ((s.mpreg !== 0 || s.ovaries !== 0) && s.bellyImplant === -1 && s.physicalAge < 70),
-				implantError: s => (s.physicalAge >= 70) ? "This slave's body is too old to handle pregnancy." : "This slave lacks a viable womb.",
-				implant: s => {
-					if (s.ovaryAge >= 47) {
-						s.ovaryAge = 45;
-					} else {
-						s.ovaryAge = -2; // It shouldn't matter if this goes negative as it is just a signal for menopause to occur.
-					}
-					if (s.preg < 0) {
-						s.preg = 0;
-					}
-					if (s.pubertyXX === 0 && s.physicalAge >= V.fertilityAge) {
-						if (V.precociousPuberty === 1) {
-							s.pubertyAgeXX = s.physicalAge + 1;
-						} else {
-							s.pubertyXX = 1;
-						}
-					}
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "asexualReproOvaries", name: "Asexual reproduction modification",
-		tooltip: "requires existing ovaries for successful implantation",
-		cost: 10000, time: 10,
-		canGrow: () => (V.asexualReproduction === 1),
-		dependencies: ["ovaries", "pigOvaries", "dogOvaries", "horseOvaries", "cowOvaries", "mpreg", "mpregPig", "mpregDog", "mpregHorse", "mpregCow"],
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 20, surgeryType: "asexualReproOvaries",
-				canImplant: s => (s.mpreg !== 0 || s.ovaries !== 0),
-				implantError: () => "This slave lacks ovaries.",
-				implant: s => {
-					if (s.preg < 0) {
-						s.preg = 0;
-					}
-					s.eggType = "human";
-					s.pregData = clone(setup.pregData.human);
-					if (s.pubertyXX === 0 && s.physicalAge >= V.fertilityAge) {
-						if (V.precociousPuberty === 1) {
-							s.pubertyAgeXX = s.physicalAge + 1;
-						} else {
-							s.pubertyXX = 1;
-						}
-					}
-					s.ovaImplant = "asexual";
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "prostate", name: "Prostate", cost: 5000, time: 5,
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 20, surgeryType: "addProstate",
-				canImplant: s => (s.prostate === 0),
-				implantError: () => "This slave already has a prostate.",
-				implant: s => {
-					s.prostate = 1;
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "leftEye", name: "Left Eye", cost: 5000, time: 10,
-		tooltip: s => getLeftEyeVision(s) === 2 ? "would not improve this slave" : "",
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 10, surgeryType: "newEyes",
-				canImplant: s => (getLeftEyeVision(s) === 0 && getBestVision(s) !== 0 && getLeftEyeType(s) !== 2),
-				implantError: s => getLeftEyeVision(s) !== 0 ? "Slave has a working left eye." : "",
-				implant: s => {
-					eyeSurgery(s, "left", "normal");
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 10, surgeryType: "unblind",
-				canImplant: s => (getBestVision(s) === 0 && getLeftEyeType(s) !== 2),
-				implantError: () => "",
-				implant: s => {
-					eyeSurgery(s, "left", "normal");
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Replace", tooltip: "replace the existing ocular implant with an organic eye",
-				healthImpact: 10, surgeryType: "newEyes", autoImplant: false,
-				canImplant: s => (getLeftEyeType(s) === 2),
-				implantError: () => "",
-				implant: s => {
-					eyeSurgery(s, "left", "normal");
-				}
-			})
-		]
-	});
-	new App.Medicine.OrganFarm.Organ({
-		type: "rightEye", name: "Right Eye", cost: 5000, time: 10,
-		tooltip: s => getRightEyeVision(s) === 2 ? "would not improve this slave" : "",
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 10, surgeryType: "newEyes",
-				canImplant: s => (getRightEyeVision(s) === 0 && getBestVision(s) !== 0 && getRightEyeType(s) !== 2),
-				implantError: s => getRightEyeVision(s) !== 0 ? "Slave has a working right eye." : "",
-				implant: s => {
-					eyeSurgery(s, "right", "normal");
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 10, surgeryType: "unblind",
-				canImplant: s => (getBestVision(s) === 0 && getRightEyeType(s) !== 2),
-				implantError: () => "",
-				implant: s => {
-					eyeSurgery(s, "right", "normal");
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Replace", tooltip: "replace the existing ocular implant with an organic eye",
-				healthImpact: 20, surgeryType: "newEyes", autoImplant: false,
-				canImplant: s => (getRightEyeType(s) === 2),
-				implantError: () => "",
-				implant: s => {
-					eyeSurgery(s, "right", "normal");
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "ears", name: "Normal Ears", cost: 1000, time: 2,
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Attach", healthImpact: 15, surgeryType: "earMinor",
-				canImplant: s => (s.earShape === "none"),
-				implantError: () => "This slave already has ears.",
-				implant: s => {
-					s.earShape = "normal";
-					if (s.hears === -1) {
-						s.hears = 0;
-					}
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Replace", tooltip: "replace current ears with normal human ears",
-				healthImpact: 20, surgeryType: "earMinor", autoImplant: false,
-				canImplant: s => (s.earShape !== "normal"),
-				implantError: () => "This slave already has normal ears.",
-				implant: s => {
-					s.earShape = "normal";
-				}
-			})
-		]
-	});
-	new App.Medicine.OrganFarm.Organ({
-		type: "topEars", name: "Top Ears", cost: 1000, time: 2,
-		canGrow: () => (V.surgeryUpgrade >= 1),
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Attach", healthImpact: 10, surgeryType: "earMinor",
-				canImplant: s => (s.earT === "none"),
-				implantError: () => "This slave already has ears at the top of the head.",
-				implant: s => {
-					s.earT = "normal";
-					s.earTColor = "hairless";
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Replace", tooltip: "replace current top ears with normal ears",
-				healthImpact: 20, surgeryType: "earMinor", autoImplant: false,
-				canImplant: s => (s.earT !== "normal"),
-				implantError: () => "This slave already has normal ears at the top of the head.",
-				implant: s => {
-					s.earT = "normal";
-					s.earTColor = "hairless";
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "cochleae", name: "Cochleae", cost: 8000, time: 6,
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 20, surgeryType: "undeafen",
-				canImplant: s => (s.hears <= -2 && s.earImplant === 0),
-				implantError: () => "This slave already has working ears.",
-				implant: s => {
-					s.hears = 0;
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Replace", tooltip: "remove cochlear implants before implanting organic cochleae",
-				healthImpact: 20, surgeryType: "newEars", autoImplant: false,
-				canImplant: s => (s.earImplant === 1),
-				implantError: () => "",
-				implant: s => {
-					s.hears = 0;
-					s.earImplant = 0;
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "voicebox", name: "Vocal Cords", cost: 5000, time: 5,
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Implant", healthImpact: 10, surgeryType: "restoreVoice",
-				canImplant: s => (s.voice === 0 && s.electrolarynx === 0),
-				implantError: () => "This slave is not mute.",
-				implant: s => {
-					if (s.ovaries === 1 && s.hormoneBalance >= 200) {
-						s.voice = 3;
-					} else if (s.balls > 0 || s.hormoneBalance < -20) {
-						s.voice = 1;
-					} else {
-						s.voice = 2;
-					}
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Replace", tooltip: "remove electrolarynx and implant organic vocal cords",
-				healthImpact: 20, surgeryType: "newVoice", autoImplant: false,
-				canImplant: s => (s.electrolarynx === 1),
-				implantError: () => "",
-				implant: s => {
-					s.electrolarynx = 0;
-					if (s.ovaries === 1 && s.hormoneBalance >= 200) {
-						s.voice = 3;
-					} else if (s.balls > 0 || s.hormoneBalance < -20) {
-						s.voice = 1;
-					} else {
-						s.voice = 2;
-					}
-				}
-			})
-		]
-	});
-
-	new App.Medicine.OrganFarm.Organ({
-		type: "hair", name: "Hair Follicles", cost: 500, time: 2, displayMultipleActions: true,
-		actions: [
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Scalp", healthImpact: 10, surgeryType: "restoreHairHead",
-				canImplant: s => (s.bald !== 0),
-				implantError: () => "This slave already has hair.",
-				implant: s => {
-					s.bald = 0;
-					s.hLength = 1;
-					s.hStyle = "neat";
-					s.hColor = getGeneticHairColor(s);
-				}
-			}),
-			/* So apparently hair is tracked via the .earTColor variable with no differential between possible hair origin. Not worth the variable, currently.
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Ears", healthImpact: 5,
-				surgeryType: "addHairEarsH", autoImplant: false,
-				canImplant: s => (s.earTShape !== "normal"),
-				implantError: "",
-				implant: s => {
-					s.earTColor = getGeneticHairColor(s);
-				}
-			}),
-			*/
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Brow", healthImpact: 5,
-				surgeryType: "restoreHairBrow", autoImplant: false,
-				canImplant: s => (s.eyebrowHStyle === "bald"),
-				implantError: () => "",
-				implant: s => {
-					s.eyebrowHStyle = "natural";
-					s.eyebrowFullness = "natural";
-					s.eyebrowHColor = getGeneticHairColor(s);
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Axillary", healthImpact: 5,
-				surgeryType: "restoreHairPits", autoImplant: false,
-				canImplant: s => (s.underArmHStyle === "bald" || s.underArmHStyle === "hairless"),
-				implantError: () => "",
-				implant: s => {
-					s.underArmHStyle = "bushy";
-					s.underArmHColor = getGeneticHairColor(s);
-				}
-			}),
-			new App.Medicine.OrganFarm.OrganImplantAction({
-				name: "Pubic", healthImpact: 5,
-				surgeryType: "restoreHairPubes", autoImplant: false,
-				canImplant: s => (s.pubicHStyle === "bald" || s.pubicHStyle === "hairless"),
-				implantError: () => "",
-				implant: s => {
-					s.pubicHStyle = "very bushy";
-					s.pubicHColor = getGeneticHairColor(s);
-				}
-			})
-		]
-	});
-};
diff --git a/src/zz1-last/init.js b/src/zz1-last/init.js
index 6e14d81e03b..4c7ae0dde77 100644
--- a/src/zz1-last/init.js
+++ b/src/zz1-last/init.js
@@ -1,4 +1,3 @@
-App.Medicine.OrganFarm.init();
 App.Art.cacheArtData();
 App.Corporate.Init();
 
-- 
GitLab