diff --git a/Source/Recipes/Install_Part/Recipe_InstallAnus.cs b/Source/Recipes/Install_Part/Recipe_InstallAnus.cs
index d0b54a94026fc39018ee925e03560b3a693e8f35..bca3e50c2feef32ae43b12002e5d3842fd496a0d 100644
--- a/Source/Recipes/Install_Part/Recipe_InstallAnus.cs
+++ b/Source/Recipes/Install_Part/Recipe_InstallAnus.cs
@@ -4,14 +4,13 @@ using Verse;
 
 namespace rjw
 {
-	public class Recipe_InstallAnus : Recipe_InstallPart
+	public class Recipe_InstallAnus : Recipe_InstallPrivates
 	{
 		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
 		{
-			bool blocked = Genital_Helper.anus_blocked(p) || xxx.is_slime(p);
-
-			foreach (var part in base.GetPartsToApplyOn(p, r))
-				if ((!blocked) && (part == xxx.anus))
+			var gen_blo = Genital_Helper.anus_blocked(p);
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+				if ((!gen_blo) || (part != xxx.anus))
 					yield return part;
 		}
 	}
diff --git a/Source/Recipes/Install_Part/Recipe_InstallBreasts.cs b/Source/Recipes/Install_Part/Recipe_InstallBreasts.cs
index 2259001b4bc0836a93bf455cd23a6408b95b37c6..23fd96757389ab0238610df308775ed9955e8b28 100644
--- a/Source/Recipes/Install_Part/Recipe_InstallBreasts.cs
+++ b/Source/Recipes/Install_Part/Recipe_InstallBreasts.cs
@@ -4,14 +4,13 @@ using Verse;
 
 namespace rjw
 {
-	public class Recipe_InstallBreasts : Recipe_InstallPart
+	public class Recipe_InstallBreasts : Recipe_InstallPrivates
 	{
 		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
 		{
-			bool blocked = Genital_Helper.breasts_blocked(p) || xxx.is_slime(p);
-
-			foreach (var part in base.GetPartsToApplyOn(p, r))
-				if ((!blocked) && (part == xxx.breasts))
+			var gen_blo = Genital_Helper.breasts_blocked(p);
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+				if ((!gen_blo) || (part != xxx.breasts))
 					yield return part;
 		}
 	}
diff --git a/Source/Recipes/Install_Part/Recipe_InstallGenitals.cs b/Source/Recipes/Install_Part/Recipe_InstallGenitals.cs
index 4b6eb63670731db73d10b9d6594986cb33ff85cc..01f732984079c668fef6271490d7760e2dd9a7be 100644
--- a/Source/Recipes/Install_Part/Recipe_InstallGenitals.cs
+++ b/Source/Recipes/Install_Part/Recipe_InstallGenitals.cs
@@ -4,15 +4,15 @@ using Verse;
 
 namespace rjw
 {
-	public class Recipe_InstallGenitals : Recipe_InstallPart
+	public class Recipe_InstallGenitals : Recipe_InstallPrivates
 	{
 		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
 		{
-			bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);
-
-			foreach (var part in base.GetPartsToApplyOn(p, r))
-				if ((!blocked) && (part == xxx.genitals))
+			var gen_blo = Genital_Helper.genitals_blocked(p);
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+				if ((!gen_blo) || (part != xxx.genitals))
 					yield return part;
+			
 		}
 	}
 }
\ No newline at end of file
diff --git a/Source/Recipes/Install_Part/Recipe_InstallPart.cs b/Source/Recipes/Install_Part/Recipe_InstallPart.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0aee5fb75217508dd9c59e63390b8c1b6862bbcc
--- /dev/null
+++ b/Source/Recipes/Install_Part/Recipe_InstallPart.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using RimWorld;
+using Verse;
+
+namespace rjw
+{
+	public class Recipe_InstallPart : rjw_CORE_EXPOSED.Recipe_InstallArtificialBodyPart
+	{
+		public virtual bool blocked(Pawn p)
+		{
+			return true;
+		}
+
+		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
+		{
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+			{
+				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked(p) && !xxx.is_slime(p))
+					yield return part;
+			}
+		}
+
+		public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List<Thing> ingredients, Bill bill) {
+			GenderHelper.Sex before = GenderHelper.GetSex(pawn);
+
+			base.ApplyOnPawn(pawn, part, billDoer, ingredients, bill);
+
+			GenderHelper.Sex after = GenderHelper.GetSex(pawn);
+
+			if (before!=after)
+				GenderHelper.ChangeSex(pawn, before, after);
+		}
+	}
+
+	public class Recipe_InstallGenitals : Recipe_InstallPart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.genitals_blocked(p));
+		}
+	}
+
+	public class Recipe_InstallBreasts : Recipe_InstallPart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.breasts_blocked(p));
+		}
+	}
+
+	public class Recipe_InstallAnus : Recipe_InstallPart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.anus_blocked(p));
+		}
+	}
+}
\ No newline at end of file
diff --git a/Source/Recipes/Install_Part/Recipe_InstallPrivates.cs b/Source/Recipes/Install_Part/Recipe_InstallPrivates.cs
deleted file mode 100644
index 2a32855ca3b9456a4804098581eb418f7875c1e3..0000000000000000000000000000000000000000
--- a/Source/Recipes/Install_Part/Recipe_InstallPrivates.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Collections.Generic;
-using RimWorld;
-using Verse;
-
-namespace rjw
-{
-	public class Recipe_InstallPrivates : rjw_CORE_EXPOSED.Recipe_InstallArtificialBodyPart
-	{
-		public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List<Thing> ingredients, Bill bill) {
-			GenderHelper.Sex before = GenderHelper.GetSex(pawn);
-
-			base.ApplyOnPawn(pawn, part, billDoer, ingredients, bill);
-
-			GenderHelper.Sex after = GenderHelper.GetSex(pawn);
-
-			if (before!=after)
-				GenderHelper.ChangeSex(pawn, before, after);
-		}
-	}
-}
\ No newline at end of file
diff --git a/Source/Recipes/Remove_Part/Recipe_RemoveAnus.cs b/Source/Recipes/Remove_Part/Recipe_RemoveAnus.cs
index 73be0269dba5d07d94cdeb2cbd9694d6846407d5..46c82fc7d7d020464d4d734329f3202afda9f910 100644
--- a/Source/Recipes/Remove_Part/Recipe_RemoveAnus.cs
+++ b/Source/Recipes/Remove_Part/Recipe_RemoveAnus.cs
@@ -12,8 +12,8 @@ namespace rjw
 			{
 				bool blocked = Genital_Helper.anus_blocked(p) || xxx.is_slime(p);
 
-				foreach (var part in p.health.hediffSet.GetNotMissingParts())
-					if (r.appliedOnFixedBodyParts.Contains(part.def) && (part == xxx.anus) && (!blocked))
+				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
+					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
 						yield return part;
 			}
 		}
