code:
using System.Collections.Generic;
using RimWorld;
using Verse;
using System.Linq;
using System;

namespace rjw
{
	public class Recipe_GrowBreasts : Recipe_Surgery
	{
		public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List<Thing> ingredients, Bill bill)
		{
			if (billDoer != null)
			{
				if (CheckSurgeryFail(billDoer, pawn, ingredients, part, bill))
				{
					return;
				}
				TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[]
				{
					billDoer,
					pawn
				});
			}

			var oldBoobs = pawn.health.hediffSet.hediffs.FirstOrDefault(hediff => hediff.def == bill.recipe.removesHediff);
			var newBoobs = bill.recipe.addsHediff;
			var newSize = BreastSize_Helper.GetSize(newBoobs);

			GenderHelper.ChangeSex(pawn, () =>
			{
				BreastSize_Helper.HurtBreasts(pawn, part, 3 * (newSize - 1));
				if (pawn.health.hediffSet.PartIsMissing(part))
				{
					return;
				}
				if (oldBoobs != null)
				{
					pawn.health.RemoveHediff(oldBoobs);
				}
				pawn.health.AddHediff(newBoobs, part);
			});
		}

		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipeDef)
		{
			yield break;
			var chest = Genital_Helper.get_breastsBPR(pawn);

			if (pawn.health.hediffSet.PartIsMissing(chest)
				|| Genital_Helper.breasts_blocked(pawn))
			{
				yield break;
			}

			var old = recipeDef.removesHediff;
			if (old == null ? BreastSize_Helper.HasNipplesOnly(pawn, chest) : pawn.health.hediffSet.HasHediff(old, chest))
			{
				yield return chest;
			}
		}
	}
}


code:
using RimWorld;
using System.Collections.Generic;
using Verse;

namespace rjw
{
	/// <summary>
	/// Removes heddifs (restraints/cocoon)
	/// </summary>
	public class Recipe_RemoveRestraints : Recipe_RemoveHediff
	{
		public override bool AvailableOnNow(Thing pawn, BodyPartRecord part = null)
		{
			return true;
		}

		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
		{
			List<Hediff> allHediffs = pawn.health.hediffSet.hediffs;
			int i = 0;
			while (true)
			{
				if (i >= allHediffs.Count)
				{
					yield break;
				}
				if (allHediffs[i].def == recipe.removesHediff && allHediffs[i].Visible)
				{
					break;
				}
				i++;
			}

			yield return allHediffs[i].Part;
		}
	}
}

license: mit


code:
using System.Collections.Generic;
using RimWorld;
using Verse;
using System.Linq;
using System;

namespace rjw
{
	public class Recipe_ShrinkBreasts : Recipe_Surgery
	{
		public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List<Thing> ingredients, Bill bill)
		{
			if (billDoer != null)
			{
				if (CheckSurgeryFail(billDoer, pawn, ingredients, part, bill))
				{
					return;
				}
				TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[]
				{
					billDoer,
					pawn
				});
			}

			if (!BreastSize_Helper.TryGetBreastSize(pawn, out var oldSize))
			{
				throw new ApplicationException("Recipe_ShrinkBreasts could not find any breasts to shrink.");
			}

			var oldBoobs = pawn.health.hediffSet.GetFirstHediffOfDef(BreastSize_Helper.GetHediffDef(oldSize));
			var newSize = oldSize - 1;
			var newBoobs = BreastSize_Helper.GetHediffDef(newSize);

			// I can't figure out how to spawn a stack of 2 meat.
			for (var i = 0; i < 2; i++)
			{
				GenSpawn.Spawn(pawn.RaceProps.meatDef, billDoer.Position, billDoer.Map);
			}

			GenderHelper.ChangeSex(pawn, () =>
			{
				BreastSize_Helper.HurtBreasts(pawn, part, 5);
				if (pawn.health.hediffSet.PartIsMissing(part))
				{
					return;
				}
				pawn.health.RemoveHediff(oldBoobs);
				pawn.health.AddHediff(newBoobs, part);
			});
		}

		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipeDef)
		{
			yield break;
			var chest = Genital_Helper.get_breastsBPR(pawn);

			if (Genital_Helper.breasts_blocked(pawn))
			{
				yield break;
			}

			if (BreastSize_Helper.TryGetBreastSize(pawn, out var size)
				//&& size > BreastSize_Helper.GetSize(Genital_Helper.flat_breasts))
				)
			{
				yield return chest;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemoveAnus : Recipe_RemovePart
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			if (Genital_Helper.has_anus(p))
			{
				bool blocked = Genital_Helper.anus_blocked(p) || xxx.is_slime(p);//|| xxx.is_demon(p)

				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
						yield return part;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemoveBreasts : Recipe_RemovePart
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			if (Genital_Helper.has_breasts(p))
			{
				bool blocked = Genital_Helper.breasts_blocked(p) || xxx.is_slime(p);//|| xxx.is_demon(p)

				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
						yield return part;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemoveGenitals : Recipe_RemovePart
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			if (Genital_Helper.has_genitals(p))
			{
				bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p);//|| xxx.is_demon(p)

				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
						yield return part;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemovePart : rjw_CORE_EXPOSED.Recipe_RemoveBodyPart
	{
		// 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 override bool blocked(Pawn p)
		{
			return xxx.is_slime(p);//|| xxx.is_demon(p)
		}

		public bool is_harvest(Pawn p, BodyPartRecord part)
		{
			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))
					yield return part;
			}
		}

		public override void ApplyOnPawn(Pawn p, BodyPartRecord part, Pawn doer, List<Thing> ingredients, Bill bill)
		{
			var har = is_harvest(p, part);

			base.ApplyOnPawn(p, part, doer, ingredients, bill);

			if (har)
			{
				if (!p.Dead)
				{
					//Log.Message("alive harvest " + part);
					ThoughtUtility.GiveThoughtsForPawnOrganHarvested(p, doer);
				}
				else
				{
					//Log.Message("dead harvest " + part);
					ThoughtUtility.GiveThoughtsForPawnExecuted(p, doer, PawnExecutionKind.OrganHarvesting);
				}
			}
		}

		public override string GetLabelWhenUsedOn(Pawn p, BodyPartRecord part)
		{
			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));
		}
	}
	*/
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemovePenis : Recipe_RemovePart
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			if (Genital_Helper.has_penis(p) || Genital_Helper.has_penis_infertile(p) || Genital_Helper.has_ovipositorF(p))
			{
				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) && (!blocked))
						yield return part;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemoveUdder : Recipe_RemovePart
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{

			if (Genital_Helper.has_udder(p))
			{
				bool blocked = Genital_Helper.udder_blocked(p) || xxx.is_slime(p);//|| xxx.is_demon(p)

				foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts())
					if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked))
						yield return part;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_RemoveVagina : Recipe_RemovePart
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			if (Genital_Helper.has_vagina(p) )
			{
				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) && (!blocked))
						yield return part;
			}
		}
	}
}


code:
using System.Collections.Generic;
using RimWorld;
using Verse;

namespace rjw
{
	public class Recipe_MakeFuta : rjw_CORE_EXPOSED.Recipe_AddBodyPart
	{
		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);

			GenderHelper.ChangeSex(pawn, before, after);
		}
	}

	//Female to futa
	public class Recipe_MakeFutaF : Recipe_MakeFuta
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			var parts = p.GetGenitalsList();

			bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p); //|| xxx.is_demon(p);
			bool has_vag = Genital_Helper.has_vagina(p, parts);
			bool has_cock = Genital_Helper.has_male_bits(p, parts);

			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked && (has_vag && !has_cock))
					yield return part;
		}
	}

	//Male to futa
	public class Recipe_MakeFutaM : Recipe_MakeFuta
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			var parts = p.GetGenitalsList();

			bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p); //|| xxx.is_demon(p);
			bool has_vag = Genital_Helper.has_vagina(p, parts);
			bool has_cock = Genital_Helper.has_male_bits(p, parts);

			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked && (!has_vag && has_cock))
					yield return part;
		}
	}

	//TODO: maybe merge with above to make single recipe, but meh for now just copy-paste recipes or some filter to disable multiparts if normal part doesn't exist yet

	//add multi parts
	public class Recipe_AddMultiPart : Recipe_MakeFuta
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			//don't add artificial - peg, hydraulics, bionics, archo, ovi
			if (r.addsHediff.addedPartProps?.solid ?? false)
				yield break;

			//don't add if artificial parts present
			if (p.health.hediffSet.hediffs.Any((Hediff hed) =>
				(hed.Part != null) &&
				r.appliedOnFixedBodyParts.Contains(hed.Part.def) &&
				(hed.def.addedPartProps?.solid ?? false)))
				yield break;

			var parts = p.GetGenitalsList();

			//don't add if no ovi
			//if (Genital_Helper.has_ovipositorF(p, parts) || Genital_Helper.has_ovipositorM(p, parts))
			//	yield break;

			//don't add if same part type not present yet
			if (!Genital_Helper.has_vagina(p, parts) && r.defName.ToLower().Contains("vagina"))
				yield break;
			if (!Genital_Helper.has_penis_fertile(p, parts) && r.defName.ToLower().Contains("penis"))
				yield break;

			//cant install parts when part blocked, on slimes, on demons
			bool blocked = (xxx.is_slime(p) //|| xxx.is_demon(p)
				|| (Genital_Helper.genitals_blocked(p) && r.appliedOnFixedBodyParts.Contains(xxx.genitalsDef))
				|| (Genital_Helper.anus_blocked(p) && r.appliedOnFixedBodyParts.Contains(xxx.anusDef))
				|| (Genital_Helper.breasts_blocked(p) && r.appliedOnFixedBodyParts.Contains(xxx.breastsDef)));

			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked)
					yield return part;
		}
	}

	public class Recipe_AddSinglePart : Recipe_MakeFuta
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			//cant install parts when part blocked, on slimes, or when already has one
			bool blocked = xxx.is_slime(p) || p.health.hediffSet.HasHediff(r.addsHediff);

			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked)
					yield return part;
		}
	}

	public class Recipe_RemoveSinglePart : Recipe_MakeFuta
	{
		public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r)
		{
			//cant install parts when part blocked, on slimes, or when already has one
			bool blocked = xxx.is_slime(p) || !p.health.hediffSet.HasHediff(r.removesHediff);

			foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r))
				if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked)
					yield return part;
		}
	}
}


code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;

namespace rjw
{
	public class PawnRelationWorker_Child_Beast : PawnRelationWorker_Child
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isChildOf(other, me);
		}
	}

	public class PawnRelationWorker_Sibling_Beast : PawnRelationWorker_Sibling
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isSiblingOf(other, me);
		}
	}
	public class PawnRelationWorker_HalfSibling_Beast : PawnRelationWorker_HalfSibling
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isHalfSiblingOf(other, me);
		}
	}
	public class PawnRelationWorker_Grandparent_Beast : PawnRelationWorker_Grandparent
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGrandchildOf(me, other);
		}
	}
	public class PawnRelationWorker_Grandchild_Beast : PawnRelationWorker_Grandchild
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGrandparentOf(me, other);  //if other isGrandchildOf of me, me is their grandparent
		}
	}
	public class PawnRelationWorker_NephewOrNiece_Beast : PawnRelationWorker_NephewOrNiece
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isUncleOrAuntOf(me, other);
		}
	}
	public class PawnRelationWorker_UncleOrAunt_Beast : PawnRelationWorker_UncleOrAunt
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isNephewOrNieceOf(me, other);
		}
	}

	public class PawnRelationWorker_Cousin_Beast : PawnRelationWorker_Cousin
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isCousinOf(me, other);
		}
	}

	public class PawnRelationWorker_GreatGrandparent_Beast : PawnRelationWorker_GreatGrandparent
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGreatGrandChildOf(me, other);
		}
	}

	public class PawnRelationWorker_GreatGrandchild_Beast : PawnRelationWorker_GreatGrandchild
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGreatGrandparentOf(me, other);
		}
	}

	public class PawnRelationWorker_GranduncleOrGrandaunt_Beast : PawnRelationWorker_GranduncleOrGrandaunt
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGrandnephewOrGrandnieceOf(me, other);
		}
	}

	public class PawnRelationWorker_GrandnephewOrGrandniece_Beast : PawnRelationWorker_GrandnephewOrGrandniece
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGreatUncleOrAuntOf(me, other);
		}
	}

	public class PawnRelationWorker_CousinOnceRemoved_Beast : PawnRelationWorker_CousinOnceRemoved
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isCousinOnceRemovedOf(me, other);
		}
	}

	public class PawnRelationWorker_SecondCousin_Beast : PawnRelationWorker_SecondCousin
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isSecondCousinOf(me, other);
		}
	}
	/*
	public class PawnRelationWorker_Kin_Beast : PawnRelationWorker_Kin
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (!xxx.is_animal(other) || me == other)
			{
				return false;
			}

			if (base.InRelation(me, other) == true)
			{
				return true;
			}
			return false;
		}
	}
	*/
}


code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;

namespace rjw
{
	public class PawnRelationWorker_Child_Humanlike : PawnRelationWorker_Child
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			if (base.InRelation(me, other) == true)
			{
				return true;
			}
			return false;
		}
	}

	public class PawnRelationWorker_Sibling_Humanlike : PawnRelationWorker_Sibling
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			if (base.InRelation(me, other) == true)
			{
				return true;
			}
			return false;
		}
	}
	public class PawnRelationWorker_HalfSibling_Humanlike : PawnRelationWorker_HalfSibling
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isHalfSiblingOf(other, me);
		}
	}
	public class PawnRelationWorker_Grandparent_Humanlike : PawnRelationWorker_Grandparent
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGrandchildOf(me, other);
		}
	}
	public class PawnRelationWorker_Grandchild_Humanlike : PawnRelationWorker_Grandchild
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGrandparentOf(me, other);
		}
	}
	public class PawnRelationWorker_NephewOrNiece_Humanlike : PawnRelationWorker_NephewOrNiece
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isUncleOrAuntOf(me, other);
		}
	}
	public class PawnRelationWorker_UncleOrAunt_Humanlike : PawnRelationWorker_UncleOrAunt
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isNephewOrNieceOf(me, other);
		}
	}

	public class PawnRelationWorker_Cousin_Humanlike : PawnRelationWorker_Cousin
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isCousinOf(me, other);
		}
	}

	public class PawnRelationWorker_GreatGrandparent_Humanlike : PawnRelationWorker_GreatGrandparent
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGreatGrandChildOf(me, other);
		}
	}

	public class PawnRelationWorker_GreatGrandchild_Humanlike : PawnRelationWorker_GreatGrandchild
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGreatGrandparentOf(me, other);
		}
	}

	public class PawnRelationWorker_GranduncleOrGrandaunt_Humanlike : PawnRelationWorker_GranduncleOrGrandaunt
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGrandnephewOrGrandnieceOf(me, other);
		}
	}

	public class PawnRelationWorker_GrandnephewOrGrandniece_Humanlike : PawnRelationWorker_GrandnephewOrGrandniece
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isGreatUncleOrAuntOf(me, other);
		}
	}

	public class PawnRelationWorker_CousinOnceRemoved_Humanlike : PawnRelationWorker_CousinOnceRemoved
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isCousinOnceRemovedOf(me, other);
		}
	}

	public class PawnRelationWorker_SecondCousin_Humanlike : PawnRelationWorker_SecondCousin
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			return RelationChecker.isSecondCousinOf(me, other);
		}
	}

	public class PawnRelationWorker_Kin_Humanlike : PawnRelationWorker_Kin
	{
		public override bool InRelation(Pawn me, Pawn other)
		{
			if (xxx.is_animal(other) || me == other)
			{
				return false;
			}

			if (base.InRelation(me, other) == true)
			{
				return true;
			}
			return false;
		}
	}
}


code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;

namespace rjw
{
	/// <summary>
	/// Checks for relations, workaround for relation checks that rely on other relation checks, since the vanilla inRelation checks have been prefixed.
	///
	/// Return true if first pawn is specified relation of the second pawn
	///
	///  If "me" isRelationOf "other" return true
	/// </summary>
	///
	public static class RelationChecker
	{
		public static bool isChildOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if (me.GetMother() != other)
			{
				return me.GetFather() == other;
			}
			//else "other" is mother
			return true;
		}

		public static bool isSiblingOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if (me.GetMother() != null && me.GetFather() != null && me.GetMother() == other.GetMother() && me.GetFather() == other.GetFather())
			{
				return true;
			}
			return false;
		}

		public static bool isHalfSiblingOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if (isSiblingOf(me, other))
			{
				return false;
			}
			return ((me.GetMother() != null && me.GetMother() == other.GetMother()) || (me.GetFather() != null && me.GetFather() == other.GetFather()));
		}

		public static bool isAnySiblingOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if ((me.GetMother() != null && me.GetMother() == other.GetMother()) || (me.GetFather() != null && me.GetFather() == other.GetFather()))
			{
				return true;
			}
			return false;
		}

		public static bool isGrandchildOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if ((me.GetMother() != null && isChildOf(me.GetMother(), other)) || (me.GetFather() != null && isChildOf(me.GetFather(), other)))
			{
				return true;
			}
			return false;
		}

		public static bool isGrandparentOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if (isGrandchildOf(other, me))
			{
				return true;
			}
			return false;
		}

		public static bool isNephewOrNieceOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if ((me.GetMother() != null && (isAnySiblingOf(other, me.GetMother()))) || (me.GetFather() != null && (isAnySiblingOf(other, me.GetFather()))))
			{
				return true;
			}
			return false;
		}

		public static bool isUncleOrAuntOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if (isNephewOrNieceOf(other, me))
			{
				return true;
			}
			return false;
		}

		public static bool isCousinOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}

			if ((other.GetMother() != null && isNephewOrNieceOf(me, other.GetMother())) || (other.GetFather() != null && isNephewOrNieceOf(me, other.GetFather())))
			{
				return true;
			}
			return false;
		}

		public static bool isGreatGrandparentOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}

			return isGreatGrandChildOf(other, me);
		}

		public static bool isGreatGrandChildOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}

			if ((me.GetMother() != null && isGrandchildOf(me.GetMother(), other)) || (me.GetFather() != null && isGrandchildOf(me.GetFather(), other)))
			{
				return true;
			}
			return false;
		}

		public static bool isGreatUncleOrAuntOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}

			return isGrandnephewOrGrandnieceOf(other, me);
		}

		public static bool isGrandnephewOrGrandnieceOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}

			if ((me.GetMother() != null && isUncleOrAuntOf(other, me.GetMother())) || (me.GetFather() != null && isUncleOrAuntOf(other, me.GetFather())))
			{
				return true;
			}
			return false;
		}

		public static bool isCousinOnceRemovedOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			if ((other.GetMother() != null && isCousinOf(me, other.GetMother())) || (other.GetFather() != null && isCousinOf(me, other.GetFather())))
			{
				return true;
			}
			if ((other.GetMother() != null && isGrandnephewOrGrandnieceOf(me, other.GetMother())) || (other.GetFather() != null && isGrandnephewOrGrandnieceOf(me, other.GetFather())))
			{
				return true;
			}
			return false;
		}

		public static bool isSecondCousinOf(Pawn me, Pawn other)
		{
			if (me == null || me == other)
			{
				return false;
			}
			PawnRelationWorker worker = PawnRelationDefOf.GranduncleOrGrandaunt.Worker;
			Pawn mother = other.GetMother();
			if (mother != null && ((mother.GetMother() != null && isGrandnephewOrGrandnieceOf(me, mother.GetMother())) || (mother.GetFather() != null && isGrandnephewOrGrandnieceOf(me, mother.GetFather()))))
			{
				return true;
			}
			Pawn father = other.GetFather();
			if (father != null && ((father.GetMother() != null && isGrandnephewOrGrandnieceOf(me, father.GetMother())) || (father.GetFather() != null && isGrandnephewOrGrandnieceOf(me, father.GetFather()))))
			{
				return true;
			}
			return false;
		}
	}
}


