diff --git a/1.4/Assemblies/RJW_Menstruation.dll b/1.4/Assemblies/RJW_Menstruation.dll index 325db98..74a0375 100644 Binary files a/1.4/Assemblies/RJW_Menstruation.dll and b/1.4/Assemblies/RJW_Menstruation.dll differ diff --git a/1.4/Defs/GeneDefs/GeneDefs_Menstruation.xml b/1.4/Defs/GeneDefs/GeneDefs_Menstruation.xml new file mode 100644 index 0000000..b685015 --- /dev/null +++ b/1.4/Defs/GeneDefs/GeneDefs_Menstruation.xml @@ -0,0 +1,99 @@ + + + + + Menstruation + + 402 + + + + Menstruation + +
  • Menstruation_EggLifetime
  • +
    +
    + + + Menstruation_ShortEggLifetime + + Unfertilized eggs with this gene last three-quarters as long. + 1 + 10 + + + + Menstruation_DoubleEggLifetime + + Unfertilized eggs with this gene last twice as long. + -1 + 12 + + + + Menstruation_QuadEggLifetime + + Eggs with this gene last four times as long. + -2 + 1 + 16 + + + + Menstruation + +
  • Menstruation_Estrus
  • +
    +
    + + + Menstruation_NeverEstrus + + Carriers of this gene will never go into estrus. + 1 + 20 + + + + Menstruation_FullEstrus + + Carriers of this gene will enter full estrus every menstrual cycle, regardless of vagina type. + -1 + 1 + 25 + + + + Menstruation + +
  • Menstruation_Ovulation
  • +
    +
    + + + Menstruation_DoubleOvulation + + Wombs with this gene will ovulate twice as many eggs, and contain double. + -1 + 30 + + + + Menstruation_QuadOvulation + + Wombs with this gene will ovulate four times as many eggs, and contain quadruple. + -1 + 35 + + + + Menstruation_NoBleeding + + Menstruation + Wombs with this gene will not bleed at the end of their cycle. + 1 + 40 + + + +
    \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs index 55b7ecf..3bccc44 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs @@ -75,7 +75,7 @@ namespace RJW_Menstruation case Stage.Ovulatory: return true; case Stage.Luteal: - return IsEggExist && curStageHrs < Props.eggLifespanDays * 24; + return IsEggExist && curStageHrs < EggLifespanHours * 24; default: return false; } @@ -93,7 +93,7 @@ namespace RJW_Menstruation case Stage.Ovulatory: return true; case Stage.Luteal: - return IsEggExist && curStageHrs < Props.eggLifespanDays * 24; + return IsEggExist && curStageHrs < EggLifespanHours * 24; default: return false; } 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 5064dc2..256a67f 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 @@ -126,6 +126,11 @@ namespace RJW_Menstruation // RJW pregnancy, or Biotech pregnancy/labor/laborpushing protected Hediff pregnancy = null; + protected int eggLifeSpanHours = 48; + protected EstrusLevel estrusLevel = EstrusLevel.Visible; + protected float ovulationFactor = 1f; + protected bool noBleeding = false; + private static readonly SimpleCurve SexFrequencyCurve = new SimpleCurve() { new CurvePoint(0.4f,0.05f), @@ -179,6 +184,7 @@ namespace RJW_Menstruation // Any exceptions in that will have been reported elsewhere in the code by now avglittersize = 1.0f; }; + avglittersize *= ovulationFactor; const float yearsBeforeMenopause = 6.0f; opcache = (int)(RaceCyclesPerYear() * avglittersize * @@ -470,6 +476,15 @@ namespace RJW_Menstruation return !eggs.NullOrEmpty(); } } + + public int EggLifespanHours + { + get + { + return eggLifeSpanHours; + } + } + public virtual bool IsDangerDay { get @@ -483,7 +498,7 @@ namespace RJW_Menstruation case Stage.Ovulatory: return true; case Stage.Luteal: - return curStageHrs < Props.eggLifespanDays * 24; + return curStageHrs < EggLifespanHours * 24; default: return false; } @@ -606,6 +621,28 @@ namespace RJW_Menstruation } } + public void Notify_UpdatedGenes() + { + eggLifeSpanHours = Props.eggLifespanDays * 24; + estrusLevel = Props.concealedEstrus ? EstrusLevel.Concealed : EstrusLevel.Visible; + ovulationFactor = 1f; + noBleeding = false; + + if (Pawn.genes == null || !ModsConfig.BiotechActive) return; + + if (Pawn.genes.HasGene(VariousDefOf.ShortEggLifetime)) eggLifeSpanHours = eggLifeSpanHours * 3 / 4; + else if (Pawn.genes.HasGene(VariousDefOf.DoubleEggLifetime)) eggLifeSpanHours *= 2; + else if (Pawn.genes.HasGene(VariousDefOf.QuadEggLifetime)) eggLifeSpanHours *= 4; + + if (Pawn.genes.HasGene(VariousDefOf.NeverEstrus)) estrusLevel = EstrusLevel.None; + else if (Pawn.genes.HasGene(VariousDefOf.FullEstrus)) estrusLevel = EstrusLevel.Visible; + + if (Pawn.genes.HasGene(VariousDefOf.DoubleOvulation)) ovulationFactor = 2f; + else if (Pawn.genes.HasGene(VariousDefOf.QuadOvulation)) ovulationFactor = 4f; + + noBleeding = Pawn.genes.HasGene(VariousDefOf.NoBleeding); + } + public bool ShouldSimulate() { if (!Configurations.EnableAnimalCycle && Pawn.IsAnimal()) return false; @@ -1029,6 +1066,8 @@ namespace RJW_Menstruation initError = true; Props = (CompProperties_Menstruation)props; + Notify_UpdatedGenes(); + if (Props.infertile) { if (cums == null) cums = new List(); @@ -1101,6 +1140,7 @@ namespace RJW_Menstruation { avglittersize = 1.0f; } + avglittersize *= ovulationFactor; float fertStartAge = Pawn.RaceProps.lifeStageAges?.Find(stage => stage.def.reproductive)?.minAge ?? 0.0f; float fertEndAge = Pawn.RaceProps.lifeExpectancy * (Pawn.IsAnimal() ? RJWPregnancySettings.fertility_endage_female_animal : RJWPregnancySettings.fertility_endage_female_humanlike); @@ -1160,7 +1200,7 @@ namespace RJW_Menstruation case Stage.Ovulatory: return true; case Stage.Luteal: - return curStageHrs < Props.eggLifespanDays * 24; + return curStageHrs < EggLifespanHours * 24; default: return false; } @@ -1169,12 +1209,13 @@ namespace RJW_Menstruation public EstrusLevel GetEstrusLevel() { if (!ShouldBeInEstrus()) return EstrusLevel.None; - else return Props.concealedEstrus ? EstrusLevel.Concealed : EstrusLevel.Visible; + else return estrusLevel; } public void SetEstrus() { - Hediff hediff = HediffMaker.MakeHediff(Props.concealedEstrus ? VariousDefOf.Hediff_Estrus_Concealed : VariousDefOf.Hediff_Estrus, Pawn); + if (estrusLevel == EstrusLevel.None) return; + Hediff hediff = HediffMaker.MakeHediff(estrusLevel == EstrusLevel.Concealed ? VariousDefOf.Hediff_Estrus_Concealed : VariousDefOf.Hediff_Estrus, Pawn); Pawn.health.AddHediff(hediff); } @@ -1454,25 +1495,27 @@ namespace RJW_Menstruation protected virtual void OvulatoryAction() { estrusflag = false; - int eggnum; + float eggnum; + int ovulated; try { - eggnum = Math.Max((int)Rand.ByCurve(Pawn.def.race.litterSizeCurve), 1); + eggnum = Math.Max(Rand.ByCurve(Pawn.def.race.litterSizeCurve), 1f); } catch (NullReferenceException) { - eggnum = 1; + eggnum = 1f; } catch (ArgumentException e) { Log.Warning($"Invalid litterSizeCurve for {Pawn.def}: {e}"); - eggnum = 1; + eggnum = 1f; } - eggnum += eggstack; + eggnum *= ovulationFactor; + ovulated = (int)eggnum + eggstack; - for (int i = 0; i < eggnum; i++) - eggs.Add(new Egg((int)(Props.eggLifespanDays * 24 / CycleFactor))); - ovarypower -= eggnum; + for (int i = 0; i < ovulated; i++) + eggs.Add(new Egg((int)(EggLifespanHours * 24 / CycleFactor))); + ovarypower -= ovulated; eggstack = 0; if (EggHealth <= 0) @@ -1709,7 +1752,7 @@ namespace RJW_Menstruation protected void GoFollicularOrBleeding() { - if (Props.bleedingIntervalDays == 0) + if (Props.bleedingIntervalDays == 0 || noBleeding) { GoNextStage(Stage.Follicular); } 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..7d9de72 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 @@ -177,4 +177,13 @@ namespace RJW_Menstruation } } + [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(); + } + } } \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs index 5e00858..9917653 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs @@ -44,8 +44,14 @@ namespace RJW_Menstruation public static readonly RecordDef AmountofCreampied = DefDatabase.GetNamed("AmountofCreampied"); public static readonly RecordDef AmountofFertilizedEggs = DefDatabase.GetNamed("AmountofFertilizedEggs"); public static readonly TaleDef TaleCameInside = DefDatabase.GetNamed("CameInside"); - - + public static readonly GeneDef ShortEggLifetime = DefDatabase.GetNamed("Menstruation_ShortEggLifetime"); + public static readonly GeneDef DoubleEggLifetime = DefDatabase.GetNamed("Menstruation_DoubleEggLifetime"); + public static readonly GeneDef QuadEggLifetime = DefDatabase.GetNamed("Menstruation_QuadEggLifetime"); + public static readonly GeneDef NeverEstrus = DefDatabase.GetNamed("Menstruation_NeverEstrus"); + public static readonly GeneDef FullEstrus = DefDatabase.GetNamed("Menstruation_FullEstrus"); + public static readonly GeneDef DoubleOvulation = DefDatabase.GetNamed("Menstruation_DoubleOvulation"); + public static readonly GeneDef QuadOvulation = DefDatabase.GetNamed("Menstruation_QuadOvulation"); + public static readonly GeneDef NoBleeding = DefDatabase.GetNamed("Menstruation_NoBleeding"); private static List allraces = null; private static List allkinds = null;