diff --git a/1.5/Assemblies/RJW_Menstruation.dll b/1.5/Assemblies/RJW_Menstruation.dll index 84270e6..7e99807 100644 Binary files a/1.5/Assemblies/RJW_Menstruation.dll and b/1.5/Assemblies/RJW_Menstruation.dll differ diff --git a/1.5/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs b/1.5/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs index 6732a92..38a25de 100644 --- a/1.5/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs +++ b/1.5/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs @@ -150,7 +150,7 @@ namespace RJW_Menstruation } } - [HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome_NewTemp))] + [HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))] public static class ApplyBirthOutcome_PregeneratedBabies_Patch { private static Pawn GetPregeneratedBaby(PawnGenerationRequest request, Thing birtherThing) @@ -182,7 +182,6 @@ namespace RJW_Menstruation public static IEnumerable Transpiler(IEnumerable instructions) { - bool methodPatched = false; if (birtherThing < 0) throw new InvalidOperationException("Could not locate index of birtherThing"); if (GeneratePawn?.ReturnType != typeof(Pawn)) throw new InvalidOperationException("GeneratePawn not found"); foreach (CodeInstruction instruction in instructions) @@ -191,18 +190,16 @@ namespace RJW_Menstruation { yield return new CodeInstruction(OpCodes.Ldarg, birtherThing); yield return CodeInstruction.Call(typeof(ApplyBirthOutcome_PregeneratedBabies_Patch), nameof(GetPregeneratedBaby)); - methodPatched = true; } else yield return instruction; } - if (!methodPatched) throw new InvalidOperationException("PregnancyUtility.ApplyBirthOutcome_NewTemp not patched"); } } [HarmonyPatch(typeof(Hediff_LaborPushing), nameof(Hediff_LaborPushing.PreRemoved))] public static class Hediff_LaborPushing_PreRemoved_Patch { - private static Thing ApplyBirthLoop(RitualOutcomePossibility outcome, float quality, Precept_Ritual ritual, List genes, Pawn geneticMother, Thing birtherThing, Pawn father, Pawn doctor, LordJob_Ritual lordJobRitual, RitualRoleAssignments assignments, bool preventLetter) + private static Thing ApplyBirthLoop(RitualOutcomePossibility outcome, float quality, Precept_Ritual ritual, List genes, Pawn geneticMother, Thing birtherThing, Pawn father, Pawn doctor, LordJob_Ritual lordJobRitual, RitualRoleAssignments assignments) { if (birtherThing is Pawn mother) { @@ -218,7 +215,7 @@ namespace RJW_Menstruation Pawn thisFather = baby.GetFather() ?? father; baby.relations.ClearAllRelations(); // To keep ApplyBirthOutcome from erroring when it tries to set up relations - PregnancyUtility.ApplyBirthOutcome_NewTemp(thisOutcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments, preventLetter); + PregnancyUtility.ApplyBirthOutcome(thisOutcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments); // No more babies if mom dies halfway through. Unrealistic maybe, but saves a lot of headache in ApplyBirthOutcome if (mother.Dead) break; if (xxx.is_human(baby)) @@ -233,25 +230,20 @@ namespace RJW_Menstruation } } - return PregnancyUtility.ApplyBirthOutcome_NewTemp(outcome, quality, ritual, genes, geneticMother, birtherThing, father, doctor, lordJobRitual, assignments, preventLetter); + return PregnancyUtility.ApplyBirthOutcome(outcome, quality, ritual, genes, geneticMother, birtherThing, father, doctor, lordJobRitual, assignments); } - private static readonly MethodInfo ApplyBirthOutcome_NewTemp = typeof(PregnancyUtility).GetMethod(nameof(PregnancyUtility.ApplyBirthOutcome_NewTemp), - new Type[] {typeof(RitualOutcomePossibility), typeof(float), typeof(Precept_Ritual), typeof(List), typeof(Pawn), typeof(Thing), typeof(Pawn), typeof(Pawn), typeof(LordJob_Ritual), typeof(RitualRoleAssignments), typeof(bool)}); + private static readonly MethodInfo ApplyBirthOutcome = typeof(PregnancyUtility).GetMethod(nameof(PregnancyUtility.ApplyBirthOutcome), + new Type[] {typeof(RitualOutcomePossibility), typeof(float), typeof(Precept_Ritual), typeof(List), typeof(Pawn), typeof(Thing), typeof(Pawn), typeof(Pawn), typeof(LordJob_Ritual), typeof(RitualRoleAssignments)}); public static IEnumerable Transpiler(IEnumerable instructions) { - bool methodPatched = false; - if (ApplyBirthOutcome_NewTemp?.ReturnType != typeof(Thing)) throw new InvalidOperationException("ApplyBirthOutcome_NewTemp not found"); + if (ApplyBirthOutcome?.ReturnType != typeof(Thing)) throw new InvalidOperationException("ApplyBirthOutcome not found"); foreach (CodeInstruction instruction in instructions) { - if (instruction.Calls(ApplyBirthOutcome_NewTemp)) - { + if (instruction.Calls(ApplyBirthOutcome)) yield return CodeInstruction.Call(typeof(Hediff_LaborPushing_PreRemoved_Patch), nameof(Hediff_LaborPushing_PreRemoved_Patch.ApplyBirthLoop)); - methodPatched = true; - } else yield return instruction; } - if (!methodPatched) throw new InvalidOperationException("Hediff_LaborPushing.PreRemoved not patched"); } } @@ -291,23 +283,17 @@ namespace RJW_Menstruation } return PregnancyUtility.ApplyBirthOutcome(outcome, quality, ritual, genes, geneticMother, birtherThing, father, doctor, lordJobRitual, assignments); } - // RitualOutcomeEffectWorker_ChildBirth.Apply does not call ApplyBirthOutcome_NewTemp private static readonly MethodInfo ApplyBirthOutcome = typeof(PregnancyUtility).GetMethod(nameof(PregnancyUtility.ApplyBirthOutcome), new Type[] { typeof(RitualOutcomePossibility), typeof(float), typeof(Precept_Ritual), typeof(List), typeof(Pawn), typeof(Thing), typeof(Pawn), typeof(Pawn), typeof(LordJob_Ritual), typeof(RitualRoleAssignments) }); public static IEnumerable Transpiler(IEnumerable instructions) { - bool methodPatched = false; if (ApplyBirthOutcome?.ReturnType != typeof(Thing)) throw new InvalidOperationException("ApplyBirthOutcome not found"); foreach (CodeInstruction instruction in instructions) { if (instruction.Calls(ApplyBirthOutcome)) - { yield return CodeInstruction.Call(typeof(Ritual_ChildBirth_Apply_Patch), nameof(Ritual_ChildBirth_Apply_Patch.ApplyBirthLoop)); - methodPatched = true; - } else yield return instruction; } - if (!methodPatched) throw new InvalidOperationException("RitualOutcomeEffectWorker_ChildBirth.Apply not patched"); } } diff --git a/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs b/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs index 7f5468f..0125f26 100644 --- a/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs +++ b/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs @@ -128,7 +128,7 @@ namespace RJW_Menstruation public static IEnumerable TargetMethods() { yield return AccessTools.Method(typeof(PregnancyUtility), nameof(PregnancyUtility.TryTerminatePregnancy)); -// yield return AccessTools.Method(typeof(Recipe_TerminatePregnancy), nameof(Recipe_TerminatePregnancy.ApplyOnPawn)); + yield return AccessTools.Method(typeof(Recipe_TerminatePregnancy), nameof(Recipe_TerminatePregnancy.ApplyOnPawn)); } private static PregnancyAttitude? GetAttitude(Hediff pregnancy) @@ -155,30 +155,19 @@ namespace RJW_Menstruation public static IEnumerable Transpiler(IEnumerable instructions) { - int methodPatched = 0; if (GetPregnancyHediff?.ReturnType != typeof(Hediff)) throw new InvalidOperationException("GetPregnancyHediff not found"); if (Get_Attitude == null || Nullable.GetUnderlyingType(Get_Attitude.ReturnType) != typeof(PregnancyAttitude)) throw new InvalidOperationException("get_Attitude not found"); foreach (CodeInstruction instruction in instructions) { if (instruction.Calls(GetPregnancyHediff)) - { yield return CodeInstruction.Call(typeof(TerminatePregnancy_Patch), nameof(TerminatePregnancy_Patch.GetEarliestPregnancy)); - methodPatched++; - } // Menstruation pregnancies don't have an attitude, so skip the cast to Hediff_Pregnant and call a version that handles it else if (instruction.opcode == OpCodes.Castclass && (Type)instruction.operand == typeof(Hediff_Pregnant)) - { yield return new CodeInstruction(OpCodes.Nop); - methodPatched++; - } else if (instruction.Calls(Get_Attitude)) - { yield return CodeInstruction.Call(typeof(TerminatePregnancy_Patch), nameof(TerminatePregnancy_Patch.GetAttitude)); - methodPatched++; - } else yield return instruction; } - if (methodPatched != 3) throw new InvalidOperationException($"PregnancyUtility.TryTerminatePregnancy or Recipe_TerminatePregnancy.ApplyOnPawn not patched ({methodPatched}"); } } diff --git a/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs b/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs index d4a6f94..e02c665 100644 --- a/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs +++ b/1.5/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs @@ -3,7 +3,6 @@ using RimWorld; using rjw; using rjw.Modules.Interactions.Enums; using rjw.Modules.Interactions.Objects; -using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -133,18 +132,13 @@ namespace RJW_Menstruation private static readonly MethodInfo IsPregnant = AccessTools.Method(typeof(PawnExtensions), nameof(PawnExtensions.IsPregnant), new System.Type[] { typeof(Pawn), typeof(bool) }); public static IEnumerable Transpiler(IEnumerable instructions) { - bool methodPatched = false; if (IsPregnant?.ReturnType != typeof(bool)) throw new System.InvalidOperationException("IsPregnant not found"); foreach (CodeInstruction instruction in instructions) { if (instruction.Calls(IsPregnant)) - { yield return CodeInstruction.Call(typeof(CanImpregnate_Patch), nameof(PregnancyBlocksImpregnation)); - methodPatched = true; - } else yield return instruction; } - if (!methodPatched) throw new InvalidOperationException("PregnancyHelper.CanImpregnate not patched"); } } @@ -244,7 +238,6 @@ namespace RJW_Menstruation private static readonly FieldInfo MinimumFuckabilityToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumFuckabilityToHookup)); public static IEnumerable Transpiler(IEnumerable instructions) { - bool methodPatched = false; if (MinimumFuckabilityToHookup?.FieldType != typeof(float)) throw new System.InvalidOperationException("MinimumFuckabilityToHookup not found"); bool first_fuckability = true; foreach (CodeInstruction instruction in instructions) @@ -257,11 +250,9 @@ namespace RJW_Menstruation yield return CodeInstruction.Call(typeof(Roll_To_Skip_Patch), nameof(FuckabilityThreshold)); first_fuckability = false; - methodPatched = true; } else yield return instruction; } - if (!methodPatched) throw new InvalidOperationException("CasualSex_Helper.roll_to_skip not patched"); } } @@ -283,7 +274,6 @@ namespace RJW_Menstruation private static readonly FieldInfo MinimumRelationshipToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumRelationshipToHookup)); public static IEnumerable Transpiler(IEnumerable instructions) { - int methodPatched = 0; if (MinimumAttractivenessToHookup?.FieldType != typeof(float)) throw new System.InvalidOperationException("MinimumAttractivenessToHookup not found"); if (MinimumRelationshipToHookup?.FieldType != typeof(float)) throw new System.InvalidOperationException("MinimumRelationshipToHookup not found"); LocalBuilder pawn_index = null; @@ -297,7 +287,6 @@ namespace RJW_Menstruation { // a future RJW or compiler update might change this, or maybe another mod's patch pawn_index = (LocalBuilder)instruction.operand; yield return instruction; - methodPatched++; } else if (instruction.LoadsField(MinimumAttractivenessToHookup)) { @@ -309,7 +298,6 @@ namespace RJW_Menstruation yield return CodeInstruction.Call(typeof(FindBestPartner_Patch), nameof(AttractivenessThreshold)); first_attractiveness = false; - methodPatched++; } else if (instruction.LoadsField(MinimumRelationshipToHookup)) { @@ -321,12 +309,9 @@ namespace RJW_Menstruation yield return CodeInstruction.Call(typeof(FindBestPartner_Patch), nameof(RelationshipThreshold)); first_relationship = false; - methodPatched++; } else yield return instruction; } - // 5 because each LoadsField gets checked twice - if (methodPatched != 5) throw new System.InvalidOperationException($"CasualSex_Helper.FindBestPartner not patched ({methodPatched})"); } } diff --git a/1.5/source/RJW_Menstruation/RJW_Menstruation/PregnancyCommon.cs b/1.5/source/RJW_Menstruation/RJW_Menstruation/PregnancyCommon.cs index 324ff39..9b9bdad 100644 --- a/1.5/source/RJW_Menstruation/RJW_Menstruation/PregnancyCommon.cs +++ b/1.5/source/RJW_Menstruation/RJW_Menstruation/PregnancyCommon.cs @@ -97,39 +97,53 @@ namespace RJW_Menstruation bool IsAndroidmother = AndroidsCompatibility.IsAndroid(mother); bool IsAndroidfather = AndroidsCompatibility.IsAndroid(father); - if (IsAndroidmother != IsAndroidfather) - spawn_kind_def = IsAndroidmother ? fatherKindDef : motherKindDef; - - string MotherRaceName = motherKindDef?.race?.defName; - string FatherRaceName = fatherKindDef?.race?.defName; - - if (MotherRaceName != FatherRaceName && !FatherRaceName.NullOrEmpty()) + if (IsAndroidmother && !IsAndroidfather) { - PawnKindDef hybridPawnKind = Configurations.UseHybridExtention ? GetHybrid(father, mother) : null; - if (hybridPawnKind != null) - { - spawn_kind_def = hybridPawnKind; - } - else + spawn_kind_def = fatherKindDef; + } + else if (!IsAndroidmother && IsAndroidfather) + { + spawn_kind_def = motherKindDef; + } + + string MotherRaceName = ""; + string FatherRaceName = ""; + MotherRaceName = motherKindDef?.race?.defName; + PawnKindDef non_hybrid_kind_def = spawn_kind_def; + if (father != null) + FatherRaceName = fatherKindDef?.race?.defName; + + + if (FatherRaceName != "" && Configurations.UseHybridExtention) + { + spawn_kind_def = GetHybrid(father, mother); + //Log.Message("pawnkind: " + spawn_kind_def?.defName); + } + + if (MotherRaceName != FatherRaceName && FatherRaceName != "") + { + if (!Configurations.UseHybridExtention || spawn_kind_def == null) { + spawn_kind_def = non_hybrid_kind_def; IEnumerable groups = DefDatabase.AllDefs.Where(x => !(x.hybridRaceParents.NullOrEmpty() || x.hybridChildKindDef.NullOrEmpty())); + //ModLog.Message(" found custom RaceGroupDefs " + groups.Count()); - foreach (RaceGroupDef def in groups) + foreach (RaceGroupDef t in groups) { - if ((def.hybridRaceParents.Contains(MotherRaceName) && def.hybridRaceParents.Contains(FatherRaceName)) - || (def.hybridRaceParents.Contains("Any") && (def.hybridRaceParents.Contains(MotherRaceName) || def.hybridRaceParents.Contains(FatherRaceName)))) + if ((t.hybridRaceParents.Contains(MotherRaceName) && t.hybridRaceParents.Contains(FatherRaceName)) + || (t.hybridRaceParents.Contains("Any") && (t.hybridRaceParents.Contains(MotherRaceName) || t.hybridRaceParents.Contains(FatherRaceName)))) { //ModLog.Message(" has hybridRaceParents"); - if (def.hybridChildKindDef.Contains("MotherKindDef")) + if (t.hybridChildKindDef.Contains("MotherKindDef")) spawn_kind_def = motherKindDef; - else if (def.hybridChildKindDef.Contains("FatherKindDef") && father != null) + else if (t.hybridChildKindDef.Contains("FatherKindDef") && father != null) spawn_kind_def = fatherKindDef; else { //ModLog.Message(" trying hybridChildKindDef " + t.defName); List child_kind_def_list = new List(); - child_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => def.hybridChildKindDef.Contains(x.defName))); + child_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => t.hybridChildKindDef.Contains(x.defName))); //ModLog.Message(" found custom hybridChildKindDefs " + t.hybridChildKindDef.Count); if (!child_kind_def_list.NullOrEmpty()) @@ -138,10 +152,12 @@ namespace RJW_Menstruation } } } - } - if (spawn_kind_def == null) + } + else if (!Configurations.UseHybridExtention || spawn_kind_def == null) + { spawn_kind_def = mother.RaceProps?.AnyPawnKind ?? motherKindDef; + } if (spawn_kind_def.defName.Contains("Nymph")) {