rjw_menstruation/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs

189 lines
7.3 KiB
C#

using HarmonyLib;
using System.Linq;
using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Reflection;
namespace RJW_Menstruation
{
[HarmonyPatch(typeof(Hediff_Pregnant), "Miscarry")]
public class Miscarry_Patch
{
public static void Postfix(Hediff_Pregnant __instance)
{
HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy();
if (comp == null) return;
comp.Pregnancy = null;
}
}
[HarmonyPatch(typeof(Hediff_Pregnant), nameof(Hediff_Pregnant.StartLabor))]
public class StartLabor_Patch
{
public static void Postfix(Hediff_Pregnant __instance)
{
HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy();
if (comp == null) return;
comp.Pregnancy = __instance.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.PregnancyLabor);
}
}
[HarmonyPatch(typeof(Hediff_Labor), nameof(Hediff_Labor.PreRemoved))]
public class Labor_PreRemoved_Patch
{
public static void PostFix(Hediff_Labor __instance)
{
HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy();
if (comp == null) return;
comp.Pregnancy = __instance.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.PregnancyLaborPushing);
}
}
[HarmonyPatch(typeof(Hediff_LaborPushing), nameof(Hediff_LaborPushing.PreRemoved))]
public class LaborPushing_PreRemoved_Patch
{
public static void PostFix(Hediff_LaborPushing __instance)
{
HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy();
if (comp == null) return;
comp.Pregnancy = null;
}
}
// Prevents a pregnancy from going into labor if another pregnancy already is
[HarmonyPatch(typeof(Hediff_Pregnant), nameof(Hediff_Pregnant.GestationProgress), MethodType.Getter)]
public class Hediff_Pregnant_GestationProgess_Patch
{
public static void PostFix(Hediff_Pregnant __instance, ref float __result)
{
if (__result < 1f) return;
Pawn pawn = __instance.pawn;
if (pawn.health.hediffSet.hediffs.Any(hediff => hediff.def == HediffDefOf.PregnancyLabor || hediff.def == HediffDefOf.PregnancyLaborPushing))
__result = 0.999f;
}
}
[HarmonyPatch(typeof(Recipe_ExtractOvum), nameof(Recipe_ExtractOvum.AvailableReport))]
public class ExtractOvum_AvailableReport_Patch
{
public static void PostFix(Thing thing, ref AcceptanceReport __result)
{
if (!__result.Accepted) return;
Pawn pawn = (Pawn)thing;
if (pawn.IsRJWPregnant())
{
__result = "CannotPregnant".Translate();
return;
}
List<HediffComp_Menstruation> comps = pawn.GetMenstruationComps().ToList();
if (!comps.Any()) return;
if (comps.All(comp => comp.ovarypower <= 0))
{
__result = Translations.CannotNoEggs;
return;
}
return;
}
}
[HarmonyPatch(typeof(Recipe_ExtractOvum), "OnSurgerySuccess")]
public class ExtractOvum_OnSurgerySuccess_Patch
{
public static void PostFix(Pawn pawn)
{
List<HediffComp_Menstruation> comps = pawn.GetMenstruationComps().ToList();
if (!comps.Any()) return;
HediffComp_Menstruation mostEggs = comps.MaxBy(comp => comp.ovarypower);
if (mostEggs.ovarypower <= 0) return; // Shouldn't happen
mostEggs.ovarypower--;
}
}
[HarmonyPatch(typeof(Recipe_ImplantEmbryo), nameof(Recipe_ImplantEmbryo.ApplyOnPawn))]
public class ImplantEmbryo_ApplyOnPawn_Patch
{
public static void PostFix(Pawn pawn)
{
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
comp.TakeLoosePregnancy();
}
}
[HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))]
public class ApplyBirthOutcome_Patch
{
public static void PostFix(Thing birtherThing)
{
if (birtherThing is Pawn pawn && !pawn.health.Dead)
pawn.GetBreastComp()?.GaveBirth();
}
}
[HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.TryTerminatePregnancy))]
public class TryTerminatePregnancy_Patch
{
private static Hediff GetEarliestPregnancy(Pawn pawn)
{
Hediff Earliest_Pregnancy = PregnancyUtility.GetPregnancyHediff(pawn);
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
{
Hediff pregnancy = comp.Pregnancy;
if (pregnancy == null) continue;
if (Earliest_Pregnancy == null || Earliest_Pregnancy.Severity > pregnancy.Severity) Earliest_Pregnancy = pregnancy;
}
return Earliest_Pregnancy;
}
private static readonly MethodInfo GetPregnancyHediff = AccessTools.Method(typeof(PregnancyUtility), nameof(PregnancyUtility.GetPregnancyHediff), new System.Type[] { typeof(Pawn) });
// Also called for Recipe_TerminatePregnancy.ApplyOnPawn
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
if (GetPregnancyHediff == null || GetPregnancyHediff.ReturnType != typeof(Hediff)) throw new System.InvalidOperationException("GetPregnancyHediff not found");
foreach (CodeInstruction instruction in instructions)
{
if (instruction.Calls(GetPregnancyHediff))
yield return CodeInstruction.Call(typeof(TryTerminatePregnancy_Patch), nameof(TryTerminatePregnancy_Patch.GetEarliestPregnancy));
else yield return instruction;
}
}
public static void Postfix(bool __result, Pawn pawn)
{
if (__result)
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
_ = comp.Pregnancy; // get_Pregnancy will remove the hediff attached to the comp that doesn't have it anymore
}
}
[HarmonyPatch(typeof(Recipe_TerminatePregnancy), nameof(Recipe_TerminatePregnancy.AvailableOnNow))]
public class TerminatePregnancy_AvailableOnNow_Patch
{
public static void Postfix(ref bool __result, Thing thing)
{
if (!ModsConfig.BiotechActive || !(thing is Pawn pawn)) return;
__result |= pawn.GetMenstruationComps().Any(comp => comp.Pregnancy != null);
}
}
[HarmonyPatch(typeof(Recipe_TerminatePregnancy), nameof(Recipe_TerminatePregnancy.ApplyOnPawn))]
public class TerminatePregnancy_ApplyOnPawn_Patch
{
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return TryTerminatePregnancy_Patch.Transpiler(instructions);
}
}
[HarmonyPatch(typeof(Pawn_GeneTracker), "Notify_GenesChanged")]
public class Notify_GenesChanged_Patch
{
public static void Postfix(Pawn_GeneTracker __instance)
{
foreach (HediffComp_Menstruation comp in __instance.pawn.GetMenstruationComps())
comp.Notify_UpdatedGenes();
}
}
}