From e42bbdb3d48b44bfb74cd1e8c2c2ed35de88f55a Mon Sep 17 00:00:00 2001 From: lutepickle <28810-lutepickle@users.noreply.gitgud.io> Date: Sun, 8 Jan 2023 10:11:58 -0800 Subject: [PATCH] Add the ApplyBirthOutcome transpiler --- .../RJW_Menstruation/Configurations.cs | 2 + .../HediffComp_PregeneratedBabies.cs | 51 +++++++++++++++++-- .../RJW_Menstruation/Patch/Biotech_Patch.cs | 2 +- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs index 6a843bb..c496fb6 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs @@ -55,6 +55,7 @@ namespace RJW_Menstruation public static float EstrusAttractivenessToHookup = RJWHookupSettings.MinimumAttractivenessToHookup; public static float EstrusRelationshipToHookup = RJWHookupSettings.MinimumRelationshipToHookup; public static PregnancyType PregnancySource = PregnancyType.MultiplePregnancy; + public static bool EnableBiotechTwins = false; public static bool EnableHeteroOvularTwins = true; public static bool EnableEnzygoticTwins = true; public static float EnzygoticTwinsChance = EnzygoticTwinsChanceDefault; @@ -89,6 +90,7 @@ namespace RJW_Menstruation EstrusAttractivenessToHookup = RJWHookupSettings.MinimumAttractivenessToHookup; EstrusRelationshipToHookup = RJWHookupSettings.MinimumRelationshipToHookup; EnzygoticTwinsChanceAdjust = EnzygoticTwinsChanceAdjustDefault; + EnableBiotechTwins = false; EnableEnzygoticTwins = true; EnableHeteroOvularTwins = true; PregnancySource = PregnancyType.MultiplePregnancy; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs index 8831540..f0d8ef2 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs @@ -1,10 +1,12 @@ -using RimWorld; -using RimWorld.BaseGen; +using HarmonyLib; +using Mono.Cecil.Cil; +using RimWorld; using rjw; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using Verse; namespace RJW_Menstruation @@ -93,7 +95,7 @@ namespace RJW_Menstruation { Pawn baby = PawnGenerator.GeneratePawn(request); if (baby == null) break; - PregnancyCommon.SetupBabyXenotype(mother, father, baby); + PregnancyCommon.SetupBabyXenotype(mother, father, baby); // Probably redundant with Biotech post-birth xenotyping if (division > 1) { if (i == 0) @@ -136,4 +138,47 @@ namespace RJW_Menstruation } } } + + [HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))] + public static class ApplyBirthOutcome_PregeneratedBabies_Patch + { + private static Pawn GetPregeneratedBaby(PawnGenerationRequest request, Thing birtherThing) + { + // Don't test for the config set here. We can do it at the functions that call ApplyBirthOutcome + // Easier to work out twins that way + + // From e.g. a vat + if (!(birtherThing is Pawn mother) || !xxx.is_human(mother)) + return PawnGenerator.GeneratePawn(request); + + // No babies found. Could be an unmodified pregnancy + HediffComp_PregeneratedBabies comp = mother.health.hediffSet.GetFirstHediff()?.TryGetComp(); + if (comp == null || !comp.HasBaby) + return PawnGenerator.GeneratePawn(request); + + Pawn baby = comp.PopBaby(); + if (baby == null) return PawnGenerator.GeneratePawn(request); // Shouldn't happen + if (request.ForceDead) baby.Kill(null, null); + return baby; + } + + private static readonly MethodInfo ApplyBirthOutcome = typeof(PregnancyUtility).GetMethod(nameof(PregnancyUtility.ApplyBirthOutcome)); + private static readonly int birtherThing = ApplyBirthOutcome.GetParameters().FirstIndexOf(parameter => parameter.Name == "birtherThing" && parameter.ParameterType == typeof(Thing)); + private static readonly MethodInfo GeneratePawn = typeof(PawnGenerator).GetMethod(nameof(PawnGenerator.GeneratePawn), new Type[] {typeof (PawnGenerationRequest)}); + + public static IEnumerable Transpiler(IEnumerable instructions) + { + if (birtherThing < 0) throw new InvalidOperationException("Could not locate index of birtherThing"); + if (GeneratePawn == null || GeneratePawn.ReturnType != typeof(Pawn)) throw new InvalidOperationException("GeneratePawn not found"); + foreach (CodeInstruction instruction in instructions) + { + if (instruction.Calls(GeneratePawn)) + { + yield return new CodeInstruction(OpCodes.Ldarg, birtherThing); + yield return CodeInstruction.Call(typeof(ApplyBirthOutcome_PregeneratedBabies_Patch), nameof(GetPregeneratedBaby)); + } + else yield return instruction; + } + } + } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs index 7d9de72..c60d3b4 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs @@ -111,7 +111,7 @@ namespace RJW_Menstruation } [HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))] - public class ApplyBirthOutcome_Patch + public class ApplyBirthOutcome_Breast_Patch { public static void PostFix(Thing birtherThing) {