mirror of
https://gitgud.io/lutepickle/rjw_menstruation.git
synced 2024-08-14 22:46:52 +00:00
Fix transpiler pointing towards old version of ApplyBirthOutcome, add checks to all transpilers that they are actually applied
This commit is contained in:
parent
7e4518a98a
commit
bfcb469969
4 changed files with 49 additions and 9 deletions
Binary file not shown.
|
@ -150,7 +150,7 @@ namespace RJW_Menstruation
|
|||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))]
|
||||
[HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome_NewTemp))]
|
||||
public static class ApplyBirthOutcome_PregeneratedBabies_Patch
|
||||
{
|
||||
private static Pawn GetPregeneratedBaby(PawnGenerationRequest request, Thing birtherThing)
|
||||
|
@ -182,6 +182,7 @@ namespace RJW_Menstruation
|
|||
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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)
|
||||
|
@ -190,16 +191,18 @@ 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<GeneDef> genes, Pawn geneticMother, Thing birtherThing, Pawn father, Pawn doctor, LordJob_Ritual lordJobRitual, RitualRoleAssignments assignments)
|
||||
private static Thing ApplyBirthLoop(RitualOutcomePossibility outcome, float quality, Precept_Ritual ritual, List<GeneDef> genes, Pawn geneticMother, Thing birtherThing, Pawn father, Pawn doctor, LordJob_Ritual lordJobRitual, RitualRoleAssignments assignments, bool preventLetter)
|
||||
{
|
||||
if (birtherThing is Pawn mother)
|
||||
{
|
||||
|
@ -215,7 +218,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(thisOutcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments);
|
||||
PregnancyUtility.ApplyBirthOutcome_NewTemp(thisOutcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments, preventLetter);
|
||||
// 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))
|
||||
|
@ -230,20 +233,25 @@ namespace RJW_Menstruation
|
|||
}
|
||||
}
|
||||
|
||||
return PregnancyUtility.ApplyBirthOutcome(outcome, quality, ritual, genes, geneticMother, birtherThing, father, doctor, lordJobRitual, assignments);
|
||||
return PregnancyUtility.ApplyBirthOutcome_NewTemp(outcome, quality, ritual, genes, geneticMother, birtherThing, father, doctor, lordJobRitual, assignments, preventLetter);
|
||||
}
|
||||
|
||||
private static readonly MethodInfo ApplyBirthOutcome = typeof(PregnancyUtility).GetMethod(nameof(PregnancyUtility.ApplyBirthOutcome),
|
||||
new Type[] {typeof(RitualOutcomePossibility), typeof(float), typeof(Precept_Ritual), typeof(List<GeneDef>), typeof(Pawn), typeof(Thing), typeof(Pawn), typeof(Pawn), typeof(LordJob_Ritual), typeof(RitualRoleAssignments)});
|
||||
private static readonly MethodInfo ApplyBirthOutcome_NewTemp = typeof(PregnancyUtility).GetMethod(nameof(PregnancyUtility.ApplyBirthOutcome_NewTemp),
|
||||
new Type[] {typeof(RitualOutcomePossibility), typeof(float), typeof(Precept_Ritual), typeof(List<GeneDef>), typeof(Pawn), typeof(Thing), typeof(Pawn), typeof(Pawn), typeof(LordJob_Ritual), typeof(RitualRoleAssignments), typeof(bool)});
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
|
||||
{
|
||||
if (ApplyBirthOutcome?.ReturnType != typeof(Thing)) throw new InvalidOperationException("ApplyBirthOutcome not found");
|
||||
bool methodPatched = false;
|
||||
if (ApplyBirthOutcome_NewTemp?.ReturnType != typeof(Thing)) throw new InvalidOperationException("ApplyBirthOutcome_NewTemp not found");
|
||||
foreach (CodeInstruction instruction in instructions)
|
||||
{
|
||||
if (instruction.Calls(ApplyBirthOutcome))
|
||||
if (instruction.Calls(ApplyBirthOutcome_NewTemp))
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,17 +291,23 @@ 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<GeneDef>), typeof(Pawn), typeof(Thing), typeof(Pawn), typeof(Pawn), typeof(LordJob_Ritual), typeof(RitualRoleAssignments) });
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace RJW_Menstruation
|
|||
public static IEnumerable<MethodBase> 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,19 +155,30 @@ namespace RJW_Menstruation
|
|||
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ 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;
|
||||
|
@ -132,13 +133,18 @@ 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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +244,7 @@ namespace RJW_Menstruation
|
|||
private static readonly FieldInfo MinimumFuckabilityToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumFuckabilityToHookup));
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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)
|
||||
|
@ -250,9 +257,11 @@ 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,6 +283,7 @@ namespace RJW_Menstruation
|
|||
private static readonly FieldInfo MinimumRelationshipToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumRelationshipToHookup));
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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;
|
||||
|
@ -287,6 +297,7 @@ 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))
|
||||
{
|
||||
|
@ -298,6 +309,7 @@ namespace RJW_Menstruation
|
|||
|
||||
yield return CodeInstruction.Call(typeof(FindBestPartner_Patch), nameof(AttractivenessThreshold));
|
||||
first_attractiveness = false;
|
||||
methodPatched++;
|
||||
}
|
||||
else if (instruction.LoadsField(MinimumRelationshipToHookup))
|
||||
{
|
||||
|
@ -309,9 +321,12 @@ 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})");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue