diff --git a/About/Manifest.xml b/About/Manifest.xml index 0b0a172..ced33c3 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ RJW Menstruation - 1.0.1.12 + 1.0.1.13 diff --git a/Assemblies/RJW_Menstruation.dll b/Assemblies/RJW_Menstruation.dll index 96e0961..977494d 100644 Binary files a/Assemblies/RJW_Menstruation.dll and b/Assemblies/RJW_Menstruation.dll differ diff --git a/Patches/Hediffs_PrivateParts_Animal.xml b/Patches/Hediffs_PrivateParts_Animal.xml index a38eb4c..bd4560a 100644 --- a/Patches/Hediffs_PrivateParts_Animal.xml +++ b/Patches/Hediffs_PrivateParts_Animal.xml @@ -36,19 +36,20 @@ Defs/rjw.HediffDef_PartBase[defName="CatVagina"] -
  • +
  • 6 1.0 2.0 0.05 - 6 - 14 + 9 + 10 0 15 - 14 + 1 Womb/Womb Genitals/Vagina FirstHalf + 9
  • @@ -126,19 +127,19 @@ Defs/rjw.HediffDef_PartBase[defName="RodentVagina"] -
  • +
  • 5 1.0 2.0 0.05 - 2 - 7 + 6 + 9 0 3 - 7 + 1 Womb/Womb Genitals/Vagina - 1 + 6
  • diff --git a/changelogs.txt b/changelogs.txt index 1ff7c19..0574f05 100644 --- a/changelogs.txt +++ b/changelogs.txt @@ -1,3 +1,8 @@ +Version 1.0.1.13 + - requires RJW 4.6.1 or later + - added induced ovulator + - fenline and rodent vagina ovulate after sex in follicular stage + - minor bug fix Version 1.0.1.12 - requires RJW 4.6.1 or later - added HybridExtension attribute to PawnDNAModExtension diff --git a/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvaulator.cs b/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvaulator.cs new file mode 100644 index 0000000..cf0c068 --- /dev/null +++ b/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvaulator.cs @@ -0,0 +1,64 @@ +using HugsLib; +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class CompProperties_InducedOvulator : CompProperties_Menstruation + { + public CompProperties_InducedOvulator() + { + compClass = typeof(HediffComp_InducedOvulator); + } + + } + + public class HediffComp_InducedOvulator : HediffComp_Menstruation + { + protected override void FollicularAction() + { + if (!IsBreedingSeason()) + { + GoNextStage(Stage.Anestrus); + return; + } + if (curStageHrs >= FollicularIntervalHours) + { + GoNextStage(Stage.Luteal); + } + else + { + curStageHrs += Configurations.CycleAcceleration; + if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24) + { + estrusflag = true; + SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation); + } + StayCurrentStage(); + } + } + + public override void AfterCumIn(Pawn cummer) + { + base.AfterCumIn(cummer); + if (curStage == Stage.Follicular) curStage = Stage.Ovulatory; + } + + + + } + + + + + + + + + +} diff --git a/source/RJW_Menstruation/RJW_Menstruation/HediffComp_Menstruation.cs b/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs similarity index 86% rename from source/RJW_Menstruation/RJW_Menstruation/HediffComp_Menstruation.cs rename to source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs index cccbb8f..b3df198 100644 --- a/source/RJW_Menstruation/RJW_Menstruation/HediffComp_Menstruation.cs +++ b/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs @@ -97,18 +97,18 @@ namespace RJW_Menstruation Anestrus } - private List cums; - private List eggs; - private int follicularIntervalhours = -1; - private int lutealIntervalhours = -1; - private int bleedingIntervalhours = -1; - private int recoveryIntervalhours = -1; - private float crampPain = -1; - private Need sexNeed = null; - private string customwombtex = null; - private string customvagtex = null; - private bool estrusflag = false; - private int opcache = -1; + protected List cums; + protected List eggs; + protected int follicularIntervalhours = -1; + protected int lutealIntervalhours = -1; + protected int bleedingIntervalhours = -1; + protected int recoveryIntervalhours = -1; + protected float crampPain = -1; + protected Need sexNeed = null; + protected string customwombtex = null; + protected string customvagtex = null; + protected bool estrusflag = false; + protected int opcache = -1; public int ovarypowerthreshold { @@ -586,7 +586,7 @@ namespace RJW_Menstruation AfterFluidIn(cumd); } - public void AfterCumIn(Pawn cummer) + public virtual void AfterCumIn(Pawn cummer) { if (xxx.is_human(parent.pawn) && xxx.is_human(cummer)) { @@ -1205,6 +1205,150 @@ namespace RJW_Menstruation parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn)); } + protected virtual void FollicularAction() + { + if (!IsBreedingSeason()) + { + GoNextStage(Stage.Anestrus); + return; + } + if (curStageHrs >= FollicularIntervalHours) + { + GoNextStage(Stage.Ovulatory); + } + else + { + curStageHrs += Configurations.CycleAcceleration; + if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24) + { + estrusflag = true; + SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation); + } + StayCurrentStage(); + } + } + + protected virtual void OvulatoryAction() + { + estrusflag = false; + int i = 0; + do + { + ovarypower--; + eggs.Add(new Egg((int)(Props.eggLifespanDays * 24 / CycleFactor))); + i++; + } while (i < Rand.ByCurve(parent.pawn.RaceProps.litterSizeCurve) + eggstack); + eggstack = 0; + if (Configurations.EnableMenopause && ovarypower < 1) + { + eggs.Clear(); + Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_Climacteric); + if (hediff != null) parent.pawn.health.RemoveHediff(hediff); + hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Menopause, parent.pawn); + hediff.Severity = 0.2f; + parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn)); + GoNextStage(Stage.Young); + } + else if (Configurations.EnableMenopause && ovarypower < ovarypowerthreshold) + { + Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn); + hediff.Severity = 0.008f * i; + parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn)); + lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6); + GoNextStage(Stage.ClimactericLuteal); + } + else + { + lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor); + GoNextStage(Stage.Luteal); + } + } + + protected virtual void LutealAction() + { + if (!eggs.NullOrEmpty()) + { + EggDecay(); + FertilizationCheck(); + if (Implant()) GoNextStage(Stage.Pregnant); + else + { + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + } + else if (curStageHrs <= lutealIntervalhours) + { + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + else + { + if (Props.bleedingIntervalDays == 0) + { + follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor); + GoNextStage(Stage.Follicular); + } + else + { + bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor); + if (crampPain >= 0.05f) + { + AddCrampPain(); + } + GoNextStage(Stage.Bleeding); + } + } + } + + protected virtual void BleedingAction() + { + if (curStageHrs >= bleedingIntervalhours) + { + follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor); + Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp); + if (hediff != null) parent.pawn.health.RemoveHediff(hediff); + GoNextStage(Stage.Follicular); + } + else + { + if (curStageHrs < bleedingIntervalhours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut(); + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + } + + protected virtual void PregnantAction() + { + if (!eggs.NullOrEmpty()) + { + EggDecay(); + FertilizationCheck(); + Implant(); + } + if (parent.pawn.IsPregnant()) StayCurrentStageConst(Stage.Pregnant); + else GoNextStage(Stage.Recover); + } + + protected virtual void YoungAction() + { + if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) StayCurrentStageConst(Stage.Young); + else GoNextStage(Stage.Follicular); + } + + protected virtual void AnestrusAction() + { + if (IsBreedingSeason()) + { + GoFollicularOrBleeding(); + } + else + { + StayCurrentStage(); + } + } + + private Action PeriodSimulator(Stage targetstage) { Action action = null; @@ -1213,118 +1357,25 @@ namespace RJW_Menstruation case Stage.Follicular: action = delegate { - if (!IsBreedingSeason()) - { - GoNextStage(Stage.Anestrus); - return; - } - if (curStageHrs >= FollicularIntervalHours) - { - GoNextStage(Stage.Ovulatory); - } - else - { - curStageHrs += Configurations.CycleAcceleration; - if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24) - { - estrusflag = true; - SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation); - } - StayCurrentStage(); - } + FollicularAction(); }; break; case Stage.Ovulatory: action = delegate { - estrusflag = false; - int i = 0; - do - { - ovarypower--; - eggs.Add(new Egg((int)(Props.eggLifespanDays * 24 / CycleFactor))); - i++; - } while (i < Rand.ByCurve(parent.pawn.RaceProps.litterSizeCurve) + eggstack); - eggstack = 0; - if (Configurations.EnableMenopause && ovarypower < 1) - { - eggs.Clear(); - Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_Climacteric); - if (hediff != null) parent.pawn.health.RemoveHediff(hediff); - hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Menopause, parent.pawn); - hediff.Severity = 0.2f; - parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn)); - GoNextStage(Stage.Young); - } - else if (Configurations.EnableMenopause && ovarypower < ovarypowerthreshold) - { - Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn); - hediff.Severity = 0.008f * i; - parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn)); - lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6); - GoNextStage(Stage.ClimactericLuteal); - } - else - { - lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor); - GoNextStage(Stage.Luteal); - } + OvulatoryAction(); }; break; case Stage.Luteal: action = delegate { - if (!eggs.NullOrEmpty()) - { - EggDecay(); - FertilizationCheck(); - if (Implant()) GoNextStage(Stage.Pregnant); - else - { - curStageHrs += Configurations.CycleAcceleration; - StayCurrentStage(); - } - } - else if (curStageHrs <= lutealIntervalhours) - { - curStageHrs += Configurations.CycleAcceleration; - StayCurrentStage(); - } - else - { - if (Props.bleedingIntervalDays == 0) - { - follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor); - GoNextStage(Stage.Follicular); - } - else - { - bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor); - if (crampPain >= 0.05f) - { - AddCrampPain(); - } - GoNextStage(Stage.Bleeding); - } - } + LutealAction(); }; break; case Stage.Bleeding: action = delegate { - if (curStageHrs >= bleedingIntervalhours) - { - follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor); - Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp); - if (hediff != null) parent.pawn.health.RemoveHediff(hediff); - GoNextStage(Stage.Follicular); - } - else - { - if (curStageHrs < bleedingIntervalhours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut(); - curStageHrs += Configurations.CycleAcceleration; - StayCurrentStage(); - } + BleedingAction(); }; break; case Stage.Fertilized: //Obsoleted stage. merged in luteal stage @@ -1332,35 +1383,12 @@ namespace RJW_Menstruation { ModLog.Message("Obsoleted stage. skipping..."); GoNextStage(Stage.Luteal); - //if (curStageHrs >= 24) - //{ - // if (Implant()) - // { - // GoNextStage(Stage.Pregnant); - // } - // else - // { - // GoNextStageSetHour(Stage.Luteal, 96); - // } - //} - //else - //{ - // curStageHrs+=Configurations.CycleAcceleration; - // StayCurrentStage(); - //} }; break; case Stage.Pregnant: action = delegate { - if (!eggs.NullOrEmpty()) - { - EggDecay(); - FertilizationCheck(); - Implant(); - } - if (parent.pawn.IsPregnant()) StayCurrentStageConst(Stage.Pregnant); - else GoNextStage(Stage.Recover); + PregnantAction(); }; break; case Stage.Recover: @@ -1398,8 +1426,7 @@ namespace RJW_Menstruation case Stage.Young: action = delegate { - if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) StayCurrentStageConst(Stage.Young); - else GoNextStage(Stage.Follicular); + YoungAction(); }; break; case Stage.ClimactericFollicular: @@ -1484,14 +1511,7 @@ namespace RJW_Menstruation case Stage.Anestrus: action = delegate { - if (IsBreedingSeason()) - { - GoFollicularOrBleeding(); - } - else - { - StayCurrentStage(); - } + AnestrusAction(); }; break; default: @@ -1511,48 +1531,50 @@ namespace RJW_Menstruation actionref = action; return actionref; - void GoNextStage(Stage nextstage, float factor = 1.0f) + + + + } + + protected void GoNextStage(Stage nextstage, float factor = 1.0f) + { + curStageHrs = 0; + curStage = nextstage; + HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), (int)(tickInterval * factor), parent.pawn, false); + } + + + protected void GoNextStageSetHour(Stage nextstage, int hour, float factor = 1.0f) + { + curStageHrs = hour; + curStage = nextstage; + HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), (int)(tickInterval * factor), parent.pawn, false); + } + + //stage can be interrupted in other reasons + protected void StayCurrentStage(float factor = 1.0f) + { + HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), (int)(tickInterval * factor), parent.pawn, false); + } + + //stage never changes + protected void StayCurrentStageConst(Stage curstage, float factor = 1.0f) + { + HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curstage), (int)(tickInterval * factor), parent.pawn, false); + } + + protected void GoFollicularOrBleeding() + { + if (Props.bleedingIntervalDays == 0) { - curStageHrs = 0; - curStage = nextstage; - HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), (int)(tickInterval * factor), parent.pawn, false); + follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor); + GoNextStage(Stage.Follicular); } - - - void GoNextStageSetHour(Stage nextstage, int hour, float factor = 1.0f) + else { - curStageHrs = hour; - curStage = nextstage; - HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), (int)(tickInterval * factor), parent.pawn, false); + bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor); + GoNextStage(Stage.Bleeding); } - - //stage can be interrupted in other reasons - void StayCurrentStage(float factor = 1.0f) - { - HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), (int)(tickInterval * factor), parent.pawn, false); - } - - //stage never changes - void StayCurrentStageConst(Stage curstage, float factor = 1.0f) - { - HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curstage), (int)(tickInterval * factor), parent.pawn, false); - } - - void GoFollicularOrBleeding() - { - if (Props.bleedingIntervalDays == 0) - { - follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor); - GoNextStage(Stage.Follicular); - } - else - { - bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor); - GoNextStage(Stage.Bleeding); - } - } - - } diff --git a/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj b/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj index 21b8c0a..ab4ccd1 100644 --- a/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj +++ b/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj @@ -61,12 +61,13 @@ + - + diff --git a/source/RJW_Menstruation/RJW_Menstruation/Things.cs b/source/RJW_Menstruation/RJW_Menstruation/Things.cs index 700b5e3..d28a4ee 100644 --- a/source/RJW_Menstruation/RJW_Menstruation/Things.cs +++ b/source/RJW_Menstruation/RJW_Menstruation/Things.cs @@ -63,7 +63,9 @@ namespace RJW_Menstruation if (childNodes.Count >= 1) foreach (XmlNode node in childNodes) { - //Log.Message(xmlRoot.Name + "HybridInfo: " + node.Name + " " + node.InnerText); +#if DEBUG + Log.Message(xmlRoot.Name + "HybridInfo: " + node.Name + " " + node.InnerText); +#endif hybridInfo.Add(node.Name, ParseHelper.FromString(node.InnerText)); } diff --git a/source/RJW_Menstruation/RJW_Menstruation/Utility.cs b/source/RJW_Menstruation/RJW_Menstruation/Utility.cs index 034d124..61324fe 100644 --- a/source/RJW_Menstruation/RJW_Menstruation/Utility.cs +++ b/source/RJW_Menstruation/RJW_Menstruation/Utility.cs @@ -227,8 +227,9 @@ namespace RJW_Menstruation public static Texture2D GetGenitalIcon(this Pawn pawn) { - var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)).Find((Hediff h) => h.def.defName.ToLower().Contains("vagina")); - HediffComp_Menstruation comp = pawn.GetMenstruationComp(); + var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.Find((Hediff h) => h.def.defName.ToLower().Contains("vagina")); + if (hediff == null) return ContentFinder.Get("Genitals/Vagina00", true); + HediffComp_Menstruation comp = hediff.GetMenstruationComp(); string icon; if (comp != null) icon = comp.vagTex; else icon = "Genitals/Vagina"; @@ -254,7 +255,7 @@ namespace RJW_Menstruation var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("anus")); if (hediff != null) { - CompProperties_Anus Props = (CompProperties_Anus)hediff.TryGetComp().props; + CompProperties_Anus Props = (CompProperties_Anus)hediff.TryGetComp()?.props; string icon; if (Props != null) icon = Props.analTex ?? "Genitals/Anal"; else icon = "Genitals/Anal";