diff --git a/1.4/Assemblies/RJW_Menstruation.dll b/1.4/Assemblies/RJW_Menstruation.dll
index 97337d7..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 d015752..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;
@@ -1037,7 +978,7 @@ namespace RJW_Menstruation
if (TotalCum > Props.maxCumCapacity * Pawn.BodySize) leakfactor = Math.Min(1 + (TotalCum - Props.maxCumCapacity * Pawn.BodySize) / 10, 2f);
if (absorber != null && absorber.dirty && !absorber.LeakAfterDirty) leakfactor = 0f;
if (Pawn.CurJobDef == xxx.knotted) leakfactor = 0f;
- HashSet removecums = new HashSet();
+ List removecums = new List();
foreach (Cum cum in cums)
{
cum.CumEffects(Pawn);
@@ -1050,7 +991,10 @@ namespace RJW_Menstruation
}
if (cums.Count > 1) MakeCumFilthMixture(totalleak, filthlabels);
else if (cums.Count == 1) MakeCumFilth(cums.First(), totalleak);
- cums.RemoveAll(cum => removecums.Contains(cum));
+ foreach (Cum cum in removecums)
+ {
+ cums.Remove(cum);
+ }
cumd = TotalCumPercent - cumd;
if (totalleak >= 1.0f) AfterCumOut();
AfterFluidOut(cumd);
@@ -1070,7 +1014,7 @@ namespace RJW_Menstruation
List filthlabels = new List();
float outcum = 0;
float cumd = TotalCumPercent;
- HashSet removecums = new HashSet();
+ List removecums = new List();
foreach (Cum cum in cums)
{
float vd = cum.DismishForce(portion);
@@ -1083,7 +1027,10 @@ namespace RJW_Menstruation
}
if (cums.Count > 1) MakeCumFilthMixture(totalleak, filthlabels);
else if (cums.Count == 1) MakeCumFilth(cums.First(), totalleak);
- cums.RemoveAll(cum => removecums.Contains(cum));
+ foreach (Cum cum in removecums)
+ {
+ cums.Remove(cum);
+ }
cumd = TotalCumPercent - cumd;
AfterFluidOut(cumd);
return outcum;
@@ -1101,7 +1048,7 @@ namespace RJW_Menstruation
Color color = GetCumMixtureColor;
float totalleak = 0;
List cumlabels = new List();
- HashSet removecums = new HashSet();
+ List removecums = new List();
bool pure = true;
foreach (Cum cum in cums)
{
@@ -1112,7 +1059,10 @@ namespace RJW_Menstruation
if (cum.ShouldRemove()) removecums.Add(cum);
if (cum.notcum) pure = false;
}
- cums.RemoveAll(cum => removecums.Contains(cum));
+ foreach (Cum cum in removecums)
+ {
+ cums.Remove(cum);
+ }
return new CumMixture(Pawn, totalleak, cumlabels, color, mixtureDef, pure);
}
@@ -1161,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)
@@ -1181,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");
@@ -1334,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);
@@ -1355,7 +1304,7 @@ namespace RJW_Menstruation
{
if (eggs.NullOrEmpty()) return false;
- HashSet deadeggs = new HashSet();
+ List deadeggs = new List();
bool pregnant = false;
foreach (Egg egg in eggs)
{
@@ -1375,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)
@@ -1448,7 +1397,9 @@ namespace RJW_Menstruation
rjw_preg.p_start_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour;
rjw_preg.p_end_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour;
}
+ if (!(pregnancy is Hediff_MultiplePregnancy)) break;
}
+
}
else
{
@@ -1465,7 +1416,12 @@ namespace RJW_Menstruation
return true;
}
else
- eggs.RemoveAll(egg => deadeggs.Contains(egg));
+ {
+ foreach (Egg egg in deadeggs)
+ {
+ eggs.Remove(egg);
+ }
+ }
return pregnant;
}
@@ -1535,7 +1491,7 @@ namespace RJW_Menstruation
protected void EggDecay()
{
- HashSet deadeggs = new HashSet();
+ List deadeggs = new List();
foreach (Egg egg in eggs)
{
egg.position += Configurations.CycleAcceleration;
@@ -1546,7 +1502,10 @@ namespace RJW_Menstruation
if (egg.lifespanhrs < 0) deadeggs.Add(egg);
}
}
- eggs.RemoveAll(egg => deadeggs.Contains(egg));
+ foreach (Egg egg in deadeggs)
+ {
+ eggs.Remove(egg);
+ }
}
protected void AddCrampPain()
@@ -1586,6 +1545,7 @@ namespace RJW_Menstruation
{
estrusflag = false;
float eggnum;
+ int ovulated;
try
{
eggnum = Math.Max(Rand.ByCurve(Pawn.def.race.litterSizeCurve), 1f);
@@ -1600,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.Min(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()
@@ -1625,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);
}
@@ -1704,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);
}
@@ -1726,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);
}
@@ -1753,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)
{
@@ -1769,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);
}
@@ -1792,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);
}
@@ -1813,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);
@@ -1822,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 fc6edef..5477ddb 100644
--- a/About/Manifest.xml
+++ b/About/Manifest.xml
@@ -1,7 +1,7 @@
RJW Menstruation
- 1.0.8.9
+ 1.0.8.7
diff --git a/changelogs.txt b/changelogs.txt
index f68bbbe..46e6221 100644
--- a/changelogs.txt
+++ b/changelogs.txt
@@ -1,17 +1,3 @@
-Version 1.0.8.9
- - Fix bug that sent pawns into menopause very early. Please use the recalculate ovary power dev action to restore lost eggs.
-
-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.