diff --git a/Source/Recipes/Remove_Part/Recipe_RemoveBreasts.cs b/Source/Recipes/Remove_Part/Recipe_RemoveBreasts.cs
index f558d5e26517e1601dfa8640ae7058f612ac73a1..85a63103dc246f819e1dc845e212980f54297cd5 100644
--- a/Source/Recipes/Remove_Part/Recipe_RemoveBreasts.cs
+++ b/Source/Recipes/Remove_Part/Recipe_RemoveBreasts.cs
@@ -12,8 +12,8 @@ namespace rjw
 			{
 				bool blocked = Genital_Helper.breasts_blocked(p) || xxx.is_slime(p);
 
-				foreach (var part in p.health.hediffSet.GetNotMissingParts())
-					if (r.appliedOnFixedBodyParts.Contains(part.def) && (part == xxx.breasts) && (!blocked))
+				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
+					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
 						yield return part;
 			}
 		}
diff --git a/Source/Recipes/Remove_Part/Recipe_RemoveGenitals.cs b/Source/Recipes/Remove_Part/Recipe_RemoveGenitals.cs
index 0d440067fcac1ed72dcd91990d923bc3bf5c8daf..ea64f19d0b98bb1593262258baff6246da97fc96 100644
--- a/Source/Recipes/Remove_Part/Recipe_RemoveGenitals.cs
+++ b/Source/Recipes/Remove_Part/Recipe_RemoveGenitals.cs
@@ -12,8 +12,8 @@ namespace rjw
 			{
 				bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);
 
