diff --git a/1.4/Assemblies/RJW_Menstruation.dll b/1.4/Assemblies/RJW_Menstruation.dll index 4d7a51b..bc84c90 100644 Binary files a/1.4/Assemblies/RJW_Menstruation.dll and b/1.4/Assemblies/RJW_Menstruation.dll differ diff --git a/1.4/Patches/Biosculpter_Patch.xml b/1.4/Patches/Biosculpter_Patch.xml index 558f4b7..cdee9e3 100644 --- a/1.4/Patches/Biosculpter_Patch.xml +++ b/1.4/Patches/Biosculpter_Patch.xml @@ -11,7 +11,7 @@ eggRestoration Restore one year worth of eggs in each womb. - UI/Icon/EggRegeneration + Eggs/Egg 4 diff --git a/1.4/Patches/Hediffs_PrivateParts_Animal.xml b/1.4/Patches/Hediffs_PrivateParts_Animal.xml index fc60760..723eafc 100644 --- a/1.4/Patches/Hediffs_PrivateParts_Animal.xml +++ b/1.4/Patches/Hediffs_PrivateParts_Animal.xml @@ -30,28 +30,6 @@ - - /Defs/rjw.HediffDef_PartBase[defName="CatVagina"] diff --git a/1.4/Textures/UI/Icon/EggRegeneration.png b/1.4/Textures/UI/Icon/EggRegeneration.png deleted file mode 100644 index 3c16583..0000000 Binary files a/1.4/Textures/UI/Icon/EggRegeneration.png and /dev/null differ diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/CompBiosculpterPod_EggRestorationCycle.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/CompBiosclupterPod_EggRestorationCycle.cs similarity index 100% rename from 1.4/source/RJW_Menstruation/RJW_Menstruation/CompBiosculpterPod_EggRestorationCycle.cs rename to 1.4/source/RJW_Menstruation/RJW_Menstruation/CompBiosclupterPod_EggRestorationCycle.cs diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs index 32219a6..78638ee 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs @@ -68,8 +68,6 @@ namespace RJW_Menstruation const int tickInterval = GenDate.TicksPerHour; const int maxImplantDelayHours = 30 * 24; const int minImplantAgeHours = 3 * 24; - const float pulloutSuccessRate = 0.8f; - const float fetishPulloutSuccessModifier = 0.25f; public CompProperties_Menstruation Props; public Stage curStage = Stage.Follicular; @@ -639,7 +637,7 @@ namespace RJW_Menstruation curStage = Stage.Pregnant; } - BeforeSimulator(); + CumOut(); if (pregnancy == null && (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || EggHealth <= 0 || Pawn.SterileGenes())) curStage = Stage.Infertile; switch (curStage) @@ -737,17 +735,10 @@ namespace RJW_Menstruation /// /// /// - /// - public void CumIn(Pawn pawn, float volume, float fertility = 1.0f, bool precum = false) + /// + public void CumIn(Pawn pawn, float volume, float fertility = 1.0f, ThingDef filthdef = null) { if (volume <= 0) return; - if (!precum && fertility > 0 && IsDangerDay && pawn.relations.GetPregnancyApproachForPartner(Pawn) == PregnancyApproach.AvoidPregnancy) - { - float successChance = pulloutSuccessRate; - if (pawn.Has(Quirk.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; - if (Pawn.Has(Quirk.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; - if (Rand.Chance(successChance)) return; - } if (Pawn.HasIUD()) fertility /= 100f; float cumd = TotalCumPercent; float tmp = TotalCum + volume; @@ -759,12 +750,12 @@ namespace RJW_Menstruation { if (cum.pawn.Equals(pawn)) { - cum.MergeWithCum(volume, fertility); + cum.MergeWithCum(volume, fertility, filthdef); merged = true; } cum.DismishForce(cumoutrate); } - if (!merged) cums.Add(new Cum(pawn, volume * (1 - cumoutrate), fertility)); + if (!merged) cums.Add(new Cum(pawn, volume * (1 - cumoutrate), fertility, filthdef)); } else { @@ -774,20 +765,17 @@ namespace RJW_Menstruation { if (cum.pawn.Equals(pawn)) { - cum.MergeWithCum(volume, fertility); + cum.MergeWithCum(volume, fertility, filthdef); merged = true; } } - if (!merged) cums.Add(new Cum(pawn, volume, fertility)); + if (!merged) cums.Add(new Cum(pawn, volume, fertility, filthdef)); } cumd = TotalCumPercent - cumd; - if (!precum) - { - Pawn.records.AddTo(VariousDefOf.AmountofCreampied, volume); - AfterCumIn(pawn); - AfterFluidIn(cumd); - } + Pawn.records.AddTo(VariousDefOf.AmountofCreampied, volume); + AfterCumIn(pawn); + AfterFluidIn(cumd); } /// @@ -1053,7 +1041,6 @@ namespace RJW_Menstruation else if (currentIntervalHours < curStageHrs) curStageHrs = currentIntervalHours; } if (crampPain < 0) crampPain = PainRandomizer(); - InitializeExtraValues(); if (cums == null) cums = new List(); if (eggs == null) eggs = new List(); @@ -1066,10 +1053,6 @@ namespace RJW_Menstruation initError = false; } - protected virtual void InitializeExtraValues() - { - } - protected virtual float RaceCyclesPerYear() { int breedingSeasons = 0; @@ -1135,12 +1118,8 @@ namespace RJW_Menstruation ovarypower = Math.Max(0, (int)(ovarypower * multiply)); } - protected virtual void BeforeSimulator() - { - CumOut(); - } - protected virtual void AfterSimulator() + protected void AfterSimulator() { if (EggHealth < 1f) { @@ -1489,7 +1468,7 @@ namespace RJW_Menstruation protected virtual void LutealAction() { - if (curStageHrs >= currentIntervalHours) + if (curStageHrs > currentIntervalHours) { eggs.Clear(); if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Range(0.0f, 1.0f) < 0.3f)) //skips bleeding @@ -1805,7 +1784,7 @@ namespace RJW_Menstruation GoNextStage(Stage.Pregnant); } - public virtual void CopyCycleProperties(HediffComp_Menstruation original) + public void CopyCycleProperties(HediffComp_Menstruation original) { cycleSpeed = original.cycleSpeed; cycleVariability = original.cycleVariability; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs deleted file mode 100644 index 0026e89..0000000 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs +++ /dev/null @@ -1,103 +0,0 @@ -using RimWorld; -using Verse; - -namespace RJW_Menstruation -{ - public class CompProperties_PeriodicOvulator : CompProperties_Menstruation - { - public FloatRange cycleIntervalDays; // From the start of one cycle to the start of the next - - public CompProperties_PeriodicOvulator() - { - compClass = typeof(HediffComp_PeriodicOvulator); - } - } - - public class HediffComp_PeriodicOvulator : HediffComp_Menstruation - { - public int hoursToNextCycle = -100000; - public int averageCycleIntervalHours = -1; - - public new CompProperties_PeriodicOvulator Props; - - protected override void InitializeExtraValues() - { - base.InitializeExtraValues(); - Props = (CompProperties_PeriodicOvulator)props; - if (averageCycleIntervalHours < 0) - { - averageCycleIntervalHours = (int)(24f * Props.cycleIntervalDays.RandomInRange / cycleSpeed); - if (hoursToNextCycle < -50000) - hoursToNextCycle = Rand.Range(0, averageCycleIntervalHours); - // Make the cutoff halfway into cycle, just to be sure there isn't a double-cycle the first time - if ((curStage == Stage.Follicular || curStage == Stage.Luteal || curStage == Stage.Bleeding) - && (averageCycleIntervalHours - hoursToNextCycle) / 2 >= 24 * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed) - curStage = Stage.Anestrus; - } - } - - protected override float RaceCyclesPerYear() - { - // Don't bother trying to work seasonal breeding into the math - // Due to the enormous variation in possible cycle gaps, cheat and base it off the individual - return averageCycleIntervalHours * cycleSpeed / (24 * 360); // cancel out their cycleSpeed from initialization to get their "normal" speed - } - - protected override void BeforeSimulator() - { - base.BeforeSimulator(); - if (hoursToNextCycle > 0) hoursToNextCycle -= Configurations.CycleAcceleration; - } - - public override void CompExposeData() - { - base.CompExposeData(); - Scribe_Values.Look(ref hoursToNextCycle, "hoursToNextCycle", hoursToNextCycle, true); - Scribe_Values.Look(ref averageCycleIntervalHours, "averageCycleIntervalHours", averageCycleIntervalHours, true); - } - - protected override void BleedingAction() - { - if (curStageHrs >= currentIntervalHours) - { - Hediff hediff = Pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp); - if (hediff != null) Pawn.health.RemoveHediff(hediff); - estrusflag = false; - GoNextStage(Stage.Anestrus); - return; - } - else - { - if (curStageHrs < currentIntervalHours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut(); - curStageHrs += Configurations.CycleAcceleration; - StayCurrentStage(); - } - } - - protected override void PregnantAction() - { - base.PregnantAction(); - if (curStage != Stage.Pregnant) - // Go halfway into the cycle - hoursToNextCycle = (int)(averageCycleIntervalHours * Rand.Range(-cycleVariability, cycleVariability)) / 2; - } - - protected override void AnestrusAction() - { - if (hoursToNextCycle <= 0) - { - hoursToNextCycle = (int)(averageCycleIntervalHours * Rand.Range(-cycleVariability, cycleVariability)); - if (IsBreedingSeason()) GoNextStage(Stage.Follicular); - return; - } - StayCurrentStage(); - } - - public override void CopyCycleProperties(HediffComp_Menstruation original) - { - base.CopyCycleProperties(original); - if (original is HediffComp_PeriodicOvulator comp) - averageCycleIntervalHours = comp.averageCycleIntervalHours; - } - } -} 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 4de0dfa..708596c 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 @@ -1,4 +1,5 @@ using HarmonyLib; +using System; using System.Linq; using RimWorld; using Verse; @@ -177,4 +178,15 @@ namespace RJW_Menstruation } } + [HarmonyPatch(typeof(CompBiosculpterPod), nameof(CompBiosculpterPod.CannotUseNowPawnCycleReason), new Type[] { typeof(Pawn), typeof(Pawn), typeof(CompBiosculpterPod_Cycle), typeof(bool) } )] + public class CannotUseNowPawnCycleReason_Patch + { + private const string eggRestorationKey = "eggRestoration"; + public static void Postfix(ref string __result, Pawn biosculptee, CompBiosculpterPod_Cycle cycle) + { + if (__result != null) return; + if(cycle.Props.key == eggRestorationKey && !biosculptee.GetMenstruationComps().Any()) + __result = Translations.CannotNoWomb; + } + } } \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs index 616f591..97cb9c4 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs @@ -1,8 +1,6 @@ using HarmonyLib; using RimWorld; -using System; using System.Collections.Generic; -using System.Linq; using UnityEngine; using Verse; @@ -20,7 +18,11 @@ namespace RJW_Menstruation comp.Initialize(); } - __instance.GetBreastComp()?.Initialize(); + HediffComp_Breast bcomp = __instance.GetBreastComp(); + if (bcomp != null) + { + bcomp.Initialize(); + } } } @@ -109,15 +111,56 @@ namespace RJW_Menstruation } - [HarmonyPatch(typeof(CompBiosculpterPod), nameof(CompBiosculpterPod.CannotUseNowPawnCycleReason), new Type[] { typeof(Pawn), typeof(Pawn), typeof(CompBiosculpterPod_Cycle), typeof(bool) })] - public class CannotUseNowPawnCycleReason_Patch - { - private const string eggRestorationKey = "eggRestoration"; - public static void Postfix(ref string __result, Pawn biosculptee, CompBiosculpterPod_Cycle cycle) - { - if (__result != null) return; - if (cycle.Props.key == eggRestorationKey && !biosculptee.GetMenstruationComps().Any()) - __result = Translations.CannotNoWomb; - } - } + + //Merged to RJW + //[HarmonyPatch(typeof(PawnColumnWorker_Pregnant), "GetIconFor")] + //public class PawnColumnWorker_Patch_Icon + //{ + // public static void Postfix(Pawn pawn, ref Texture2D __result) + // { + // if (pawn.IsVisiblyPregnant()) __result = ContentFinder.Get("UI/Icons/Animal/Pregnant", true); + // } + // + //} + // + //[HarmonyPatch(typeof(PawnColumnWorker_Pregnant), "GetTooltipText")] + //public class PawnColumnWorker_Patch_Tooltip + //{ + // public static bool Prefix(Pawn pawn, ref string __result) + // { + // float gestationProgress = PregnancyHelper.GetPregnancy(pawn).Severity; + // int num = (int)(pawn.RaceProps.gestationPeriodDays * 60000f); + // int numTicks = (int)(gestationProgress * (float)num); + // __result = "PregnantIconDesc".Translate(numTicks.ToStringTicksToDays("F0"), num.ToStringTicksToDays("F0")); + // return false; + // } + // + //} + // + //[HarmonyPatch(typeof(TransferableUIUtility), "DoExtraAnimalIcons")] + //public class TransferableUIUtility_Patch_Icon + //{ + // //private static readonly Texture2D PregnantIcon = ContentFinder.Get("UI/Icons/Animal/Pregnant", true); + // + // + // + // public static void Postfix(Transferable trad, Rect rect, ref float curX, Texture2D ___PregnantIcon) + // { + // Pawn pawn = trad.AnyThing as Pawn; + // if (pawn?.health?.hediffSet != null && pawn.IsVisiblyPregnant()) + // { + // Rect rect3 = new Rect(curX - 24f, (rect.height - 24f) / 2f, 24f, 24f); + // curX -= 24f; + // if (Mouse.IsOver(rect3)) + // { + // TooltipHandler.TipRegion(rect3, PawnColumnWorker_Pregnant.GetTooltipText(pawn)); + // } + // GUI.DrawTexture(rect3, ___PregnantIcon); + // } + // } + //} + + + + } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs index a32877c..9032766 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs @@ -43,7 +43,7 @@ namespace RJW_Menstruation } else if (Genital_Helper.has_ovipositorM(pawn, pawnparts)) { - comp.CumIn(pawn, Rand.Range(0.75f, 4.5f) * pawn.BodySize, pawn.SterileGenes() ? 0.0f : 1.0f); + comp.CumIn(pawn, Rand.Range(0.75f, 4.5f) * pawn.BodySize, partner.SterileGenes() ? 0.0f : 1.0f); } else comp.CumIn(pawn, pawn.GetCumVolume(pawnparts), 0); @@ -70,7 +70,7 @@ namespace RJW_Menstruation /// /// /// Interaction can result in pregnancy - public static bool InteractionCanCausePregnancy(SexProps props) + private static bool InteractionCanCausePregnancy(SexProps props) { InteractionWithExtension interaction = rjw.Modules.Interactions.Helpers.InteractionHelper.GetWithExtension(props.dictionaryKey); @@ -331,34 +331,6 @@ namespace RJW_Menstruation } } - [HarmonyPatch(typeof(JobDriver_Sex), nameof(JobDriver_Sex.SexTick))] - public static class SexTick_Patch - { - private const float fertilePrecummersPercentage = 0.33f; - private const float precumRatio = 0.1f; // Relative to ejaculation volume - private const float precumFertility = 0.5f; - private const float expectedDurationTicks = 2000f * (0.9f - 0.5f) / 2; - - public static void Postfix(JobDriver_Sex __instance, Pawn pawn, Thing target) - { - if (!pawn.IsHashIntervalTick(__instance.ticks_between_thrusts)) return; - xxx.rjwSextype sextype = __instance.Sexprops.sexType; - if (!(target is Pawn partner) || pawn == partner) return; - if (sextype != xxx.rjwSextype.Vaginal && sextype != xxx.rjwSextype.DoublePenetration) return; - if (__instance.Sexprops.usedCondom) return; - if (!Impregnate_Patch.InteractionCanCausePregnancy(__instance.Sexprops)) return; - - // Archotech penises have more control. Or something. - CompHediffBodyPart penisComp = pawn.GetGenitalsList()?.Find(genital => (genital as Hediff_PartBaseNatural)?.def.defName.ToLower().Contains("penis") ?? false)?.TryGetComp(); - if (penisComp == null || Rand.ChanceSeeded(1.0f - fertilePrecummersPercentage, Gen.HashOffset(penisComp.parent.loadID))) return; - HediffComp_Menstruation vaginaComp = partner.GetRandomMenstruationComp(); - if (vaginaComp == null) return; - - float precumAmount = pawn.GetCumVolume(penisComp) * precumRatio * __instance.ticks_between_thrusts / expectedDurationTicks; - vaginaComp.CumIn(pawn, precumAmount, pawn.SterileGenes() ? 0.0f : precumFertility * pawn.health.capacities.GetLevel(xxx.reproduction), true); - } - } - [HarmonyPatch(typeof(CompHediffBodyPart), nameof(CompHediffBodyPart.updatesize))] public static class Updatesize_Patch { diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj b/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj index 5dd5cdc..1a8b5e3 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj @@ -68,7 +68,6 @@ - diff --git a/changelogs.txt b/changelogs.txt index 146583c..e67ba4d 100644 --- a/changelogs.txt +++ b/changelogs.txt @@ -1,10 +1,6 @@ Version 1.0.8.5 - - Added biosculpter recipe to restore 1 year's worth of eggs, with icon by DestinyPlayer. - - Vaginal sex with the "avoid pregnancy" relation will (usually) pull out prevent cum from entering the womb if there's a risk of pregnancy. - - Impregnation fetishists are significantly less likely to pull out. - - Some males will release small amounts of semen into a womb during vaginal sex before their actual ejaculation. + - Added biosculptor recipe to restore 1 year's worth of eggs. - Babies born from multiple pregnancy will properly produce the prompt to name them. - - Experimental "periodic ovulator" cycle type, currently not used. See Patches/Hediffs_Private_Parts_Animal.xml. Version 1.0.8.4 - Fix Biotech xenotype inheritance for single-child pregnancies.