2022-11-04 02:01:50 +00:00
using HarmonyLib ;
2022-11-04 14:08:59 +00:00
using System.Linq ;
2022-11-04 02:01:50 +00:00
using RimWorld ;
using Verse ;
2022-11-11 05:25:07 +00:00
using System.Collections.Generic ;
2022-11-22 06:21:38 +00:00
using System.Reflection ;
2023-01-11 15:32:50 +00:00
using System ;
using System.Reflection.Emit ;
2022-11-04 02:01:50 +00:00
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 ( ) ;
2023-03-01 17:55:54 +00:00
if ( Configurations . Debug ) Log . Message ( $"{comp.Pawn}'s labor starting, menstruation comp is {comp}" ) ;
2022-11-04 02:01:50 +00:00
if ( comp = = null ) return ;
comp . Pregnancy = __instance . pawn . health . hediffSet . GetFirstHediffOfDef ( HediffDefOf . PregnancyLabor ) ;
2023-03-01 17:55:54 +00:00
if ( Configurations . Debug ) Log . Message ( $"New pregnancy Hediff is {comp.Pregnancy}" ) ;
2022-11-04 02:01:50 +00:00
}
}
[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 ( ) ;
2023-03-01 17:55:54 +00:00
if ( Configurations . Debug ) Log . Message ( $"{comp.Pawn}'s initial labor ending, menstruation comp is {comp}" ) ;
2022-11-04 02:01:50 +00:00
if ( comp = = null ) return ;
comp . Pregnancy = __instance . pawn . health . hediffSet . GetFirstHediffOfDef ( HediffDefOf . PregnancyLaborPushing ) ;
2023-03-01 17:55:54 +00:00
if ( Configurations . Debug ) Log . Message ( $"New pregnancy Hediff is {comp.Pregnancy}" ) ;
2022-11-04 02:01:50 +00:00
}
}
[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 ( ) ;
2023-03-01 17:55:54 +00:00
if ( Configurations . Debug ) Log . Message ( $"{comp.Pawn}'s labor pushing ending, menstruation comp is {comp}" ) ;
2022-11-04 02:01:50 +00:00
if ( comp = = null ) return ;
comp . Pregnancy = null ;
}
}
2022-11-04 14:08:59 +00:00
// 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 ;
}
}
2022-11-11 05:25:07 +00:00
[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 ;
}
}
2022-11-11 05:46:42 +00:00
[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 - - ;
}
}
2022-11-11 05:50:31 +00:00
[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 ( ) ;
}
}
2022-11-22 06:21:38 +00:00
2022-11-24 15:12:30 +00:00
[HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))]
2023-01-08 18:11:58 +00:00
public class ApplyBirthOutcome_Breast_Patch
2022-11-24 15:12:30 +00:00
{
public static void PostFix ( Thing birtherThing )
{
if ( birtherThing is Pawn pawn & & ! pawn . health . Dead )
pawn . GetBreastComp ( ) ? . GaveBirth ( ) ;
}
}
2023-01-11 15:32:50 +00:00
[HarmonyPatch]
public class TerminatePregnancy_Patch
2022-11-22 06:21:38 +00:00
{
2023-01-11 15:32:50 +00:00
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 ) ) ;
}
private static PregnancyAttitude ? GetAttitude ( Hediff pregnancy )
{
if ( pregnancy is Hediff_Pregnant preg ) return preg . Attitude ;
else return null ;
}
2022-11-22 06:21:38 +00:00
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 ;
}
2022-12-25 03:44:07 +00:00
2022-11-22 06:21:38 +00:00
return Earliest_Pregnancy ;
}
2023-01-11 15:32:50 +00:00
private static readonly MethodInfo GetPregnancyHediff = AccessTools . Method ( typeof ( PregnancyUtility ) , nameof ( PregnancyUtility . GetPregnancyHediff ) , new Type [ ] { typeof ( Pawn ) } ) ;
private static readonly MethodInfo Get_Attitude = AccessTools . DeclaredPropertyGetter ( typeof ( Hediff_Pregnant ) , nameof ( Hediff_Pregnant . Attitude ) ) ;
2022-11-22 06:21:38 +00:00
public static IEnumerable < CodeInstruction > Transpiler ( IEnumerable < CodeInstruction > instructions )
{
2023-01-11 15:32:50 +00:00
if ( GetPregnancyHediff = = null | | 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" ) ;
2022-11-22 06:21:38 +00:00
foreach ( CodeInstruction instruction in instructions )
{
if ( instruction . Calls ( GetPregnancyHediff ) )
2023-01-11 15:32:50 +00:00
yield return CodeInstruction . Call ( typeof ( TerminatePregnancy_Patch ) , nameof ( TerminatePregnancy_Patch . GetEarliestPregnancy ) ) ;
// 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 ) ;
else if ( instruction . Calls ( Get_Attitude ) )
yield return CodeInstruction . Call ( typeof ( TerminatePregnancy_Patch ) , nameof ( TerminatePregnancy_Patch . GetAttitude ) ) ;
2022-11-22 06:21:38 +00:00
else yield return instruction ;
}
}
2023-01-11 15:32:50 +00:00
}
2022-11-22 06:21:38 +00:00
2023-01-11 15:32:50 +00:00
[HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.TryTerminatePregnancy))]
public class PregnancyUtility_TryTerminatePregnancy_Patch
{
2022-11-22 06:21:38 +00:00
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 ) ;
}
}
2023-01-22 17:44:28 +00:00
[HarmonyPatch(typeof(Pawn_GeneTracker), "AddGene", new Type[] { typeof ( Gene ) , typeof ( bool ) } ) ]
public class AddGene_Patch
{
public static bool Prefix ( ref Gene __result , Gene gene , Pawn ___pawn )
{
if ( VariousDefOf . WombGenes . Contains ( gene . def ) & & ! ___pawn . GetMenstruationComps ( ) . Any ( ) )
{
__result = null ;
return false ;
}
else return true ;
}
}
2023-01-04 06:48:06 +00:00
[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 ( ) ;
}
}
2022-11-04 02:01:50 +00:00
}