-				foreach (var part in p.health.hediffSet.GetNotMissingParts())
-					if (r.appliedOnFixedBodyParts.Contains(part.def) &&	(part == xxx.genitals) && (!blocked))
+				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
+					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
 						yield return part;
 			}
 		}
diff --git a/Source/Recipes/Remove_Part/Recipe_RemovePart.cs b/Source/Recipes/Remove_Part/Recipe_RemovePart.cs
index 23d2476d25ec683fc977a163e129d726ece9f2a2..c593e32c9bdfad315d449ed84eb0dee86cb2bb64 100644
--- a/Source/Recipes/Remove_Part/Recipe_RemovePart.cs
+++ b/Source/Recipes/Remove_Part/Recipe_RemovePart.cs
@@ -9,15 +9,29 @@ namespace rjw
 		// Quick and dirty method to guess whether the player is harvesting the genitals or amputating them
 		// due to infection. The core code can't do this properly because it considers the private part
 		// hediffs as "unclean".
+		public virtual bool blocked(Pawn p)
+		{
+			return true;
+		}
+
 		public bool is_harvest(Pawn p, BodyPartRecord part)
 		{
-			foreach (var hed in p.health.hediffSet.hediffs)
-				if ((hed.Part == part) && hed.def.isBad && (hed.Severity >= 0.70f))
+			foreach (Hediff hed in p.health.hediffSet.hediffs)
+				if ((hed.Part.def == part.def) && hed.def.isBad && (hed.Severity >= 0.70f))
 					return false;
 
 			return true;
 		}
 
+		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
+		{
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+			{
+				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked(p) && !xxx.is_slime(p))
+					yield return part;
+			}
+		}
+
 		public override void ApplyOnPawn(Pawn p, BodyPartRecord part, Pawn doer, List<Thing> ingredients, Bill bill)
 		{
 			var har = is_harvest(p, part);
@@ -38,4 +52,52 @@ namespace rjw
 			return recipe.label.CapitalizeFirst();
 		}
 	}
+	/*
+	public class Recipe_RemovePenis : Recipe_RemovePart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.genitals_blocked(p)
+				|| !(Genital_Helper.has_penis(p) 
+					&& Genital_Helper.has_penis_infertile(p) 
+					&& Genital_Helper.has_ovipositorF(p)));
+		}
+	}
+
+	public class Recipe_RemoveVagina : Recipe_RemovePart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.genitals_blocked(p)
+				|| !Genital_Helper.has_vagina(p));
+		}
+	}
+
+	public class Recipe_RemoveGenitals : Recipe_RemovePart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.genitals_blocked(p)
+				|| !Genital_Helper.has_genitals(p));
+		}
+	}
+
+	public class Recipe_RemoveBreasts : Recipe_RemovePart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.breasts_blocked(p)
+				|| !Genital_Helper.has_breasts(p));
+		}
+	}
+
+	public class Recipe_RemoveAnus : Recipe_RemovePart
+	{
+		public override bool blocked(Pawn p)
+		{
+			return (Genital_Helper.anus_blocked(p)
+				|| !Genital_Helper.has_anus(p));
+		}
+	}
+	*/
 }
\ No newline at end of file
diff --git a/Source/Recipes/Remove_Part/Recipe_RemovePenis.cs b/Source/Recipes/Remove_Part/Recipe_RemovePenis.cs
index c764976d00182aeee0eb8dba8a38aa781ef3d128..15965f47606e960a27796916184bc27dd6d83585 100644
--- a/Source/Recipes/Remove_Part/Recipe_RemovePenis.cs
+++ b/Source/Recipes/Remove_Part/Recipe_RemovePenis.cs
@@ -13,7 +13,7 @@ namespace rjw
 				bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);
 
 				foreach (var part in p.health.hediffSet.GetNotMissingParts())