code:
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{22F82FFF-8BD4-4CEE-9F22-C7DA71281E72}</ProjectGuid>
    <OutputType>Library</OutputType>
    <NoStandardLibraries>false</NoStandardLibraries>
    <AssemblyName>RJW</AssemblyName>
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <TargetFrameworkProfile />
    <ShouldCreateLogs>True</ShouldCreateLogs>
    <AdvancedSettingsExpanded>True</AdvancedSettingsExpanded>
    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
    <UpdateAssemblyFileVersion>True</UpdateAssemblyFileVersion>
    <UpdateAssemblyInfoVersion>True</UpdateAssemblyInfoVersion>
    <AssemblyVersionSettings>None.None.IncrementOnDemand.Increment</AssemblyVersionSettings>
    <AssemblyFileVersionSettings>None.None.IncrementOnDemand.None</AssemblyFileVersionSettings>
    <AssemblyInfoVersionSettings>None.None.IncrementOnDemand.None</AssemblyInfoVersionSettings>
    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
    <AssemblyVersion>1.6.0.493</AssemblyVersion>
    <LangVersion>10</LangVersion>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\Assemblies\</OutputPath>
    <DefineConstants>TRACE;DEBUG</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <FileAlignment>4096</FileAlignment>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>none</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\Assemblies\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>latest</LangVersion>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <!-- Set the `BENCHMARK` environment variable to "1" to enable benchmarking. -->
  <PropertyGroup Condition="'$(BENCHMARK)' == '1'">
    <DefineConstants>$(DefineConstants);BENCHMARK</DefineConstants>
  </PropertyGroup>
  <PropertyGroup>
    <RootNamespace>rjw</RootNamespace>
  </PropertyGroup>
  <Choose>
    <!-- Mod-folder Relative -->
    <When Condition="Exists('..\..\..\..\Mods')">
      <PropertyGroup>
        <RWPath>..\..\..\..</RWPath>
      </PropertyGroup>
    </When>
    <!-- Windows x86 -->
    <When Condition="Exists('C:\Program Files (x86)\Steam\steamapps\common\RimWorld')">
      <PropertyGroup>
        <RWPath>C:\Program Files (x86)\Steam\steamapps\common\RimWorld</RWPath>
      </PropertyGroup>
    </When>
    <!-- Windows x64 -->
    <When Condition="Exists('C:\Program Files\Steam\steamapps\common\RimWorld')">
      <PropertyGroup>
        <RWPath>C:\Program Files\Steam\steamapps\common\RimWorld</RWPath>
      </PropertyGroup>
    </When>
    <!-- Linux -->
    <When Condition="Exists('$(HOME)\.steam\steam')">
      <PropertyGroup>
        <RWPath>$(HOME)\.steam\steam\steamapps\common\RimWorld</RWPath>
      </PropertyGroup>
    </When>
    <!-- MacOS -->
    <When Condition="Exists('$(HOME)\Library\Application Support\Steam')">
      <PropertyGroup>
        <RWPath>$(HOME)\Library\Application Support\Steam\steamapps\common\RimWorld</RWPath>
      </PropertyGroup>
    </When>
    <!-- Fallback option: define the RIMWORLD environment variable, pointing to RimWorld's install folder -->
    <When Condition="Exists('$(RIMWORLD)')">
      <PropertyGroup>
        <RWPath>$(RIMWORLD)</RWPath>
      </PropertyGroup>
    </When>
  </Choose>
  <PropertyGroup>
    <ReferencePath>
      $(RWPath)\RimWorldWin_Data\Managed;
      $(RWPath)\RimWorldWin64_Data\Managed;
      $(RWPath)\RimWorldLinux_Data\Managed;
      $(RWPath)\RimWorldMac.app\Contents\Resources\Data\Managed;
      $(ReferencePath)
    </ReferencePath>
  </PropertyGroup>
  <!-- Prevents copying DLLs on build. -->
  <!-- If you do still get copies, wipe out the `obj` folder and re-run the `restore` task. -->
  <!-- You can do this on the command line with: `msbuild /t:restore` -->
  <ItemDefinitionGroup>
    <Reference><Private>False</Private></Reference>
    <ProjectReference><Private>False</Private></ProjectReference>
    <PackageReference><ExcludeAssets>runtime</ExcludeAssets></PackageReference>
  </ItemDefinitionGroup>
  <ItemGroup>
    <Compile Include=".\**\*.cs" />
    <!-- Ignore files in `obj`; they'll be included else where, as needed. -->
    <Compile Remove=".\obj\**\*.cs" />
    <!-- Things in trash are in trash for a reason, I presume.  Maybe delete them? -->
    <Compile Remove=".\0trash\**\*.cs" />
    <!-- Exclude files not currently in use here. -->
    <!-- Better yet, clean up your garbage.  If we need it again, Git keeps a copy for us. -->
    <Compile Remove=".\Common\ExpandedPawnCharacterCard.cs" />
    <Compile Remove=".\Common\Verb_Fuck.cs" />
    <Compile Remove=".\Common\CORE_EXPOSED\HealthCardUtility.cs" />
    <Compile Remove=".\JobDrivers\JobRJWSex.cs" />
    <Compile Remove=".\JobDrivers\JobDriver_AbortMechPregnancy.cs" />
    <Compile Remove=".\RJWTab\PawnColumnWorker_Master.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_BestialityForFemale.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Quickie.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_ViolateCorpse.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_BestialityForMale.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Masturbate_Quick.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_RapeEnemy.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_BestialityF.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Rape.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Sex.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_CleanSexStuff.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_RapeCP.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Masturbate_Bed.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_BestialityM.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Solicit.cs" />
    <Compile Remove=".\WorkGivers\WorkGiver_Masturbate_Chair.cs" />
    <Compile Remove=".\Harmony\patch_PartIsMissing.cs" />
    <Compile Remove=".\Harmony\d.cs" />
    <Compile Remove=".\Harmony\patch_need.cs" />
    <Compile Remove=".\Harmony\test.cs" />
    <Compile Remove=".\Harmony\patch_CnPBnC.cs" />
    <Compile Remove=".\Harmony\Building_Bed_Patch.cs" />
    <Compile Remove=".\Harmony\CnPcompatibility.cs" />
    <Compile Remove=".\Harmony\patch_AnimalTab.cs" />
    <Compile Remove=".\DefOf\RJW_RecipeDefOf.cs" />
    <Compile Remove=".\DefOf\JobDriver_AdjustParts.cs" />
    <Compile Remove=".\DefOf\JobDefOf.cs" />
    <Compile Remove=".\Modules\Bondage\Comps\CompCryptoStamped.cs" />
    <Compile Remove=".\Modules\Genitals\Enums\LewdablePartKind.cs" />
    <Compile Remove=".\Recipes\Install_Part\Recipe_InstallGenitals.cs" />
    <Compile Remove=".\Recipes\Install_Part\Recipe_InstallBreasts.cs" />
    <Compile Remove=".\Recipes\Install_Part\Recipe_InstallAnus.cs" />
    <Compile Remove=".\Recipes\Recipe_ShrinkBreasts.cs" />
    <Compile Remove=".\Recipes\Recipe_GrowBreasts.cs" />
    <Compile Remove=".\Recipes\Remove_Part\Recipe_RemovePenis.cs" />
    <Compile Remove=".\Recipes\Remove_Part\Recipe_RemoveVagina.cs" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="0MultiplayerAPI, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>0trash\packages\RimWorld.MultiplayerAPI.0.3.0\lib\net472\0MultiplayerAPI.dll</HintPath>
    </Reference>
    <Reference Include="Psychology">
      <HintPath>0trash\modpackages\Psychology.2018-11-18\Assemblies\Psychology.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="RimWorldChildren">
      <HintPath>0trash\modpackages\ChildrenAndPregnancy.0.4e\Assemblies\RimWorldChildren.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="SyrTraits">
      <HintPath>0trash\modpackages\SYR.Individuality.1.1.7\1.1\Assemblies\SyrTraits.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Runtime.InteropServices.RuntimeInformation" />
    <!-- RimWorld references -->
    <Reference Include="Assembly-CSharp" />
    <Reference Include="ISharpZipLib" />
    <Reference Include="Unity.TextMeshPro" />
    <Reference Include="UnityEngine.AIModule" />
    <Reference Include="UnityEngine.AccessibilityModule" />
    <Reference Include="UnityEngine.AndroidJNIModule" />
    <Reference Include="UnityEngine.AnimationModule" />
    <Reference Include="UnityEngine.AssetBundleModule" />
    <Reference Include="UnityEngine.AudioModule" />
    <Reference Include="UnityEngine.ClothModule" />
    <Reference Include="UnityEngine.ClusterInputModule" />
    <Reference Include="UnityEngine.ClusterRendererModule" />
    <Reference Include="UnityEngine.CoreModule" />
    <Reference Include="UnityEngine.CrashReportingModule" />
    <Reference Include="UnityEngine.DSPGraphModule" />
    <Reference Include="UnityEngine.DirectorModule" />
    <Reference Include="UnityEngine.GameCenterModule" />
    <Reference Include="UnityEngine.GridModule" />
    <Reference Include="UnityEngine.HotReloadModule" />
    <Reference Include="UnityEngine.IMGUIModule" />
    <Reference Include="UnityEngine.ImageConversionModule" />
    <Reference Include="UnityEngine.InputLegacyModule" />
    <Reference Include="UnityEngine.InputModule" />
    <Reference Include="UnityEngine.JSONSerializeModule" />
    <Reference Include="UnityEngine.LocalizationModule" />
    <Reference Include="UnityEngine.ParticleSystemModule" />
    <Reference Include="UnityEngine.PerformanceReportingModule" />
    <Reference Include="UnityEngine.Physics2DModule" />
    <Reference Include="UnityEngine.PhysicsModule" />
    <Reference Include="UnityEngine.ProfilerModule" />
    <Reference Include="UnityEngine.ScreenCaptureModule" />
    <Reference Include="UnityEngine.SharedInternalsModule" />
    <Reference Include="UnityEngine.SpriteMaskModule" />
    <Reference Include="UnityEngine.SpriteShapeModule" />
    <Reference Include="UnityEngine.StreamingModule" />
    <Reference Include="UnityEngine.SubstanceModule" />
    <Reference Include="UnityEngine.TLSModule" />
    <Reference Include="UnityEngine.TerrainModule" />
    <Reference Include="UnityEngine.TerrainPhysicsModule" />
    <Reference Include="UnityEngine.TextCoreModule" />
    <Reference Include="UnityEngine.TextRenderingModule" />
    <Reference Include="UnityEngine.TilemapModule" />
    <Reference Include="UnityEngine.UI" />
    <Reference Include="UnityEngine.UIElementsModule" />
    <Reference Include="UnityEngine.UIModule" />
    <Reference Include="UnityEngine.UNETModule" />
    <Reference Include="UnityEngine.UmbraModule" />
    <Reference Include="UnityEngine.UnityAnalyticsModule" />
    <Reference Include="UnityEngine.UnityConnectModule" />
    <Reference Include="UnityEngine.UnityTestProtocolModule" />
    <Reference Include="UnityEngine.UnityWebRequestAssetBundleModule" />
    <Reference Include="UnityEngine.UnityWebRequestAudioModule" />
    <Reference Include="UnityEngine.UnityWebRequestModule" />
    <Reference Include="UnityEngine.UnityWebRequestTextureModule" />
    <Reference Include="UnityEngine.UnityWebRequestWWWModule" />
    <Reference Include="UnityEngine.VFXModule" />
    <Reference Include="UnityEngine.VRModule" />
    <Reference Include="UnityEngine.VehiclesModule" />
    <Reference Include="UnityEngine.VideoModule" />
    <Reference Include="UnityEngine.WindModule" />
    <Reference Include="UnityEngine.XRModule" />
    <Reference Include="UnityEngine" />
    <!-- The following are not available on all platforms, IE Linux. -->
      <!-- <Reference Include="UnityEngine.ARModule" /> -->
      <!-- <Reference Include="NAudio" /> -->
      <!-- <Reference Include="NVorbis" /> -->
    <!-- end RimWorld references -->
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Lib.Harmony" Version="2.2.2" />
    <PackageReference Include="UnlimitedHugs.Rimworld.HugsLib" Version="10.0.1" />
  </ItemGroup>
  <ItemGroup />
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <ProjectExtensions>
    <VisualStudio AllowExistingFolder="true" />
  </ProjectExtensions>
