diff --git a/1.4/Assemblies/RJW_Menstruation.dll b/1.4/Assemblies/RJW_Menstruation.dll index d4d7bb3..32d579b 100644 Binary files a/1.4/Assemblies/RJW_Menstruation.dll and b/1.4/Assemblies/RJW_Menstruation.dll differ diff --git a/1.4/Languages/English/Keyed/RJW_Menstruation.xml b/1.4/Languages/English/Keyed/RJW_Menstruation.xml index a1c65b3..3df2d06 100644 --- a/1.4/Languages/English/Keyed/RJW_Menstruation.xml +++ b/1.4/Languages/English/Keyed/RJW_Menstruation.xml @@ -120,8 +120,6 @@ Hookup minimum opinion in estrus Estimated sperm lifespan Estimated egg lifespan - Ovulation {0} - Chance of each egg being released during ovulation. Implantation chance of fertilized eggs. Chance of fertilization this hour: {0}% Use basic RJW pregnancy Use menstruation multiple pregnancy diff --git a/1.4/MilkModule/Assemblies/MilkModule.dll b/1.4/MilkModule/Assemblies/MilkModule.dll index 1881466..5c953b2 100644 Binary files a/1.4/MilkModule/Assemblies/MilkModule.dll and b/1.4/MilkModule/Assemblies/MilkModule.dll differ diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs index fe98f5a..3a8fdb5 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs @@ -10,7 +10,7 @@ namespace RJW_Menstruation private static void SetFollicular(Pawn p) { foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - comp.GoNextStage(HediffComp_Menstruation.Stage.Follicular); + comp.curStage = HediffComp_Menstruation.Stage.Follicular; Messages.Message($"{p} is now follicular", p, MessageTypeDefOf.NeutralEvent, false); } @@ -18,7 +18,7 @@ namespace RJW_Menstruation private static void SetOvulatory(Pawn p) { foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - comp.GoNextStage(HediffComp_Menstruation.Stage.Ovulatory); + comp.curStage = HediffComp_Menstruation.Stage.Ovulatory; Messages.Message($"{p} is now ovulatory", p, MessageTypeDefOf.NeutralEvent, false); } @@ -26,7 +26,7 @@ namespace RJW_Menstruation private static void SetLuteal(Pawn p) { foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - comp.GoNextStage(HediffComp_Menstruation.Stage.Luteal); + comp.curStage = HediffComp_Menstruation.Stage.Luteal; Messages.Message($"{p} is now luteal", p, MessageTypeDefOf.NeutralEvent, false); } @@ -34,7 +34,7 @@ namespace RJW_Menstruation private static void SetBleeding(Pawn p) { foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - comp.GoNextStage(HediffComp_Menstruation.Stage.Bleeding); + comp.curStage = HediffComp_Menstruation.Stage.Bleeding; Messages.Message($"{p} is now bleeding", p, MessageTypeDefOf.NeutralEvent, false); } /* diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs index 2b51556..6e8c375 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs @@ -16,7 +16,7 @@ namespace RJW_Menstruation ) { comp.SetEstrus(); - comp.GoNextStage(HediffComp_Menstruation.Stage.Ovulatory); + comp.curStage = HediffComp_Menstruation.Stage.Ovulatory; comp.ovarypower--; } } @@ -32,7 +32,7 @@ namespace RJW_Menstruation ) { comp.SetEstrus(); - comp.GoNextStage(HediffComp_Menstruation.Stage.Ovulatory); + comp.curStage = HediffComp_Menstruation.Stage.Ovulatory; comp.eggstack += ingested.stackCount - 1; } } @@ -89,7 +89,7 @@ namespace RJW_Menstruation else m.moodPowerFactor = 0.3f; } - if (pawn.HasQuirk(QuirkUtility.Quirks.Breeder)) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill); + if (pawn.Has(Quirk.Breeder)) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill); else pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.TookContraceptivePill); } } 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 e86422d..ef575f0 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 @@ -203,7 +203,7 @@ namespace RJW_Menstruation get { if (!Configurations.EnableMenopause || Props.infertile) return Mathf.Max(1.0f, ovarypower / OvaryPowerThreshold); - else return (float)ovarypower / OvaryPowerThreshold; + else return ovarypower / OvaryPowerThreshold; } } @@ -280,65 +280,16 @@ namespace RJW_Menstruation return 1.0f; } } - - // I hate doing this, but it's the least bad option - public bool calculatingOvulationChance = false; - - public float OvulationChance - { - get - { - float ovulationChance = 1.0f; - if (EggHealth <= 0.0f) return 0.0f; - if (EggHealth < 1.0f / 3.0f) ovulationChance = 0.8f; - if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) - { - if (Pawn.SterileGenes()) return 0.0f; - // Replicate how rjw.PawnCapacityWorker_Fertility.CalculateCapacityLevel does it, but without the age factor - if (!Pawn.RaceHasFertility()) return 0.0f; - if (AndroidsCompatibility.IsAndroid(Pawn) && parent.def != Genital_Helper.archotech_vagina) return 0.0f; - foreach (var part in StatDefOf.Fertility.parts) - { - if(part is StatPart_FertilityByGenderAge fertilityByAge) - { - float factor = 1.0f; - fertilityByAge.TransformValue(StatRequest.For(Pawn), ref factor); - if (factor <= 0.0f) return 0.0f; // Too young or too old - } - else part.TransformValue(StatRequest.For(Pawn), ref ovulationChance); - } - if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder)) ovulationChance *= 10.0f; - try - { - calculatingOvulationChance = true; - ovulationChance *= PawnCapacityUtility.CalculateCapacityLevel(Pawn.health.hediffSet, xxx.reproduction); - } - finally { calculatingOvulationChance = false; } - } - return ovulationChance; - } - } - public float ImplantChance + //effect on implant chance + public float ImplantFactor { get { float factor = 1.0f; - if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) - { - // Implant factor will be based solely on pawn age, plus any rollover from ovulation chance - StatPart_FertilityByGenderAge fertilityStatPart = StatDefOf.Fertility.GetStatPart(); - fertilityStatPart?.TransformValue(StatRequest.For(Pawn), ref factor); - float ovulationOverflow = OvulationChance; - if (ovulationOverflow > 1.0f) factor *= ovulationOverflow; - return Props.baseImplantationChanceFactor * FertilityModifier * factor; - } - else - { - return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * factor; - } + if (Pawn.Has(Quirk.Breeder)) factor = 10.0f; + return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * factor; } } - public IEnumerable GetCumsInfo { get @@ -394,13 +345,13 @@ namespace RJW_Menstruation switch (CurrentVisibleStage) { case Stage.Follicular: - return Translations.Stage_Follicular + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : ""); + return Translations.Stage_Follicular + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); case Stage.Ovulatory: - return Translations.Stage_Ovulatory + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : ""); + return Translations.Stage_Ovulatory + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); case Stage.Luteal: - return Translations.Stage_Luteal + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : ""); + return Translations.Stage_Luteal + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); case Stage.Bleeding: - return Translations.Stage_Bleeding + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : ""); + return Translations.Stage_Bleeding + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); case Stage.Pregnant: return Translations.Stage_Pregnant; case Stage.Recover: @@ -424,13 +375,13 @@ namespace RJW_Menstruation switch (CurrentVisibleStage) { case Stage.Follicular: - return Translations.Stage_Follicular_Desc + (EggHealth < 1f ? " " + Translations.Stage_Climacteric_Desc : ""); + return Translations.Stage_Follicular_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); case Stage.Ovulatory: - return Translations.Stage_Ovulatory_Desc + (EggHealth < 1f ? " " + Translations.Stage_Climacteric_Desc : ""); + return Translations.Stage_Ovulatory_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); case Stage.Luteal: - return Translations.Stage_Luteal_Desc + (EggHealth < 1f ? " " + Translations.Stage_Climacteric_Desc : ""); + return Translations.Stage_Luteal_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); case Stage.Bleeding: - return Translations.Stage_Bleeding_Desc + (EggHealth < 1f ? " " + Translations.Stage_Climacteric_Desc : ""); + return Translations.Stage_Bleeding_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); case Stage.Pregnant: return Translations.Stage_Pregnant_Desc; case Stage.Recover: @@ -700,16 +651,6 @@ namespace RJW_Menstruation return false; } - public bool ShouldBeInfertile() - { - if (pregnancy != null) return false; - if (ImplantChance <= 0.0f) return true; - // Give the last egg ovulated a chance to implant - if (curStage == Stage.Luteal || curStage == Stage.Bleeding || curStage == Stage.Recover) return false; - if (EggHealth <= 0.0f) return true; - return false; - } - public override void CompPostTick(ref float severityAdjustment) { base.CompPostTick(ref severityAdjustment); @@ -737,7 +678,7 @@ namespace RJW_Menstruation BeforeSimulator(); - if (ShouldBeInfertile()) GoNextStage(Stage.Infertile); + if (pregnancy == null && (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || EggHealth <= 0 || Pawn.SterileGenes())) GoNextStage(Stage.Infertile); switch (curStage) { case Stage.Follicular: @@ -872,8 +813,8 @@ namespace RJW_Menstruation if (!precum && fertility > 0 && IsDangerDay && pawn.relations.GetPregnancyApproachForPartner(Pawn) == PregnancyApproach.AvoidPregnancy) { float successChance = pulloutSuccessRate; - if (pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; - if (Pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; + if (pawn.Has(Quirk.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; + if (Pawn.Has(Quirk.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; if (Rand.Chance(successChance)) return; } if (Pawn.HasIUD()) fertility /= 100f; @@ -1170,12 +1111,9 @@ namespace RJW_Menstruation if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f); if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent(); - - InitOvary(); - if (currentIntervalHours < 0) { - if (ShouldBeInfertile()) curStage = Stage.Infertile; + if (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || Pawn.SterileGenes()) curStage = Stage.Infertile; else if (!IsBreedingSeason()) curStage = Stage.Anestrus; else curStage = RandomStage(); if (curStage == Stage.Follicular) @@ -1190,6 +1128,8 @@ namespace RJW_Menstruation if (cums == null) cums = new List(); if (eggs == null) eggs = new List(); + + InitOvary(); TakeLoosePregnancy(); //Log.Message(Pawn.Label + " - Initialized menstruation comp"); @@ -1343,7 +1283,7 @@ namespace RJW_Menstruation float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume); - if (Rand.Chance(Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor))) + if (Rand.Range(0.0f, 1.0f) > 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor)) return null; Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1); @@ -1384,7 +1324,7 @@ namespace RJW_Menstruation deadeggs.Add(egg); continue; } - else if (Rand.Chance(Configurations.ImplantationChance * ImplantChance * InterspeciesImplantFactor(egg.fertilizer))) + else if (Rand.Range(0.0f, 1.0f) <= Configurations.ImplantationChance * ImplantFactor * InterspeciesImplantFactor(egg.fertilizer)) { if (Configurations.Debug) Log.Message($"Implanting fertilized egg of {Pawn} into {parent}, father {egg.fertilizer}"); if (pregnancy != null) @@ -1605,6 +1545,7 @@ namespace RJW_Menstruation { estrusflag = false; float eggnum; + int ovulated; try { eggnum = Math.Max(Rand.ByCurve(Pawn.def.race.litterSizeCurve), 1f); @@ -1619,24 +1560,23 @@ namespace RJW_Menstruation eggnum = 1f; } eggnum *= ovulationFactor; - int toOvulate = (int)eggnum + eggstack; - - float ovulationChance = OvulationChance; - int ovulated = 0; - for (int i = 0; i < toOvulate; i++) - if (i < eggstack || Rand.Chance(ovulationChance)) // eggstack comes from drugs and are guaranteed ovulated - { - eggs.Add(new Egg((int)(EggLifespanHours / CycleFactor))); - ++ovulated; - } - if(ovulated < ovarypower) ovulated = Math.Max(ovarypower, eggstack); + ovulated = (int)eggnum + eggstack; + for (int i = 0; i < ovulated; i++) + eggs.Add(new Egg((int)(EggLifespanHours / CycleFactor))); ovarypower -= ovulated; - eggstack = 0; - if (Configurations.Debug && ovulated != toOvulate) - Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({ovulationChance.ToStringPercent()} chance)"); - GoNextStage(Stage.Luteal); + eggstack = 0; + if (EggHealth <= 0) + { + eggs.Clear(); + ovarypower = 0; + GoNextStage(Stage.Infertile); + } + else + { + GoNextStage(Stage.Luteal); + } } protected virtual void LutealAction() @@ -1644,7 +1584,7 @@ namespace RJW_Menstruation if (curStageHrs >= currentIntervalHours) { eggs.Clear(); - if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Chance(0.3f))) //skips bleeding + if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Range(0.0f, 1.0f) < 0.3f)) //skips bleeding { GoNextStage(Stage.Follicular); } @@ -1723,7 +1663,7 @@ namespace RJW_Menstruation { if (curStageHrs >= currentIntervalHours) { - if (ShouldBeInfertile()) + if (Pawn.health.capacities.GetLevel(xxx.reproduction) == 0 || EggHealth <= 0 || Pawn.SterileGenes()) { GoNextStage(Stage.Infertile); } @@ -1745,7 +1685,7 @@ namespace RJW_Menstruation protected virtual void InfertileAction() { - if (ShouldBeInfertile()) + if (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || EggHealth <= 0 || Pawn.SterileGenes()) { StayCurrentStageConst(Stage.Infertile); } @@ -1772,9 +1712,9 @@ namespace RJW_Menstruation { if (!xxx.is_human(Pawn) || !xxx.is_human(cummer)) return; - if ((cummer.HasQuirk(QuirkUtility.Quirks.Teratophile) != (Pawn.GetStatValue(StatDefOf.PawnBeauty) >= 0)) || - cummer.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || - cummer.HasQuirk(QuirkUtility.Quirks.Breeder)) + if ((cummer.Has(Quirk.Teratophile) != (Pawn.GetStatValue(StatDefOf.PawnBeauty) >= 0)) || + cummer.Has(Quirk.ImpregnationFetish) || + cummer.Has(Quirk.Breeder)) { if (cummer.relations.OpinionOf(Pawn) <= -25) { @@ -1788,7 +1728,7 @@ namespace RJW_Menstruation if (IsDangerDay) { - if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || Pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) + if (Pawn.Has(Quirk.Breeder) || Pawn.Has(Quirk.ImpregnationFetish)) { Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer); } @@ -1811,7 +1751,7 @@ namespace RJW_Menstruation } else { - if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || Pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) + if (Pawn.Has(Quirk.Breeder) || Pawn.Has(Quirk.ImpregnationFetish)) { Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetishSafe, cummer); } @@ -1832,7 +1772,7 @@ namespace RJW_Menstruation TaleRecorder.RecordTale(VariousDefOf.TaleCameInside, new object[] { cummer, Pawn }); } - public void GoNextStage(Stage nextstage, bool calculateHours = true) + protected void GoNextStage(Stage nextstage, bool calculateHours = true) { curStageHrs = 0; if (calculateHours) currentIntervalHours = PeriodRandomizer(nextstage); @@ -1841,7 +1781,12 @@ namespace RJW_Menstruation protected virtual void GoOvulatoryStage() { - GoNextStage(Stage.Ovulatory); + if (EggHealth < 1.0f / 3.0f && Rand.Range(0.0f, 1.0f) < 0.2f) // Skip ovulation if deep into climacteric + { + estrusflag = false; + GoNextStage(Stage.Luteal); + } + else GoNextStage(Stage.Ovulatory); } //stage can be interrupted in other reasons diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs index 8d7ab50..979077a 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs @@ -214,10 +214,6 @@ namespace RJW_Menstruation PregnancyUtility.ApplyBirthOutcome(thisOutcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments); // No more babies if mom dies halfway through. Unrealistic maybe, but saves a lot of headache in ApplyBirthOutcome if (mother.health.Dead) break; - if (xxx.is_human(baby)) - mother.records.Increment(xxx.CountOfBirthHuman); - else if (xxx.is_animal(baby)) - mother.records.Increment(xxx.CountOfBirthAnimal); thisOutcome = ((RitualOutcomeEffectWorker_ChildBirth)precept_Ritual.outcomeEffect).GetOutcome(birthQuality, null); } while (comp.HasBaby); @@ -267,10 +263,6 @@ namespace RJW_Menstruation PregnancyUtility.ApplyBirthOutcome(outcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments); if (mother.health.Dead) break; - if (xxx.is_human(baby)) - mother.records.Increment(xxx.CountOfBirthHuman); - else if (xxx.is_animal(baby)) - mother.records.Increment(xxx.CountOfBirthAnimal); } while (comp.HasBaby); // The ritual version doesn't use the return value, either diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs index d67fbb4..a7e2918 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs @@ -1,5 +1,4 @@ using RimWorld; -using RimWorld.Planet; using rjw; using System; using System.Collections.Generic; @@ -219,8 +218,6 @@ namespace RJW_Menstruation } public static Texture2D GetEggIcon(this HediffComp_Menstruation comp, bool includeOvary) { - const float ovaryChanceToShow_01 = 0.4f; - const float ovaryChanceToShow_02 = 1.0f; switch (comp.CurrentVisibleStage) { case HediffComp_Menstruation.Stage.Follicular: @@ -231,20 +228,15 @@ namespace RJW_Menstruation job.Sexprops != null && !job.Sexprops.usedCondom && (job.Sexprops.sexType == xxx.rjwSextype.Vaginal || job.Sexprops.sexType == xxx.rjwSextype.DoublePenetration)) - return ContentFinder.Get((comp.OvulationChance >= ovaryChanceToShow_01) ? "Ovaries/Ovary_01" : "Ovaries_Ovary_00", true); + return ContentFinder.Get("Ovaries/Ovary_01", true); else break; } if (comp.curStageHrs > comp.CurStageIntervalHours - 30) // Approximate time for ovulation to occur - return ContentFinder.Get((comp.OvulationChance >= ovaryChanceToShow_01) ? "Ovaries/Ovary_01" : "Ovaries_Ovary_00", true); + return ContentFinder.Get("Ovaries/Ovary_01", true); else break; case HediffComp_Menstruation.Stage.Ovulatory: if (!includeOvary) break; - if (comp.OvulationChance >= ovaryChanceToShow_02) - return ContentFinder.Get("Ovaries/Ovary_02", true); - else if (comp.OvulationChance >= ovaryChanceToShow_01) - return ContentFinder.Get("Ovaries/Ovary_01", true); - else - return ContentFinder.Get("Ovaries/Ovary_00", true); + return ContentFinder.Get("Ovaries/Ovary_02", true); case HediffComp_Menstruation.Stage.Luteal: if (!comp.IsEggExist) break; int fertstage = comp.IsFertilized; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs index b47d614..cab288a 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs @@ -23,11 +23,11 @@ namespace RJW_Menstruation { if (is_discovered || !xxx.is_human(pawn) || - pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || + pawn.Has(Quirk.Breeder) || (pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Spouse) || x.def.Equals(PawnRelationDefOf.Fiance))) != null) return; - if (pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null) + if (pawn.Has(Quirk.ImpregnationFetish) || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null) { pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancyMild); } 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 df6584b..2ffe8b3 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 @@ -26,28 +26,33 @@ namespace RJW_Menstruation public static void Postfix(Hediff_Pregnant __instance) { HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy(); + if (Configurations.Debug) Log.Message($"{comp.Pawn}'s labor starting, menstruation comp is {comp}"); if (comp == null) return; comp.Pregnancy = __instance.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.PregnancyLabor); + if (Configurations.Debug) Log.Message($"New pregnancy Hediff is {comp.Pregnancy}"); } } [HarmonyPatch(typeof(Hediff_Labor), nameof(Hediff_Labor.PreRemoved))] public class Labor_PreRemoved_Patch { - public static void Postfix(Hediff_Labor __instance) + public static void PostFix(Hediff_Labor __instance) { HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy(); + if (Configurations.Debug) Log.Message($"{comp.Pawn}'s initial labor ending, menstruation comp is {comp}"); if (comp == null) return; comp.Pregnancy = __instance.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.PregnancyLaborPushing); + if (Configurations.Debug) Log.Message($"New pregnancy Hediff is {comp.Pregnancy}"); } } [HarmonyPatch(typeof(Hediff_LaborPushing), nameof(Hediff_LaborPushing.PreRemoved))] public class LaborPushing_PreRemoved_Patch { - public static void Postfix(Hediff_LaborPushing __instance) + public static void PostFix(Hediff_LaborPushing __instance) { HediffComp_Menstruation comp = __instance.GetMenstruationCompFromPregnancy(); + if (Configurations.Debug) Log.Message($"{comp.Pawn}'s labor pushing ending, menstruation comp is {comp}"); if (comp == null) return; comp.Pregnancy = null; } @@ -57,7 +62,7 @@ namespace RJW_Menstruation [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) + public static void PostFix(Hediff_Pregnant __instance, ref float __result) { if (__result < 1f) return; Pawn pawn = __instance.pawn; @@ -69,7 +74,7 @@ namespace RJW_Menstruation [HarmonyPatch(typeof(Recipe_ExtractOvum), nameof(Recipe_ExtractOvum.AvailableReport))] public class ExtractOvum_AvailableReport_Patch { - public static void Postfix(Thing thing, ref AcceptanceReport __result) + public static void PostFix(Thing thing, ref AcceptanceReport __result) { if (!__result.Accepted) return; Pawn pawn = (Pawn)thing; @@ -92,7 +97,7 @@ namespace RJW_Menstruation [HarmonyPatch(typeof(Recipe_ExtractOvum), "OnSurgerySuccess")] public class ExtractOvum_OnSurgerySuccess_Patch { - public static void Postfix(Pawn pawn) + public static void PostFix(Pawn pawn) { List comps = pawn.GetMenstruationComps().ToList(); if (!comps.Any()) return; @@ -105,7 +110,7 @@ namespace RJW_Menstruation [HarmonyPatch(typeof(Recipe_ImplantEmbryo), nameof(Recipe_ImplantEmbryo.ApplyOnPawn))] public class ImplantEmbryo_ApplyOnPawn_Patch { - public static void Postfix(Pawn pawn) + public static void PostFix(Pawn pawn) { foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) comp.TakeLoosePregnancy(); @@ -115,7 +120,7 @@ namespace RJW_Menstruation [HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))] public class ApplyBirthOutcome_Breast_Patch { - public static void Postfix(Thing birtherThing) + public static void PostFix(Thing birtherThing) { if (birtherThing is Pawn pawn && !pawn.health.Dead) pawn.GetBreastComp()?.GaveBirth(); 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 57a6b9d..cc1ff7c 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 @@ -31,7 +31,7 @@ namespace RJW_Menstruation List pawnparts = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)); HediffComp_Menstruation comp; - if (pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || partner.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || partner.IsInEstrus()) + if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus()) comp = partner.GetFertileMenstruationComp(); else comp = partner.GetRandomMenstruationComp(); if (comp == null) return true; @@ -102,7 +102,7 @@ namespace RJW_Menstruation { if (partner.IsAnimal() && !Configurations.EnableAnimalCycle) return true; HediffComp_Menstruation comp; - if (pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || partner.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || partner.IsInEstrus()) + if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus()) comp = partner.GetFertileMenstruationComp(); else comp = partner.GetRandomMenstruationComp(); if (comp == null) @@ -129,11 +129,11 @@ namespace RJW_Menstruation else if (pawn.GetMenstruationComps().Any()) return false; else return pawn.IsPregnant(); } - private static readonly MethodInfo IsPregnant = AccessTools.Method(typeof(PawnExtensions), nameof(PawnExtensions.IsPregnant), new System.Type[] { typeof(Pawn), typeof(bool) }); + private static readonly MethodInfo IsPregnant = AccessTools.Method(typeof(PawnExtensions), nameof(PawnExtensions.IsPregnant), new System.Type[] {typeof(Pawn), typeof(bool)}); public static IEnumerable Transpiler(IEnumerable instructions) { if (IsPregnant == null || IsPregnant.ReturnType != typeof(bool)) throw new System.InvalidOperationException("IsPregnant not found"); - foreach (CodeInstruction instruction in instructions) + foreach(CodeInstruction instruction in instructions) { if (instruction.Calls(IsPregnant)) yield return CodeInstruction.Call(typeof(CanImpregnate_Patch), nameof(PregnancyBlocksImpregnation)); @@ -179,7 +179,7 @@ namespace RJW_Menstruation { // Awkward, but it'll have to do Pawn pawn = props.pawn; - if (__result == 0 || !pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || !props.hasPartner()) return; + if (__result == 0 || !pawn.Has(Quirk.ImpregnationFetish) || !props.hasPartner()) return; // Check if the existing code would have added the count Pawn partner = props.partner; @@ -371,27 +371,4 @@ namespace RJW_Menstruation } } - - [HarmonyPatch(typeof(PawnCapacityWorker_Fertility), nameof(PawnCapacityWorker_Fertility.CalculateCapacityLevel))] - public static class PawnCapacityWorker_Fertility_Patch - { - private static float GetFertilityStatOrOne(Thing thing, StatDef stat, bool applyPostProcess, int cacheStaleAfterTicks) - { - Pawn pawn = (Pawn)thing; - if (pawn.GetMenstruationComps().Any(comp => comp.calculatingOvulationChance)) - return 1.0f; - else return thing.GetStatValue(stat, applyPostProcess, cacheStaleAfterTicks); - } - private static readonly MethodInfo GetStatValue = AccessTools.Method(typeof(StatExtension), "GetStatValue", new System.Type[] { typeof(Thing), typeof(StatDef), typeof(bool), typeof(int) }); - public static IEnumerable Transpiler(IEnumerable instructions) - { - if (GetStatValue == null || GetStatValue.ReturnType != typeof(float)) throw new System.InvalidOperationException("GetStatValue not found"); - foreach (CodeInstruction instruction in instructions) - { - if (instruction.Calls(GetStatValue)) - yield return CodeInstruction.Call(typeof(PawnCapacityWorker_Fertility_Patch), nameof(GetFertilityStatOrOne)); - else yield return instruction; - } - } - } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/QuirkUtility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/QuirkUtility.cs deleted file mode 100644 index c8c2352..0000000 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/QuirkUtility.cs +++ /dev/null @@ -1,33 +0,0 @@ -using rjw; -using Verse; - -namespace RJW_Menstruation -{ - public static class QuirkUtility - { - // All quirks used in Menstruation - public enum Quirks - { - Breeder, - ImpregnationFetish, - Messy, - Teratophile, - } - public static bool HasQuirk(this Pawn pawn, Quirks quirk) - { - switch (quirk) - { - case Quirks.Breeder: - return pawn.Has(Quirk.Breeder); - case Quirks.ImpregnationFetish: - return pawn.Has(Quirk.ImpregnationFetish); - case Quirks.Messy: - return pawn.Has(Quirk.Messy); - case Quirks.Teratophile: - return pawn.Has(Quirk.Teratophile); - default: - return false; - } - } - } -} 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 f2f1834..0266ab8 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj @@ -77,7 +77,6 @@ - diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs index 1a67ebf..7b0862d 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs @@ -134,8 +134,6 @@ namespace RJW_Menstruation public static readonly string EstimatedCumLifespan = "EstimatedCumLifespan".Translate(); public static readonly string EstimatedEggLifespan = "EstimatedEggLifespan".Translate(); - public static string OvulationChanceLabel(string value) => "OvulationChanceLabel".Translate(value); - public static readonly string OvulationChanceDesc = "OvulationChanceDesc".Translate(); public static string FertilityDesc(string value) => "FertilityDesc".Translate(value); public static readonly string Gizmo_GatherCum = "Gizmo_GatherCum".Translate(); diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs index 9b726b2..4d428a9 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs @@ -228,7 +228,7 @@ namespace RJW_Menstruation string fainfo = PregnancyCommon.GetFatherInfo(babiescomp?.babies, babiescomp.Pawn, true) + " "; // Keep all parents known, for now if (feinfo == "Null") feinfo = "1 " + p.Mother.def.label + " " + Translations.Dialog_WombInfo02; - if (fainfo == "Null ") + if (fainfo == "Null") { string father = p.Father?.LabelShort ?? Translations.Dialog_FatherUnknown; fainfo = Translations.Dialog_WombInfo03 + ": " + father + " "; @@ -450,18 +450,11 @@ namespace RJW_Menstruation statvalue = pawn.records.GetValue(xxx.CountOfBirthEgg); FillableBarLabeled(lineRect, " " + xxx.CountOfBirthEgg.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 100, TextureCache.RecoverTexture, Texture2D.blackTexture, xxx.CountOfBirthEgg.description); - lineRect.y += height * 3; + lineRect.y += height * 4; - if (ModsConfig.BiotechActive && xxx.is_human(pawn)) - { - statvalue = comp.OvulationChance; - FillableBarLabeled(lineRect, " " + Translations.OvulationChanceLabel(statvalue.ToStringPercent()), statvalue, TextureCache.LutealTexture, Texture2D.blackTexture, Translations.OvulationChanceDesc); - } - lineRect.y += height; - - statvalue = Configurations.ImplantationChance * comp.ImplantChance; + statvalue = Configurations.ImplantationChance * comp.ImplantFactor; float fertchance = comp.GetFertilityChance(); - FillableBarLabeled(lineRect, " " + xxx.reproduction.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue, TextureCache.LutealTexture, Texture2D.blackTexture, Translations.FertilityDesc(string.Format("{0:0.##}", fertchance * 100))); + FillableBarLabeled(lineRect, " " + xxx.reproduction.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue, TextureCache.LutealTexture, Texture2D.blackTexture, Translations.FertilityDesc(String.Format("{0:0.##}", fertchance * 100))); Rect overayRect = new Rect(lineRect.x, lineRect.y, lineRect.width * Math.Min(1.0f, fertchance), lineRect.height); GUI.DrawTexture(overayRect, TextureCache.FertChanceTex); lineRect.y += height; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs index 13aae6e..af02fef 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs @@ -86,7 +86,7 @@ namespace RJW_Menstruation { res = 0.0f; } - if (pawn.HasQuirk(QuirkUtility.Quirks.Messy)) res *= Rand.Range(4.0f, 8.0f); + if (pawn.Has(Quirk.Messy)) res *= Rand.Range(4.0f, 8.0f); return res; } @@ -463,10 +463,6 @@ namespace RJW_Menstruation { return Color.white; } - catch (InvalidOperationException) // And sometimes it can try to pull the value of a Nullable without checking, too - { - return Color.white; - } } } } diff --git a/About/Manifest.xml b/About/Manifest.xml index 24b2e46..5477ddb 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ RJW Menstruation - 1.0.8.8 + 1.0.8.7 diff --git a/changelogs.txt b/changelogs.txt index 4647b8e..46e6221 100644 --- a/changelogs.txt +++ b/changelogs.txt @@ -1,14 +1,3 @@ -Version 1.0.8.8 - - Fix pawns skipping straight to menopause instead of going through climacteric stages. - - Fix father appearing as "Null" in womb dialog for some Biotech pregnancies. - - Fix Biotech multiple pregnancy births not being tracked in the mother's statistics. - - Other bug fixes - - Rework ovulation mechanics. A pawn's implantation chance is now dependent only on their age and climacteric effects. - - All other fertility-altering effects instead change the odds of ovulation occuring, rolled per-egg. This chance appears in the womb dialog. - - If the chance of ovulation goes above 100%, the implantation chance is increased. - - Drugs that increase the number of eggs ovulated are still guaranteed to work. - - If Biotech is disabled or not installed, the old fertility system will apply instead. - Version 1.0.8.7 - Fix missing texture when using Milkable Colonists. - Fix estrus and egg lifespan lasting far longer than intended.