-					if (r.appliedOnFixedBodyParts.Contains(part.def) && (part == xxx.genitals) && (!blocked))
+					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
 						yield return part;
 			}
 		}
diff --git a/Source/Recipes/Remove_Part/Recipe_RemoveVagina.cs b/Source/Recipes/Remove_Part/Recipe_RemoveVagina.cs
index 4f93e8b9e0d3f6ba3df6f54c864979876aca7763..bbde6947c741d0a60e6e085ba558cf422f737096 100644
--- a/Source/Recipes/Remove_Part/Recipe_RemoveVagina.cs
+++ b/Source/Recipes/Remove_Part/Recipe_RemoveVagina.cs
@@ -13,7 +13,7 @@ namespace rjw
 				bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);
 
 				foreach (var part in p.health.hediffSet.GetNotMissingParts())
-					if (r.appliedOnFixedBodyParts.Contains(part.def) && (part == xxx.genitals) && (!blocked))
+					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
 						yield return part;
 			}
 		}
diff --git a/Source/Recipes/Transgender/Recipe_MakeFutaF.cs b/Source/Recipes/Transgender/Recipe_MakeFutaF.cs
index 153029857b167b0a71351c932172d898231b0617..c25b3b1133e6ad24c4f601038561b6a6ced2b1dd 100644
--- a/Source/Recipes/Transgender/Recipe_MakeFutaF.cs
+++ b/Source/Recipes/Transgender/Recipe_MakeFutaF.cs
@@ -5,16 +5,15 @@ namespace rjw
 {
 	public class Recipe_MakeFutaF : Recipe_MakeFuta
 	{
-		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
+		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
 		{
-			bool blocked = Genital_Helper.genitals_blocked(pawn) || xxx.is_slime(pawn);
-			bool has_vag = Genital_Helper.has_vagina(pawn);
-			bool has_cock = Genital_Helper.has_penis(pawn) || Genital_Helper.has_penis_infertile(pawn) || Genital_Helper.has_ovipositorF(pawn);
+			bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);
+			bool has_vag = Genital_Helper.has_vagina(p);
+			bool has_cock = Genital_Helper.has_penis(p) || Genital_Helper.has_penis_infertile(p) || Genital_Helper.has_ovipositorF(p);
 			
-			foreach (var part in base.GetPartsToApplyOn(pawn, recipe))
-				if ((part == xxx.genitals) && (!blocked && (has_vag && !has_cock)))
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked && (has_vag && !has_cock))
 					yield return part;
-			
 		}
 	}
 }
\ No newline at end of file
diff --git a/Source/Recipes/Transgender/Recipe_MakeFutaM.cs b/Source/Recipes/Transgender/Recipe_MakeFutaM.cs
index eb69af42e33992f3cbf1f5b0973437ed8eee9f51..907964cf843464575a7fab7e94de73dd9e7843e1 100644
--- a/Source/Recipes/Transgender/Recipe_MakeFutaM.cs
+++ b/Source/Recipes/Transgender/Recipe_MakeFutaM.cs
@@ -5,16 +5,15 @@ namespace rjw
 {
 	public class Recipe_MakeFutaM : Recipe_MakeFuta
 	{
-		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
+		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
 		{
-			bool blocked = Genital_Helper.genitals_blocked(pawn) || xxx.is_slime(pawn);
-			bool has_vag = Genital_Helper.has_vagina(pawn);
-			bool has_cock = Genital_Helper.has_penis(pawn) || Genital_Helper.has_penis_infertile(pawn) || Genital_Helper.has_ovipositorF(pawn);
-			
-			foreach (var part in base.GetPartsToApplyOn(pawn, recipe))
-				if ((part == xxx.genitals) && (!blocked && (!has_vag && has_cock)))
-					yield return part;
+			bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);
+			bool has_vag = Genital_Helper.has_vagina(p);
+			bool has_cock = Genital_Helper.has_penis(p) || Genital_Helper.has_penis_infertile(p) || Genital_Helper.has_ovipositorF(p);
 			
+			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
+				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked && (!has_vag && has_cock))
+					yield return part;			
 		}
 	}
 }
\ No newline at end of file