</Project>


code:
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RimJobWorld.Main", "RimJobWorld.Main.csproj", "{22F82FFF-8BD4-4CEE-9F22-C7DA71281E72}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{22F82FFF-8BD4-4CEE-9F22-C7DA71281E72}.Debug|Any CPU.ActiveCfg = Release|Any CPU
		{22F82FFF-8BD4-4CEE-9F22-C7DA71281E72}.Debug|Any CPU.Build.0 = Release|Any CPU
		{22F82FFF-8BD4-4CEE-9F22-C7DA71281E72}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{22F82FFF-8BD4-4CEE-9F22-C7DA71281E72}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {16BA61E5-4C97-4E73-926D-6718DE8E4776}
	EndGlobalSection
EndGlobal


code:
using System;
using UnityEngine;
using Verse;
using System.Collections.Generic;

namespace rjw
{
	public class RJWDebugSettings : ModSettings
	{
		private static Vector2 scrollPosition;
		private static float height_modifier = 0f;

		public static void DoWindowContents(Rect inRect)
		{
			Rect outRect = new Rect(0f, 30f, inRect.width, inRect.height - 30f);
			Rect viewRect = new Rect(0f, 0f, inRect.width - 16f, inRect.height + height_modifier);

			Widgets.BeginScrollView(outRect, ref scrollPosition, viewRect); // scroll

			Listing_Standard listingStandard = new Listing_Standard();
			listingStandard.maxOneColumn = true;
			listingStandard.ColumnWidth = viewRect.width / 2.05f;
			listingStandard.Begin(viewRect);
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("submit_button_enabled".Translate(), ref RJWSettings.submit_button_enabled, "submit_button_enabled_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("RJW_designation_box".Translate(), ref RJWSettings.show_RJW_designation_box, "RJW_designation_box_desc".Translate());
			listingStandard.Gap(5f);
			if (listingStandard.ButtonText("Rjw Parts " + RJWSettings.ShowRjwParts))
			{
				Find.WindowStack.Add(new FloatMenu(new List<FloatMenuOption>()
					{
					  new FloatMenuOption("Extended", (() => RJWSettings.ShowRjwParts = RJWSettings.ShowParts.Extended)),
					  new FloatMenuOption("Show", (() => RJWSettings.ShowRjwParts = RJWSettings.ShowParts.Show)),
					  //new FloatMenuOption("Known".Translate(), (() => RJWSettings.ShowRjwParts = RJWSettings.ShowParts.Known)),
					  new FloatMenuOption("Hide", (() => RJWSettings.ShowRjwParts = RJWSettings.ShowParts.Hide))
					}));
			}
			listingStandard.Gap(30f);

			GUI.contentColor = Color.yellow;
			listingStandard.Label("YOU PATHETIC CHEATER ");
			GUI.contentColor = Color.white;
			listingStandard.CheckboxLabeled("override_RJW_designation_checks_name".Translate(), ref RJWSettings.override_RJW_designation_checks, "override_RJW_designation_checks_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("override_control".Translate(), ref RJWSettings.override_control, "override_control_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_Rapist".Translate(), ref RJWSettings.AddTrait_Rapist, "AddTrait_Rapist_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_Masocist".Translate(), ref RJWSettings.AddTrait_Masocist, "AddTrait_Masocist_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_Nymphomaniac".Translate(), ref RJWSettings.AddTrait_Nymphomaniac, "AddTrait_Nymphomaniac_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_Necrophiliac".Translate(), ref RJWSettings.AddTrait_Necrophiliac, "AddTrait_Necrophiliac_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_Nerves".Translate(), ref RJWSettings.AddTrait_Nerves, "AddTrait_Nerves_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_Zoophiliac".Translate(), ref RJWSettings.AddTrait_Zoophiliac, "AddTrait_Zoophiliac_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_FootSlut".Translate(), ref RJWSettings.AddTrait_FootSlut, "AddTrait_FootSlut_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_CumSlut".Translate(), ref RJWSettings.AddTrait_CumSlut, "AddTrait_CumSlut_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("AddTrait_ButtSlut".Translate(), ref RJWSettings.AddTrait_ButtSlut, "AddTrait_ButtSlut_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("Allow_RMB_DeepTalk".Translate(), ref RJWSettings.Allow_RMB_DeepTalk, "Allow_RMB_DeepTalk_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("Disable_bestiality_pregnancy_relations".Translate(), ref RJWSettings.Disable_bestiality_pregnancy_relations, "Disable_bestiality_pregnancy_relations_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("Disable_egg_pregnancy_relations".Translate(), ref RJWSettings.Disable_egg_pregnancy_relations, "Disable_egg_pregnancy_relations_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("Disable_MeditationFocusDrain".Translate(), ref RJWSettings.Disable_MeditationFocusDrain, "Disable_MeditationFocusDrain_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("Disable_RecreationDrain".Translate(), ref RJWSettings.Disable_RecreationDrain, "Disable_RecreationDrain_desc".Translate());
			listingStandard.Gap(5f);

			listingStandard.NewColumn();
			listingStandard.Gap(4f);
			GUI.contentColor = Color.yellow;
			listingStandard.CheckboxLabeled("designated_freewill".Translate(), ref RJWSettings.designated_freewill, "designated_freewill_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("override_lovin".Translate(), ref RJWSettings.override_lovin, "override_lovin_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("override_matin".Translate(), ref RJWSettings.override_matin, "override_matin_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("matin_crossbreed".Translate(), ref RJWSettings.matin_crossbreed, "matin_crossbreed_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("DevMode_name".Translate(), ref RJWSettings.DevMode, "DevMode_desc".Translate());
			listingStandard.Gap(5f);
			if (RJWSettings.DevMode)
			{
				listingStandard.CheckboxLabeled("WildMode_name".Translate(), ref RJWSettings.WildMode, "WildMode_desc".Translate());
				listingStandard.Gap(5f);
				listingStandard.CheckboxLabeled("HippieMode_name".Translate(), ref RJWSettings.HippieMode, "HippieMode_desc".Translate());
				listingStandard.Gap(5f);
				listingStandard.CheckboxLabeled("DebugLogJoinInBed".Translate(), ref RJWSettings.DebugLogJoinInBed, "DebugLogJoinInBed_desc".Translate());
				listingStandard.Gap(5f);
				listingStandard.CheckboxLabeled("DebugRape".Translate(), ref RJWSettings.DebugRape, "DebugRape_desc".Translate());
				listingStandard.Gap(5f);
				listingStandard.CheckboxLabeled("DebugInteraction".Translate(), ref RJWSettings.DebugInteraction, "DebugInteraction_desc".Translate());
				listingStandard.Gap(5f);
				listingStandard.CheckboxLabeled("DebugNymph".Translate(), ref RJWSettings.DebugNymph, "DebugNymph_desc".Translate());
				listingStandard.Gap(5f);
			}
			else
			{
				RJWSettings.DebugLogJoinInBed = false;
				RJWSettings.DebugRape = false;
			}
			listingStandard.CheckboxLabeled("GenderlessAsFuta_name".Translate(), ref RJWSettings.GenderlessAsFuta, "GenderlessAsFuta_desc".Translate());
			listingStandard.Gap(5f);
			GUI.contentColor = Color.white;

			listingStandard.Gap(30f);
			listingStandard.Label("maxDistanceCellsCasual_name".Translate() + ": " + (RJWSettings.maxDistanceCellsCasual), -1f, "maxDistanceCellsCasual_desc".Translate());
			RJWSettings.maxDistanceCellsCasual = listingStandard.Slider((int)RJWSettings.maxDistanceCellsCasual, 0, 10000);
			listingStandard.Label("maxDistanceCellsRape_name".Translate() + ": " + (RJWSettings.maxDistanceCellsRape), -1f, "maxDistanceCellsRape_desc".Translate());
			RJWSettings.maxDistanceCellsRape = listingStandard.Slider((int)RJWSettings.maxDistanceCellsRape, 0, 10000);
			listingStandard.Label("maxDistancePathCost_name".Translate() + ": " + (RJWSettings.maxDistancePathCost), -1f, "maxDistancePathCost_desc".Translate());
			RJWSettings.maxDistancePathCost = listingStandard.Slider((int)RJWSettings.maxDistancePathCost, 0, 5000);

			listingStandard.End();
			height_modifier = listingStandard.CurHeight;
			Widgets.EndScrollView();
		}

		public override void ExposeData()
		{
			base.ExposeData();
			Scribe_Values.Look(ref RJWSettings.submit_button_enabled, "submit_button_enabled", RJWSettings.submit_button_enabled, true);
			Scribe_Values.Look(ref RJWSettings.show_RJW_designation_box, "show_RJW_designation_box", RJWSettings.show_RJW_designation_box, true);
			Scribe_Values.Look(ref RJWSettings.ShowRjwParts, "ShowRjwParts", RJWSettings.ShowRjwParts, true);
			Scribe_Values.Look(ref RJWSettings.maxDistanceCellsCasual, "maxDistanceCellsCasual", RJWSettings.maxDistanceCellsCasual, true);
			Scribe_Values.Look(ref RJWSettings.maxDistanceCellsRape, "maxDistanceCellsRape", RJWSettings.maxDistanceCellsRape, true);
			Scribe_Values.Look(ref RJWSettings.maxDistancePathCost, "maxDistancePathCost", RJWSettings.maxDistancePathCost, true);

			Scribe_Values.Look(ref RJWSettings.AddTrait_Rapist, "AddTrait_Rapist", RJWSettings.AddTrait_Rapist, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_Masocist, "AddTrait_Masocist", RJWSettings.AddTrait_Masocist, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_Nymphomaniac, "AddTrait_Nymphomaniac", RJWSettings.AddTrait_Nymphomaniac, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_Necrophiliac, "AddTrait_Necrophiliac", RJWSettings.AddTrait_Necrophiliac, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_Nerves, "AddTrait_Nerves", RJWSettings.AddTrait_Nerves, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_Zoophiliac, "AddTrait_Zoophiliac", RJWSettings.AddTrait_Zoophiliac, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_FootSlut, "AddTrait_FootSlut", RJWSettings.AddTrait_FootSlut, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_CumSlut, "AddTrait_CumSlut", RJWSettings.AddTrait_CumSlut, true);
			Scribe_Values.Look(ref RJWSettings.AddTrait_ButtSlut, "AddTrait_ButtSlut", RJWSettings.AddTrait_ButtSlut, true);

			Scribe_Values.Look(ref RJWSettings.Allow_RMB_DeepTalk, "Allow_RMB_DeepTalk", RJWSettings.Allow_RMB_DeepTalk, true);
			Scribe_Values.Look(ref RJWSettings.Allow_RMB_DeepTalk, "Allow_RMB_DeepTalk", RJWSettings.Allow_RMB_DeepTalk, true);
			Scribe_Values.Look(ref RJWSettings.Disable_bestiality_pregnancy_relations, "Disable_bestiality_pregnancy_relations", RJWSettings.Disable_bestiality_pregnancy_relations, true);
			Scribe_Values.Look(ref RJWSettings.Disable_egg_pregnancy_relations, "Disable_egg_pregnancy_relations", RJWSettings.Disable_egg_pregnancy_relations, true);
			Scribe_Values.Look(ref RJWSettings.Disable_MeditationFocusDrain, "Disable_MeditationFocusDrain", RJWSettings.Disable_MeditationFocusDrain, true);
			Scribe_Values.Look(ref RJWSettings.Disable_RecreationDrain, "Disable_RecreationDrain", RJWSettings.Disable_RecreationDrain, true);

			Scribe_Values.Look(ref RJWSettings.GenderlessAsFuta, "GenderlessAsFuta", RJWSettings.GenderlessAsFuta, true);
			Scribe_Values.Look(ref RJWSettings.override_lovin, "override_lovin", RJWSettings.override_lovin, true);
			Scribe_Values.Look(ref RJWSettings.override_matin, "override_matin", RJWSettings.override_matin, true);
			Scribe_Values.Look(ref RJWSettings.matin_crossbreed, "matin_crossbreed", RJWSettings.matin_crossbreed, true);
			Scribe_Values.Look(ref RJWSettings.WildMode, "Wildmode", RJWSettings.WildMode, true);
			Scribe_Values.Look(ref RJWSettings.HippieMode, "Hippiemode", RJWSettings.HippieMode, true);
			Scribe_Values.Look(ref RJWSettings.override_RJW_designation_checks, "override_RJW_designation_checks", RJWSettings.override_RJW_designation_checks, true);
			Scribe_Values.Look(ref RJWSettings.override_control, "override_control", RJWSettings.override_control, true);
			Scribe_Values.Look(ref RJWSettings.DevMode, "DevMode", RJWSettings.DevMode, true);
			Scribe_Values.Look(ref RJWSettings.DebugLogJoinInBed, "DebugLogJoinInBed", RJWSettings.DebugLogJoinInBed, true);
			Scribe_Values.Look(ref RJWSettings.DebugRape, "DebugRape", RJWSettings.DebugRape, true);
			Scribe_Values.Look(ref RJWSettings.DebugInteraction, "DebugInteraction", RJWSettings.DebugInteraction, true);
			Scribe_Values.Look(ref RJWSettings.DebugNymph, "DebugNymph", RJWSettings.DebugNymph, true);
		}
	}
}


code:
using System;
using UnityEngine;
using Verse;

namespace rjw
{
	public class RJWHookupSettings : ModSettings
	{
		public static bool HookupsEnabled = true;
		public static bool QuickHookupsEnabled = true;
		public static bool NoHookupsDuringWorkHours = true;
		public static bool ColonistsCanHookup = true;
		public static bool ColonistsCanHookupWithVisitor = false;
		public static bool CanHookupWithPrisoner = false;
		public static bool VisitorsCanHookupWithColonists = false;
		public static bool VisitorsCanHookupWithVisitors = true;
		public static bool PrisonersCanHookupWithNonPrisoner = false;
		public static bool PrisonersCanHookupWithPrisoner = true;
		public static float HookupChanceForNonNymphos = 0.3f;
		public static float MinimumFuckabilityToHookup = 0.1f;
		public static float MinimumAttractivenessToHookup = 0.5f;
		public static float MinimumRelationshipToHookup = 20f;

		//public static bool NymphosCanPickAnyone = true;
		public static bool NymphosCanCheat = true;
		public static bool NymphosCanHomewreck = true;
		public static bool NymphosCanHomewreckReverse = true;

		private static Vector2 scrollPosition;
		private static float height_modifier = 0f;

		public static void DoWindowContents(Rect inRect)
		{
			MinimumFuckabilityToHookup = Mathf.Clamp(MinimumFuckabilityToHookup, 0.1f, 1f);
			MinimumAttractivenessToHookup = Mathf.Clamp(MinimumAttractivenessToHookup, 0.0f, 1f);
			MinimumRelationshipToHookup = Mathf.Clamp(MinimumRelationshipToHookup, -100, 100);

			Rect outRect = new Rect(0f, 30f, inRect.width, inRect.height - 30f);
			Rect viewRect = new Rect(0f, 0f, inRect.width - 16f, inRect.height + height_modifier);

			Widgets.BeginScrollView(outRect, ref scrollPosition, viewRect); // scroll

			Listing_Standard listingStandard = new Listing_Standard();
			listingStandard.maxOneColumn = true;
			listingStandard.ColumnWidth = viewRect.width / 2.05f;
			listingStandard.Begin(viewRect);
			listingStandard.Gap(4f);

			// Casual sex settings
			listingStandard.CheckboxLabeled("SettingHookupsEnabled".Translate(), ref HookupsEnabled, "SettingHookupsEnabled_desc".Translate());
			if(HookupsEnabled)
				listingStandard.CheckboxLabeled("SettingQuickHookupsEnabled".Translate(), ref QuickHookupsEnabled, "SettingQuickHookupsEnabled_desc".Translate());
			listingStandard.CheckboxLabeled("SettingNoHookupsDuringWorkHours".Translate(), ref NoHookupsDuringWorkHours, "SettingNoHookupsDuringWorkHours_desc".Translate());

			listingStandard.Gap(10f);
			listingStandard.CheckboxLabeled("SettingColonistsCanHookup".Translate(), ref ColonistsCanHookup, "SettingColonistsCanHookup_desc".Translate());
			listingStandard.CheckboxLabeled("SettingColonistsCanHookupWithVisitor".Translate(), ref ColonistsCanHookupWithVisitor, "SettingColonistsCanHookupWithVisitor_desc".Translate());
			listingStandard.CheckboxLabeled("SettingVisitorsCanHookupWithColonists".Translate(), ref VisitorsCanHookupWithColonists, "SettingVisitorsCanHookupWithColonists_desc".Translate());
			listingStandard.CheckboxLabeled("SettingVisitorsCanHookupWithVisitors".Translate(), ref VisitorsCanHookupWithVisitors, "SettingVisitorsCanHookupWithVisitors_desc".Translate());

			listingStandard.Gap(10f);
			listingStandard.CheckboxLabeled("SettingPrisonersCanHookupWithNonPrisoner".Translate(), ref PrisonersCanHookupWithNonPrisoner, "SettingPrisonersCanHookupWithNonPrisoner_desc".Translate());
			listingStandard.CheckboxLabeled("SettingPrisonersCanHookupWithPrisoner".Translate(), ref PrisonersCanHookupWithPrisoner, "SettingPrisonersCanHookupWithPrisoner_desc".Translate());
			listingStandard.CheckboxLabeled("SettingCanHookupWithPrisoner".Translate(), ref CanHookupWithPrisoner, "SettingCanHookupWithPrisoner_desc".Translate());

			listingStandard.Gap(10f);
			//listingStandard.CheckboxLabeled("SettingNymphosCanPickAnyone".Translate(), ref NymphosCanPickAnyone, "SettingNymphosCanPickAnyone_desc".Translate());
			listingStandard.CheckboxLabeled("SettingNymphosCanCheat".Translate(), ref NymphosCanCheat, "SettingNymphosCanCheat_desc".Translate());
			listingStandard.CheckboxLabeled("SettingNymphosCanHomewreck".Translate(), ref NymphosCanHomewreck, "SettingNymphosCanHomewreck_desc".Translate());
			listingStandard.CheckboxLabeled("SettingNymphosCanHomewreckReverse".Translate(), ref NymphosCanHomewreckReverse, "SettingNymphosCanHomewreckReverse_desc".Translate());

			listingStandard.Gap(10f);
			listingStandard.Label("SettingHookupChanceForNonNymphos".Translate() + ": " + (int)(HookupChanceForNonNymphos * 100) + "%", -1f, "SettingHookupChanceForNonNymphos_desc".Translate());
			HookupChanceForNonNymphos = listingStandard.Slider(HookupChanceForNonNymphos, 0.0f, 1.0f);
			listingStandard.Label("SettingMinimumFuckabilityToHookup".Translate() + ": " + (int)(MinimumFuckabilityToHookup * 100) + "%", -1f, "SettingMinimumFuckabilityToHookup_desc".Translate());
			MinimumFuckabilityToHookup = listingStandard.Slider(MinimumFuckabilityToHookup, 0.1f, 1.0f); // Minimum must be above 0.0 to avoid breaking SexAppraiser.would_fuck()'s hard-failure cases that return 0f
			listingStandard.Label("SettingMinimumAttractivenessToHookup".Translate() + ": " + (int)(MinimumAttractivenessToHookup * 100) + "%", -1f, "SettingMinimumAttractivenessToHookup_desc".Translate());
			MinimumAttractivenessToHookup = listingStandard.Slider(MinimumAttractivenessToHookup, 0.0f, 1.0f);
			listingStandard.Label("SettingMinimumRelationshipToHookup".Translate() + ": " + (MinimumRelationshipToHookup), -1f, "SettingMinimumRelationshipToHookup_desc".Translate());
			MinimumRelationshipToHookup = listingStandard.Slider((int)MinimumRelationshipToHookup, -100f, 100f);

			listingStandard.NewColumn();
			listingStandard.Gap(4f);

			listingStandard.End();
			height_modifier = listingStandard.CurHeight;
			Widgets.EndScrollView();
		}

		public override void ExposeData()
		{
			base.ExposeData();
			Scribe_Values.Look(ref HookupsEnabled, "SettingHookupsEnabled");
			Scribe_Values.Look(ref QuickHookupsEnabled, "SettingQuickHookupsEnabled");
			Scribe_Values.Look(ref NoHookupsDuringWorkHours, "NoHookupsDuringWorkHours");
			Scribe_Values.Look(ref ColonistsCanHookup, "SettingColonistsCanHookup");
			Scribe_Values.Look(ref ColonistsCanHookupWithVisitor, "SettingColonistsCanHookupWithVisitor");
			Scribe_Values.Look(ref VisitorsCanHookupWithColonists, "SettingVisitorsCanHookupWithColonists");
			Scribe_Values.Look(ref VisitorsCanHookupWithVisitors, "SettingVisitorsCanHookupWithVisitors");

			// Prisoner settings
			Scribe_Values.Look(ref CanHookupWithPrisoner, "SettingCanHookupWithPrisoner");
			Scribe_Values.Look(ref PrisonersCanHookupWithNonPrisoner, "SettingPrisonersCanHookupWithNonPrisoner");
			Scribe_Values.Look(ref PrisonersCanHookupWithPrisoner, "SettingPrisonersCanHookupWithPrisoner");

			// Nympho settings
			//Scribe_Values.Look(ref NymphosCanPickAnyone, "SettingNymphosCanPickAnyone");
			Scribe_Values.Look(ref NymphosCanCheat, "SettingNymphosCanCheat");
			Scribe_Values.Look(ref NymphosCanHomewreck, "SettingNymphosCanHomewreck");
			Scribe_Values.Look(ref NymphosCanHomewreckReverse, "SettingNymphosCanHomewreckReverse");

			Scribe_Values.Look(ref HookupChanceForNonNymphos, "SettingHookupChanceForNonNymphos");
			Scribe_Values.Look(ref MinimumFuckabilityToHookup, "SettingMinimumFuckabilityToHookup");
			Scribe_Values.Look(ref MinimumAttractivenessToHookup, "SettingMinimumAttractivenessToHookup");
			Scribe_Values.Look(ref MinimumRelationshipToHookup, "SettingMinimumRelationshipToHookup");
		}
	}
}


code:
using System;
using UnityEngine;
using Verse;

namespace rjw
{
	public class RJWPregnancySettings : ModSettings
	{
		public static bool humanlike_pregnancy_enabled = true;
		public static bool animal_pregnancy_enabled = true;
		public static bool animal_pregnancy_notifications_enabled = true;
		public static bool bestial_pregnancy_enabled = true;
		public static bool insect_pregnancy_enabled = true;
		public static bool insect_anal_pregnancy_enabled = false;
		public static bool insect_oral_pregnancy_enabled = false;
		public static bool egg_pregnancy_implant_anyone = true;
		public static bool egg_pregnancy_fertilize_anyone = false;
		public static bool egg_pregnancy_genes = true;
		public static bool egg_pregnancy_fertOrificeCheck_enabled = true;
		public static float egg_pregnancy_eggs_size = 1.0f;
		public static float egg_pregnancy_ovipositor_capacity_factor = 1f;
		public static bool safer_mechanoid_pregnancy = false;

		public static bool mechanoid_pregnancy_enabled = true;

		public static bool use_parent_method = true;
		public static float humanlike_DNA_from_mother = 0.5f;
		public static float bestiality_DNA_inheritance = 0.5f; // human/beast slider
		public static float bestial_DNA_from_mother = 1.0f; // mother/father slider

		public static bool complex_interspecies = false;
		public static int animal_impregnation_chance = 25;
		public static int humanlike_impregnation_chance = 25;
		public static float interspecies_impregnation_modifier = 0.2f;
		public static float fertility_endage_male = 1.2f;
		public static float fertility_endage_female_humanlike = 0.58f;
		public static float fertility_endage_female_animal = 0.96f;

		public static bool phantasy_pregnancy = false;
		public static float normal_pregnancy_duration = 1.0f;
		public static float egg_pregnancy_duration = 1.0f;
		public static float max_num_momtraits_inherited = 3.0f;
		public static float max_num_poptraits_inherited = 3.0f;

		private static bool useVanillaPregnancy = true;
		public static bool UseVanillaPregnancy => useVanillaPregnancy && ModsConfig.BiotechActive;

		private static Vector2 scrollPosition;
		private static float height_modifier = 0f;

		public static void DoWindowContents(Rect inRect)
		{
			Rect outRect = new Rect(0f, 30f, inRect.width, inRect.height - 30f);
			Rect viewRect = new Rect(0f, 30f, inRect.width - 16f, inRect.height + height_modifier);

			Widgets.BeginScrollView(outRect, ref scrollPosition, viewRect);

			Listing_Standard listingStandard = new Listing_Standard();
			listingStandard.maxOneColumn = true;
			listingStandard.ColumnWidth = viewRect.width / 2.05f;
			listingStandard.Begin(viewRect);
			listingStandard.Gap(4f);
			listingStandard.CheckboxLabeled("RJWH_pregnancy".Translate(), ref humanlike_pregnancy_enabled, "RJWH_pregnancy_desc".Translate());
			listingStandard.Gap(5f);
			if (ModsConfig.BiotechActive)
			{
				listingStandard.CheckboxLabeled("UseVanillaPregnancy".Translate(), ref useVanillaPregnancy, "UseVanillaPregnancy_desc".Translate());
				listingStandard.Gap(5f);
			}
			listingStandard.CheckboxLabeled("RJWA_pregnancy".Translate(), ref animal_pregnancy_enabled, "RJWA_pregnancy_desc".Translate());
			if (animal_pregnancy_enabled)
			{
				listingStandard.Gap(3f);
				listingStandard.CheckboxLabeled("  " + "RJWA_pregnancy_notifications".Translate(), ref animal_pregnancy_notifications_enabled, "RJWA_pregnancy_notifications_desc".Translate());
			}

			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("RJWB_pregnancy".Translate(), ref bestial_pregnancy_enabled, "RJWB_pregnancy_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("RJWI_pregnancy".Translate(), ref insect_pregnancy_enabled, "RJWI_pregnancy_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("egg_pregnancy_implant_anyone".Translate(), ref egg_pregnancy_implant_anyone, "egg_pregnancy_implant_anyone_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("egg_pregnancy_fertilize_anyone".Translate(), ref egg_pregnancy_fertilize_anyone, "egg_pregnancy_fertilize_anyone_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("egg_pregnancy_genes".Translate(), ref egg_pregnancy_genes, "egg_pregnancy_genes_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("RJWI_analPregnancy".Translate(), ref insect_anal_pregnancy_enabled, "RJWI_analPregnancy_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("RJWI_oralPregnancy".Translate(), ref insect_oral_pregnancy_enabled, "RJWI_oralPregnancy_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.CheckboxLabeled("RJWI_FertilizationCheck".Translate(), ref egg_pregnancy_fertOrificeCheck_enabled, "RJWI_FertilizationCheck_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.Gap(5f);

			int eggs_size = (int)(egg_pregnancy_eggs_size * 100);
			listingStandard.Label("egg_pregnancy_eggs_size".Translate() + ": " + eggs_size + "%", -1f, "egg_pregnancy_eggs_size_desc".Translate());
			egg_pregnancy_eggs_size = listingStandard.Slider(egg_pregnancy_eggs_size, 0.0f, 1.0f);
			int ovipositor_capacity_factor_percentage = (int)(egg_pregnancy_ovipositor_capacity_factor * 100);
			listingStandard.Label("egg_pregnancy_ovipositor_capacity_factor".Translate() + ": " + ovipositor_capacity_factor_percentage + "%", -1, "egg_pregnancy_ovipositor_capacity_factor_desc".Translate());
			// Note: Choose the domain any wider and a different input method has to be used or the slider width has to be increased!
			egg_pregnancy_ovipositor_capacity_factor = listingStandard.Slider(egg_pregnancy_ovipositor_capacity_factor, .1f, 5f);

			listingStandard.Gap(12f);

			listingStandard.CheckboxLabeled("UseParentMethod".Translate(), ref use_parent_method, "UseParentMethod_desc".Translate());
			listingStandard.Gap(5f);
			if (use_parent_method)
			{
				if (humanlike_DNA_from_mother == 0.0f)
				{
					listingStandard.Label("  " + "OffspringLookLikeTheirMother".Translate() + ": " + "AlwaysFather".Translate(), -1f, "OffspringLookLikeTheirMother_desc".Translate());
					humanlike_DNA_from_mother = listingStandard.Slider(humanlike_DNA_from_mother, 0.0f, 1.0f);
				}
				else if (humanlike_DNA_from_mother == 1.0f)
				{
					listingStandard.Label("  " + "OffspringLookLikeTheirMother".Translate() + ": " + "AlwaysMother".Translate(), -1f, "OffspringLookLikeTheirMother_desc".Translate());
					humanlike_DNA_from_mother = listingStandard.Slider(humanlike_DNA_from_mother, 0.0f, 1.0f);
				}
				else
				{
					int value = (int)(humanlike_DNA_from_mother * 100);
					listingStandard.Label("  " + "OffspringLookLikeTheirMother".Translate() + ": " + value + "%", -1f, "OffspringLookLikeTheirMother_desc".Translate());
					humanlike_DNA_from_mother = listingStandard.Slider(humanlike_DNA_from_mother, 0.0f, 1.0f);
				}

				if (bestial_DNA_from_mother == 0.0f)
				{
					listingStandard.Label("  " + "OffspringIsHuman".Translate() + ": " + "AlwaysFather".Translate(), -1f, "OffspringIsHuman_desc".Translate());
					bestial_DNA_from_mother = listingStandard.Slider(bestial_DNA_from_mother, 0.0f, 1.0f);
				}
				else if (bestial_DNA_from_mother == 1.0f)
				{
					listingStandard.Label("  " + "OffspringIsHuman".Translate() + ": " + "AlwaysMother".Translate(), -1f, "OffspringIsHuman_desc".Translate());
					bestial_DNA_from_mother = listingStandard.Slider(bestial_DNA_from_mother, 0.0f, 1.0f);
				}
				else
				{
					int value = (int)(bestial_DNA_from_mother * 100);
					listingStandard.Label("  " + "OffspringIsHuman".Translate() + ": " + value + "%", -1f, "OffspringIsHuman_desc".Translate());
					bestial_DNA_from_mother = listingStandard.Slider(bestial_DNA_from_mother, 0.0f, 1.0f);
				}

				if (bestiality_DNA_inheritance == 0.0f)
				{
					listingStandard.Label("  " + "OffspringIsHuman2".Translate() + ": " + "AlwaysBeast".Translate(), -1f, "OffspringIsHuman2_desc".Translate());
					bestiality_DNA_inheritance = listingStandard.Slider(bestiality_DNA_inheritance, 0.0f, 1.0f);
				}
				else if (bestiality_DNA_inheritance == 1.0f)
				{
					listingStandard.Label("  " + "OffspringIsHuman2".Translate() + ": " + "AlwaysHumanlike".Translate(), -1f, "OffspringIsHuman2_desc".Translate());
					bestiality_DNA_inheritance = listingStandard.Slider(bestiality_DNA_inheritance, 0.0f, 1.0f);
				}
				else
				{
					listingStandard.Label("  " + "OffspringIsHuman2".Translate() + ": " + "UsesOffspringIsHuman".Translate(), -1f, "OffspringIsHuman2_desc".Translate());
					bestiality_DNA_inheritance = listingStandard.Slider(bestiality_DNA_inheritance, 0.0f, 1.0f);
				}
			}
			else
				humanlike_DNA_from_mother = 100;

			listingStandard.Gap(5f);
			listingStandard.Label("max_num_momtraits_inherited".Translate() + ": " + (int)(max_num_momtraits_inherited));
			max_num_momtraits_inherited = listingStandard.Slider(max_num_momtraits_inherited, 0.0f, 9.0f);
			listingStandard.Gap(5f);
			listingStandard.Label("max_num_poptraits_inherited".Translate() + ": " + (int)(max_num_poptraits_inherited));
			max_num_poptraits_inherited = listingStandard.Slider(max_num_poptraits_inherited, 0.0f, 9.0f);
			listingStandard.Gap(5f);

			listingStandard.CheckboxLabeled("MechanoidImplanting".Translate(), ref mechanoid_pregnancy_enabled, "MechanoidImplanting_desc".Translate());
			listingStandard.Gap(5f);
			if (mechanoid_pregnancy_enabled)
			{
				listingStandard.CheckboxLabeled("SaferMechanoidImplanting".Translate(), ref safer_mechanoid_pregnancy, "SaferMechanoidImplanting_desc".Translate());
				listingStandard.Gap(5f);
			}
			listingStandard.CheckboxLabeled("ComplexImpregnation".Translate(), ref complex_interspecies, "ComplexImpregnation_desc".Translate());
			listingStandard.Gap(10f);

			GUI.contentColor = Color.cyan;
			listingStandard.Label("Base pregnancy chances:");
			listingStandard.Gap(5f);
			if (humanlike_pregnancy_enabled)
				listingStandard.Label("  Humanlike/Humanlike (same race): " + humanlike_impregnation_chance + "%");
			else
				listingStandard.Label("  Humanlike/Humanlike (same race): -DISABLED-");
			if (humanlike_pregnancy_enabled && !(humanlike_impregnation_chance * interspecies_impregnation_modifier <= 0.0f) && !complex_interspecies)
				listingStandard.Label("  Humanlike/Humanlike (different race): " + Math.Round(humanlike_impregnation_chance * interspecies_impregnation_modifier, 1) + "%");
			else if (complex_interspecies)
				listingStandard.Label("  Humanlike/Humanlike (different race): -DEPENDS ON SPECIES-");
			else
				listingStandard.Label("  Humanlike/Humanlike (different race): -DISABLED-");
			if (animal_pregnancy_enabled)
				listingStandard.Label("  Animal/Animal (same race): " + animal_impregnation_chance + "%");
			else
				listingStandard.Label("  Animal/Animal (same race): -DISABLED-");
			if (animal_pregnancy_enabled && !(animal_impregnation_chance * interspecies_impregnation_modifier <= 0.0f) && !complex_interspecies)
				listingStandard.Label("  Animal/Animal (different race): " + Math.Round(animal_impregnation_chance * interspecies_impregnation_modifier, 1) + "%");
			else if (complex_interspecies)
				listingStandard.Label("  Animal/Animal (different race): -DEPENDS ON SPECIES-");
			else
				listingStandard.Label("  Animal/Animal (different race): -DISABLED-");
			if (RJWSettings.bestiality_enabled && bestial_pregnancy_enabled && !(animal_impregnation_chance * interspecies_impregnation_modifier <= 0.0f) && !complex_interspecies)
				listingStandard.Label("  Humanlike/Animal: " + Math.Round(animal_impregnation_chance * interspecies_impregnation_modifier, 1) + "%");
			else if (complex_interspecies)
				listingStandard.Label("  Humanlike/Animal: -DEPENDS ON SPECIES-");
			else
				listingStandard.Label("  Humanlike/Animal: -DISABLED-");
			if (RJWSettings.bestiality_enabled && bestial_pregnancy_enabled && !(animal_impregnation_chance * interspecies_impregnation_modifier <= 0.0f) && !complex_interspecies)
				listingStandard.Label("  Animal/Humanlike: " + Math.Round(humanlike_impregnation_chance * interspecies_impregnation_modifier, 1) + "%");
			else if (complex_interspecies)
				listingStandard.Label("  Animal/Humanlike: -DEPENDS ON SPECIES-");
			else
				listingStandard.Label("  Animal/Humanlike: -DISABLED-");
			GUI.contentColor = Color.white;

			listingStandard.NewColumn();
			listingStandard.Gap(4f);
			listingStandard.Label("PregnantCoeffecientForHuman".Translate() + ": " + humanlike_impregnation_chance + "%", -1f, "PregnantCoeffecientForHuman_desc".Translate());
			humanlike_impregnation_chance = (int)listingStandard.Slider(humanlike_impregnation_chance, 0.0f, 100f);
			listingStandard.Label("PregnantCoeffecientForAnimals".Translate() + ": " + animal_impregnation_chance + "%", -1f, "PregnantCoeffecientForAnimals_desc".Translate());
			animal_impregnation_chance = (int)listingStandard.Slider(animal_impregnation_chance, 0.0f, 100f);
			if (!complex_interspecies)
			{
				switch (interspecies_impregnation_modifier)
				{
					case 0.0f:
						GUI.contentColor = Color.grey;
						listingStandard.Label("InterspeciesImpregnantionModifier".Translate() + ": " + "InterspeciesDisabled".Translate(), -1f, "InterspeciesImpregnantionModifier_desc".Translate());
						GUI.contentColor = Color.white;
						break;
					case 1.0f:
						GUI.contentColor = Color.cyan;
						listingStandard.Label("InterspeciesImpregnantionModifier".Translate() + ": " + "InterspeciesMaximum".Translate(), -1f, "InterspeciesImpregnantionModifier_desc".Translate());
						GUI.contentColor = Color.white;
						break;
					default:
						listingStandard.Label("InterspeciesImpregnantionModifier".Translate() + ": " + Math.Round(interspecies_impregnation_modifier * 100, 1) + "%", -1f, "InterspeciesImpregnantionModifier_desc".Translate());
						break;
				}
				interspecies_impregnation_modifier = listingStandard.Slider(interspecies_impregnation_modifier, 0.0f, 1.0f);
			}
			listingStandard.Label("RJW_fertility_endAge_male".Translate() + ": " + (int)(fertility_endage_male * 80) + "In_human_years".Translate(), -1f, "RJW_fertility_endAge_male_desc".Translate());
			fertility_endage_male = listingStandard.Slider(fertility_endage_male, 0.1f, 3.0f);
			listingStandard.Label("RJW_fertility_endAge_female_humanlike".Translate() + ": " + (int)(fertility_endage_female_humanlike * 80) + "In_human_years".Translate(), -1f, "RJW_fertility_endAge_female_humanlike_desc".Translate());
			fertility_endage_female_humanlike = listingStandard.Slider(fertility_endage_female_humanlike, 0.1f, 3.0f);
			listingStandard.Label("RJW_fertility_endAge_female_animal".Translate() + ": " + (int)(fertility_endage_female_animal * 100) + "XofLifeExpectancy".Translate(), -1f, "RJW_fertility_endAge_female_animal_desc".Translate());
			fertility_endage_female_animal = listingStandard.Slider(fertility_endage_female_animal, 0.1f, 3.0f);
			listingStandard.Gap(10f);

			listingStandard.CheckboxLabeled("phantasy_pregnancy".Translate(), ref phantasy_pregnancy, "phantasy_pregnancy_desc".Translate());
			listingStandard.Gap(5f);
			listingStandard.Label("normal_pregnancy_duration".Translate() + ": " + (int)(normal_pregnancy_duration * 100) + "%", -1f, "normal_pregnancy_duration_desc".Translate());
			normal_pregnancy_duration = listingStandard.Slider(normal_pregnancy_duration, 0.05f, 2.0f);
			listingStandard.Gap(5f);
			listingStandard.Label("egg_pregnancy_duration".Translate() + ": " + (int)(egg_pregnancy_duration * 100) + "%", -1f, "egg_pregnancy_duration_desc".Translate());
			egg_pregnancy_duration = listingStandard.Slider(egg_pregnancy_duration, 0.05f, 2.0f);
			listingStandard.Gap(5f);

			listingStandard.End();
			height_modifier = listingStandard.CurHeight;
			Widgets.EndScrollView();
		}

		public override void ExposeData()
		{
			base.ExposeData();
			Scribe_Values.Look(ref humanlike_pregnancy_enabled, "humanlike_pregnancy_enabled", humanlike_pregnancy_enabled, true);
			Scribe_Values.Look(ref useVanillaPregnancy, "useVanillaPregnancy", useVanillaPregnancy, true);
			Scribe_Values.Look(ref animal_pregnancy_enabled, "animal_enabled", animal_pregnancy_enabled, true);
			Scribe_Values.Look(ref animal_pregnancy_notifications_enabled, "animal_notifications_enabled", animal_pregnancy_notifications_enabled, true);
			Scribe_Values.Look(ref bestial_pregnancy_enabled, "bestial_pregnancy_enabled", bestial_pregnancy_enabled, true);
			Scribe_Values.Look(ref insect_pregnancy_enabled, "insect_pregnancy_enabled", insect_pregnancy_enabled, true);
			Scribe_Values.Look(ref insect_anal_pregnancy_enabled, "insect_anal_pregnancy_enabled", insect_anal_pregnancy_enabled, true);
			Scribe_Values.Look(ref insect_oral_pregnancy_enabled, "insect_oral_pregnancy_enabled", insect_oral_pregnancy_enabled, true);
			Scribe_Values.Look(ref egg_pregnancy_implant_anyone, "egg_pregnancy_implant_anyone", egg_pregnancy_implant_anyone, true);
			Scribe_Values.Look(ref egg_pregnancy_fertilize_anyone, "egg_pregnancy_fertilize_anyone", egg_pregnancy_fertilize_anyone, true);
			Scribe_Values.Look(ref egg_pregnancy_genes, "egg_pregnancy_genes", egg_pregnancy_genes, true);
			Scribe_Values.Look(ref egg_pregnancy_fertOrificeCheck_enabled, "egg_pregnancy_fertOrificeCheck_enabled", egg_pregnancy_fertOrificeCheck_enabled, true);
			Scribe_Values.Look(ref egg_pregnancy_eggs_size, "egg_pregnancy_eggs_size", egg_pregnancy_eggs_size, true);
			Scribe_Values.Look(ref egg_pregnancy_ovipositor_capacity_factor, "egg_pregnancy_ovipositor_capacity_factor", egg_pregnancy_ovipositor_capacity_factor, true);
			Scribe_Values.Look(ref mechanoid_pregnancy_enabled, "mechanoid_enabled", mechanoid_pregnancy_enabled, true);
			Scribe_Values.Look(ref safer_mechanoid_pregnancy, "safer_mechanoid_pregnancy", safer_mechanoid_pregnancy, true);
			Scribe_Values.Look(ref use_parent_method, "use_parent_method", use_parent_method, true);
			Scribe_Values.Look(ref humanlike_DNA_from_mother, "humanlike_DNA_from_mother", humanlike_DNA_from_mother, true);
			Scribe_Values.Look(ref bestial_DNA_from_mother, "bestial_DNA_from_mother", bestial_DNA_from_mother, true);
			Scribe_Values.Look(ref bestiality_DNA_inheritance, "bestiality_DNA_inheritance", bestiality_DNA_inheritance, true);
			Scribe_Values.Look(ref humanlike_impregnation_chance, "humanlike_impregnation_chance", humanlike_impregnation_chance, true);
			Scribe_Values.Look(ref animal_impregnation_chance, "animal_impregnation_chance", animal_impregnation_chance, true);
			Scribe_Values.Look(ref interspecies_impregnation_modifier, "interspecies_impregnation_chance", interspecies_impregnation_modifier, true);
			Scribe_Values.Look(ref complex_interspecies, "complex_interspecies", complex_interspecies, true);
			Scribe_Values.Look(ref fertility_endage_male, "RJW_fertility_endAge_male", fertility_endage_male, true);
			Scribe_Values.Look(ref fertility_endage_female_humanlike, "fertility_endage_female_humanlike", fertility_endage_female_humanlike, true);
			Scribe_Values.Look(ref fertility_endage_female_animal, "fertility_endage_female_animal", fertility_endage_female_animal, true);
			Scribe_Values.Look(ref phantasy_pregnancy, "phantasy_pregnancy", phantasy_pregnancy, true);
			Scribe_Values.Look(ref normal_pregnancy_duration, "normal_pregnancy_duration", normal_pregnancy_duration, true);
			Scribe_Values.Look(ref egg_pregnancy_duration, "egg_pregnancy_duration", egg_pregnancy_duration, true);
			Scribe_Values.Look(ref max_num_momtraits_inherited, "max_num_momtraits_inherited", max_num_momtraits_inherited, true);
			Scribe_Values.Look(ref max_num_poptraits_inherited, "max_num_poptraits_inherited", max_num_poptraits_inherited, true);
		}
	}
}