mirror of
https://gitgud.io/lutepickle/rjw_menstruation.git
synced 2024-08-14 22:46:52 +00:00
Compare commits
8 commits
297e37a4ef
...
3646f1135b
Author | SHA1 | Date | |
---|---|---|---|
|
3646f1135b | ||
|
1aaaf50b64 | ||
|
2bb0871919 | ||
|
4504d02245 | ||
|
98cfa23b88 | ||
|
c8d32f883f | ||
|
7825418da9 | ||
|
325b60b51c |
12 changed files with 140 additions and 45 deletions
Binary file not shown.
|
@ -120,6 +120,8 @@
|
||||||
<Option_EstrusRelationship_Label>Hookup minimum opinion in estrus</Option_EstrusRelationship_Label>
|
<Option_EstrusRelationship_Label>Hookup minimum opinion in estrus</Option_EstrusRelationship_Label>
|
||||||
<EstimatedCumLifespan>Estimated sperm lifespan</EstimatedCumLifespan>
|
<EstimatedCumLifespan>Estimated sperm lifespan</EstimatedCumLifespan>
|
||||||
<EstimatedEggLifespan>Estimated egg lifespan</EstimatedEggLifespan>
|
<EstimatedEggLifespan>Estimated egg lifespan</EstimatedEggLifespan>
|
||||||
|
<OvulationChanceLabel>Ovulation {0}</OvulationChanceLabel>
|
||||||
|
<OvulationChanceDesc>Chance of each egg being released during ovulation.</OvulationChanceDesc>
|
||||||
<FertilityDesc>Implantation chance of fertilized eggs. Chance of fertilization this hour: {0}%</FertilityDesc>
|
<FertilityDesc>Implantation chance of fertilized eggs. Chance of fertilization this hour: {0}%</FertilityDesc>
|
||||||
<Option_PregnancyFromBaseRJW_Label>Use basic RJW pregnancy</Option_PregnancyFromBaseRJW_Label>
|
<Option_PregnancyFromBaseRJW_Label>Use basic RJW pregnancy</Option_PregnancyFromBaseRJW_Label>
|
||||||
<Option_PregnancyFromMultiplePregnancy_Label>Use menstruation multiple pregnancy</Option_PregnancyFromMultiplePregnancy_Label>
|
<Option_PregnancyFromMultiplePregnancy_Label>Use menstruation multiple pregnancy</Option_PregnancyFromMultiplePregnancy_Label>
|
||||||
|
|
Binary file not shown.
|
@ -10,7 +10,7 @@ namespace RJW_Menstruation
|
||||||
private static void SetFollicular(Pawn p)
|
private static void SetFollicular(Pawn p)
|
||||||
{
|
{
|
||||||
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
||||||
comp.curStage = HediffComp_Menstruation.Stage.Follicular;
|
comp.GoNextStage(HediffComp_Menstruation.Stage.Follicular);
|
||||||
Messages.Message($"{p} is now follicular", p, MessageTypeDefOf.NeutralEvent, false);
|
Messages.Message($"{p} is now follicular", p, MessageTypeDefOf.NeutralEvent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace RJW_Menstruation
|
||||||
private static void SetOvulatory(Pawn p)
|
private static void SetOvulatory(Pawn p)
|
||||||
{
|
{
|
||||||
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
||||||
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
|
comp.GoNextStage(HediffComp_Menstruation.Stage.Ovulatory);
|
||||||
Messages.Message($"{p} is now ovulatory", p, MessageTypeDefOf.NeutralEvent, false);
|
Messages.Message($"{p} is now ovulatory", p, MessageTypeDefOf.NeutralEvent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace RJW_Menstruation
|
||||||
private static void SetLuteal(Pawn p)
|
private static void SetLuteal(Pawn p)
|
||||||
{
|
{
|
||||||
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
||||||
comp.curStage = HediffComp_Menstruation.Stage.Luteal;
|
comp.GoNextStage(HediffComp_Menstruation.Stage.Luteal);
|
||||||
Messages.Message($"{p} is now luteal", p, MessageTypeDefOf.NeutralEvent, false);
|
Messages.Message($"{p} is now luteal", p, MessageTypeDefOf.NeutralEvent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace RJW_Menstruation
|
||||||
private static void SetBleeding(Pawn p)
|
private static void SetBleeding(Pawn p)
|
||||||
{
|
{
|
||||||
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
|
||||||
comp.curStage = HediffComp_Menstruation.Stage.Bleeding;
|
comp.GoNextStage(HediffComp_Menstruation.Stage.Bleeding);
|
||||||
Messages.Message($"{p} is now bleeding", p, MessageTypeDefOf.NeutralEvent, false);
|
Messages.Message($"{p} is now bleeding", p, MessageTypeDefOf.NeutralEvent, false);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace RJW_Menstruation
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
comp.SetEstrus();
|
comp.SetEstrus();
|
||||||
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
|
comp.GoNextStage(HediffComp_Menstruation.Stage.Ovulatory);
|
||||||
comp.ovarypower--;
|
comp.ovarypower--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ namespace RJW_Menstruation
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
comp.SetEstrus();
|
comp.SetEstrus();
|
||||||
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
|
comp.GoNextStage(HediffComp_Menstruation.Stage.Ovulatory);
|
||||||
comp.eggstack += ingested.stackCount - 1;
|
comp.eggstack += ingested.stackCount - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,7 +203,7 @@ namespace RJW_Menstruation
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!Configurations.EnableMenopause || Props.infertile) return Mathf.Max(1.0f, ovarypower / OvaryPowerThreshold);
|
if (!Configurations.EnableMenopause || Props.infertile) return Mathf.Max(1.0f, ovarypower / OvaryPowerThreshold);
|
||||||
else return ovarypower / OvaryPowerThreshold;
|
else return (float)ovarypower / OvaryPowerThreshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,16 +280,63 @@ namespace RJW_Menstruation
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//effect on implant chance
|
|
||||||
public float ImplantFactor
|
// 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);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
calculatingOvulationChance = true;
|
||||||
|
ovulationChance *= PawnCapacityUtility.CalculateCapacityLevel(Pawn.health.hediffSet, xxx.reproduction);
|
||||||
|
}
|
||||||
|
finally { calculatingOvulationChance = false; }
|
||||||
|
}
|
||||||
|
return ovulationChance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public float ImplantChance
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
float factor = 1.0f;
|
float factor = 1.0f;
|
||||||
if (Pawn.Has(Quirk.Breeder)) factor = 10.0f;
|
if (Pawn.Has(Quirk.Breeder)) factor = 10.0f;
|
||||||
return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * factor;
|
|
||||||
|
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<StatPart_FertilityByGenderAge>();
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetCumsInfo
|
public IEnumerable<string> GetCumsInfo
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -345,13 +392,13 @@ namespace RJW_Menstruation
|
||||||
switch (CurrentVisibleStage)
|
switch (CurrentVisibleStage)
|
||||||
{
|
{
|
||||||
case Stage.Follicular:
|
case Stage.Follicular:
|
||||||
return Translations.Stage_Follicular + (EggHealth < 1f ? Translations.Stage_Climacteric : "");
|
return Translations.Stage_Follicular + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : "");
|
||||||
case Stage.Ovulatory:
|
case Stage.Ovulatory:
|
||||||
return Translations.Stage_Ovulatory + (EggHealth < 1f ? Translations.Stage_Climacteric : "");
|
return Translations.Stage_Ovulatory + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : "");
|
||||||
case Stage.Luteal:
|
case Stage.Luteal:
|
||||||
return Translations.Stage_Luteal + (EggHealth < 1f ? Translations.Stage_Climacteric : "");
|
return Translations.Stage_Luteal + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : "");
|
||||||
case Stage.Bleeding:
|
case Stage.Bleeding:
|
||||||
return Translations.Stage_Bleeding + (EggHealth < 1f ? Translations.Stage_Climacteric : "");
|
return Translations.Stage_Bleeding + (EggHealth < 1f ? " " + Translations.Stage_Climacteric : "");
|
||||||
case Stage.Pregnant:
|
case Stage.Pregnant:
|
||||||
return Translations.Stage_Pregnant;
|
return Translations.Stage_Pregnant;
|
||||||
case Stage.Recover:
|
case Stage.Recover:
|
||||||
|
@ -375,13 +422,13 @@ namespace RJW_Menstruation
|
||||||
switch (CurrentVisibleStage)
|
switch (CurrentVisibleStage)
|
||||||
{
|
{
|
||||||
case Stage.Follicular:
|
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:
|
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:
|
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:
|
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:
|
case Stage.Pregnant:
|
||||||
return Translations.Stage_Pregnant_Desc;
|
return Translations.Stage_Pregnant_Desc;
|
||||||
case Stage.Recover:
|
case Stage.Recover:
|
||||||
|
@ -678,7 +725,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
BeforeSimulator();
|
BeforeSimulator();
|
||||||
|
|
||||||
if (pregnancy == null && (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || EggHealth <= 0 || Pawn.SterileGenes())) GoNextStage(Stage.Infertile);
|
if (pregnancy == null && (ImplantChance <= 0.0f || EggHealth <= 0)) GoNextStage(Stage.Infertile);
|
||||||
switch (curStage)
|
switch (curStage)
|
||||||
{
|
{
|
||||||
case Stage.Follicular:
|
case Stage.Follicular:
|
||||||
|
@ -1111,9 +1158,12 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f);
|
if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f);
|
||||||
if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent();
|
if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent();
|
||||||
|
|
||||||
|
InitOvary();
|
||||||
|
|
||||||
if (currentIntervalHours < 0)
|
if (currentIntervalHours < 0)
|
||||||
{
|
{
|
||||||
if (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || Pawn.SterileGenes()) curStage = Stage.Infertile;
|
if (ImplantChance <= 0.0f || EggHealth <= 0) curStage = Stage.Infertile;
|
||||||
else if (!IsBreedingSeason()) curStage = Stage.Anestrus;
|
else if (!IsBreedingSeason()) curStage = Stage.Anestrus;
|
||||||
else curStage = RandomStage();
|
else curStage = RandomStage();
|
||||||
if (curStage == Stage.Follicular)
|
if (curStage == Stage.Follicular)
|
||||||
|
@ -1128,8 +1178,6 @@ namespace RJW_Menstruation
|
||||||
if (cums == null) cums = new List<Cum>();
|
if (cums == null) cums = new List<Cum>();
|
||||||
if (eggs == null) eggs = new List<Egg>();
|
if (eggs == null) eggs = new List<Egg>();
|
||||||
|
|
||||||
|
|
||||||
InitOvary();
|
|
||||||
TakeLoosePregnancy();
|
TakeLoosePregnancy();
|
||||||
|
|
||||||
//Log.Message(Pawn.Label + " - Initialized menstruation comp");
|
//Log.Message(Pawn.Label + " - Initialized menstruation comp");
|
||||||
|
@ -1283,7 +1331,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume);
|
float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume);
|
||||||
|
|
||||||
if (Rand.Range(0.0f, 1.0f) > 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor))
|
if (Rand.Chance(Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor)))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1);
|
Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1);
|
||||||
|
@ -1324,7 +1372,7 @@ namespace RJW_Menstruation
|
||||||
deadeggs.Add(egg);
|
deadeggs.Add(egg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (Rand.Range(0.0f, 1.0f) <= Configurations.ImplantationChance * ImplantFactor * InterspeciesImplantFactor(egg.fertilizer))
|
else if (Rand.Chance(Configurations.ImplantationChance * ImplantChance * InterspeciesImplantFactor(egg.fertilizer)))
|
||||||
{
|
{
|
||||||
if (Configurations.Debug) Log.Message($"Implanting fertilized egg of {Pawn} into {parent}, father {egg.fertilizer}");
|
if (Configurations.Debug) Log.Message($"Implanting fertilized egg of {Pawn} into {parent}, father {egg.fertilizer}");
|
||||||
if (pregnancy != null)
|
if (pregnancy != null)
|
||||||
|
@ -1527,7 +1575,7 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
else if (curStageHrs >= currentIntervalHours)
|
else if (curStageHrs >= currentIntervalHours)
|
||||||
{
|
{
|
||||||
GoOvulatoryStage();
|
GoNextStage(Stage.Ovulatory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1562,8 +1610,10 @@ namespace RJW_Menstruation
|
||||||
eggnum *= ovulationFactor;
|
eggnum *= ovulationFactor;
|
||||||
ovulated = (int)eggnum + eggstack;
|
ovulated = (int)eggnum + eggstack;
|
||||||
|
|
||||||
|
float ovulationChance = OvulationChance;
|
||||||
for (int i = 0; i < ovulated; i++)
|
for (int i = 0; i < ovulated; i++)
|
||||||
eggs.Add(new Egg((int)(EggLifespanHours / CycleFactor)));
|
if (i < eggstack || Rand.Chance(ovulationChance)) // eggstack comes from drugs and are guaranteed ovulated
|
||||||
|
eggs.Add(new Egg((int)(EggLifespanHours / CycleFactor)));
|
||||||
ovarypower -= ovulated;
|
ovarypower -= ovulated;
|
||||||
|
|
||||||
eggstack = 0;
|
eggstack = 0;
|
||||||
|
@ -1584,7 +1634,7 @@ namespace RJW_Menstruation
|
||||||
if (curStageHrs >= currentIntervalHours)
|
if (curStageHrs >= currentIntervalHours)
|
||||||
{
|
{
|
||||||
eggs.Clear();
|
eggs.Clear();
|
||||||
if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Range(0.0f, 1.0f) < 0.3f)) //skips bleeding
|
if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Chance(0.3f))) //skips bleeding
|
||||||
{
|
{
|
||||||
GoNextStage(Stage.Follicular);
|
GoNextStage(Stage.Follicular);
|
||||||
}
|
}
|
||||||
|
@ -1663,7 +1713,7 @@ namespace RJW_Menstruation
|
||||||
{
|
{
|
||||||
if (curStageHrs >= currentIntervalHours)
|
if (curStageHrs >= currentIntervalHours)
|
||||||
{
|
{
|
||||||
if (Pawn.health.capacities.GetLevel(xxx.reproduction) == 0 || EggHealth <= 0 || Pawn.SterileGenes())
|
if (ImplantChance <= 0.0f || EggHealth <= 0)
|
||||||
{
|
{
|
||||||
GoNextStage(Stage.Infertile);
|
GoNextStage(Stage.Infertile);
|
||||||
}
|
}
|
||||||
|
@ -1685,7 +1735,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
protected virtual void InfertileAction()
|
protected virtual void InfertileAction()
|
||||||
{
|
{
|
||||||
if (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || EggHealth <= 0 || Pawn.SterileGenes())
|
if (ImplantChance <= 0 || EggHealth <= 0)
|
||||||
{
|
{
|
||||||
StayCurrentStageConst(Stage.Infertile);
|
StayCurrentStageConst(Stage.Infertile);
|
||||||
}
|
}
|
||||||
|
@ -1772,7 +1822,7 @@ namespace RJW_Menstruation
|
||||||
TaleRecorder.RecordTale(VariousDefOf.TaleCameInside, new object[] { cummer, Pawn });
|
TaleRecorder.RecordTale(VariousDefOf.TaleCameInside, new object[] { cummer, Pawn });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GoNextStage(Stage nextstage, bool calculateHours = true)
|
public void GoNextStage(Stage nextstage, bool calculateHours = true)
|
||||||
{
|
{
|
||||||
curStageHrs = 0;
|
curStageHrs = 0;
|
||||||
if (calculateHours) currentIntervalHours = PeriodRandomizer(nextstage);
|
if (calculateHours) currentIntervalHours = PeriodRandomizer(nextstage);
|
||||||
|
@ -1781,12 +1831,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
protected virtual void GoOvulatoryStage()
|
protected virtual void GoOvulatoryStage()
|
||||||
{
|
{
|
||||||
if (EggHealth < 1.0f / 3.0f && Rand.Range(0.0f, 1.0f) < 0.2f) // Skip ovulation if deep into climacteric
|
GoNextStage(Stage.Ovulatory);
|
||||||
{
|
|
||||||
estrusflag = false;
|
|
||||||
GoNextStage(Stage.Luteal);
|
|
||||||
}
|
|
||||||
else GoNextStage(Stage.Ovulatory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//stage can be interrupted in other reasons
|
//stage can be interrupted in other reasons
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using RimWorld;
|
using RimWorld;
|
||||||
|
using RimWorld.Planet;
|
||||||
using rjw;
|
using rjw;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -218,6 +219,8 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
public static Texture2D GetEggIcon(this HediffComp_Menstruation comp, bool includeOvary)
|
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)
|
switch (comp.CurrentVisibleStage)
|
||||||
{
|
{
|
||||||
case HediffComp_Menstruation.Stage.Follicular:
|
case HediffComp_Menstruation.Stage.Follicular:
|
||||||
|
@ -228,15 +231,20 @@ namespace RJW_Menstruation
|
||||||
job.Sexprops != null &&
|
job.Sexprops != null &&
|
||||||
!job.Sexprops.usedCondom &&
|
!job.Sexprops.usedCondom &&
|
||||||
(job.Sexprops.sexType == xxx.rjwSextype.Vaginal || job.Sexprops.sexType == xxx.rjwSextype.DoublePenetration))
|
(job.Sexprops.sexType == xxx.rjwSextype.Vaginal || job.Sexprops.sexType == xxx.rjwSextype.DoublePenetration))
|
||||||
return ContentFinder<Texture2D>.Get("Ovaries/Ovary_01", true);
|
return ContentFinder<Texture2D>.Get((comp.OvulationChance >= ovaryChanceToShow_01) ? "Ovaries/Ovary_01" : "Ovaries_Ovary_00", true);
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
if (comp.curStageHrs > comp.CurStageIntervalHours - 30) // Approximate time for ovulation to occur
|
if (comp.curStageHrs > comp.CurStageIntervalHours - 30) // Approximate time for ovulation to occur
|
||||||
return ContentFinder<Texture2D>.Get("Ovaries/Ovary_01", true);
|
return ContentFinder<Texture2D>.Get((comp.OvulationChance >= ovaryChanceToShow_01) ? "Ovaries/Ovary_01" : "Ovaries_Ovary_00", true);
|
||||||
else break;
|
else break;
|
||||||
case HediffComp_Menstruation.Stage.Ovulatory:
|
case HediffComp_Menstruation.Stage.Ovulatory:
|
||||||
if (!includeOvary) break;
|
if (!includeOvary) break;
|
||||||
return ContentFinder<Texture2D>.Get("Ovaries/Ovary_02", true);
|
if (comp.OvulationChance >= ovaryChanceToShow_02)
|
||||||
|
return ContentFinder<Texture2D>.Get("Ovaries/Ovary_02", true);
|
||||||
|
else if (comp.OvulationChance >= ovaryChanceToShow_01)
|
||||||
|
return ContentFinder<Texture2D>.Get("Ovaries/Ovary_01", true);
|
||||||
|
else
|
||||||
|
return ContentFinder<Texture2D>.Get("Ovaries/Ovary_00", true);
|
||||||
case HediffComp_Menstruation.Stage.Luteal:
|
case HediffComp_Menstruation.Stage.Luteal:
|
||||||
if (!comp.IsEggExist) break;
|
if (!comp.IsEggExist) break;
|
||||||
int fertstage = comp.IsFertilized;
|
int fertstage = comp.IsFertilized;
|
||||||
|
|
|
@ -129,11 +129,11 @@ namespace RJW_Menstruation
|
||||||
else if (pawn.GetMenstruationComps().Any()) return false;
|
else if (pawn.GetMenstruationComps().Any()) return false;
|
||||||
else return pawn.IsPregnant();
|
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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
|
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
|
||||||
{
|
{
|
||||||
if (IsPregnant == null || IsPregnant.ReturnType != typeof(bool)) throw new System.InvalidOperationException("IsPregnant not found");
|
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))
|
if (instruction.Calls(IsPregnant))
|
||||||
yield return CodeInstruction.Call(typeof(CanImpregnate_Patch), nameof(PregnancyBlocksImpregnation));
|
yield return CodeInstruction.Call(typeof(CanImpregnate_Patch), nameof(PregnancyBlocksImpregnation));
|
||||||
|
@ -371,4 +371,27 @@ 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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,8 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
public static readonly string EstimatedCumLifespan = "EstimatedCumLifespan".Translate();
|
public static readonly string EstimatedCumLifespan = "EstimatedCumLifespan".Translate();
|
||||||
public static readonly string EstimatedEggLifespan = "EstimatedEggLifespan".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 string FertilityDesc(string value) => "FertilityDesc".Translate(value);
|
||||||
|
|
||||||
public static readonly string Gizmo_GatherCum = "Gizmo_GatherCum".Translate();
|
public static readonly string Gizmo_GatherCum = "Gizmo_GatherCum".Translate();
|
||||||
|
|
|
@ -450,11 +450,18 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
statvalue = pawn.records.GetValue(xxx.CountOfBirthEgg);
|
statvalue = pawn.records.GetValue(xxx.CountOfBirthEgg);
|
||||||
FillableBarLabeled(lineRect, " " + xxx.CountOfBirthEgg.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 100, TextureCache.RecoverTexture, Texture2D.blackTexture, xxx.CountOfBirthEgg.description);
|
FillableBarLabeled(lineRect, " " + xxx.CountOfBirthEgg.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 100, TextureCache.RecoverTexture, Texture2D.blackTexture, xxx.CountOfBirthEgg.description);
|
||||||
lineRect.y += height * 4;
|
lineRect.y += height * 3;
|
||||||
|
|
||||||
statvalue = Configurations.ImplantationChance * comp.ImplantFactor;
|
if (ModsConfig.BiotechActive)
|
||||||
|
{
|
||||||
|
statvalue = comp.OvulationChance;
|
||||||
|
FillableBarLabeled(lineRect, " " + Translations.OvulationChanceLabel(statvalue.ToStringPercent()), statvalue, TextureCache.LutealTexture, Texture2D.blackTexture, Translations.OvulationChanceDesc);
|
||||||
|
}
|
||||||
|
lineRect.y += height;
|
||||||
|
|
||||||
|
statvalue = Configurations.ImplantationChance * comp.ImplantChance;
|
||||||
float fertchance = comp.GetFertilityChance();
|
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);
|
Rect overayRect = new Rect(lineRect.x, lineRect.y, lineRect.width * Math.Min(1.0f, fertchance), lineRect.height);
|
||||||
GUI.DrawTexture(overayRect, TextureCache.FertChanceTex);
|
GUI.DrawTexture(overayRect, TextureCache.FertChanceTex);
|
||||||
lineRect.y += height;
|
lineRect.y += height;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<identifier>RJW Menstruation</identifier>
|
<identifier>RJW Menstruation</identifier>
|
||||||
<version>1.0.8.7</version>
|
<version>1.0.8.8</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<incompatibleWith />
|
<incompatibleWith />
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
Version 1.0.8.8
|
||||||
|
- Fix pawns skipping straight to menopause instead of going through climacteric stages.
|
||||||
|
- Rework ovulation mechanics. A pawn's implantation chance is now dependent on their age.
|
||||||
|
- 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
|
Version 1.0.8.7
|
||||||
- Fix missing texture when using Milkable Colonists.
|
- Fix missing texture when using Milkable Colonists.
|
||||||
- Fix estrus and egg lifespan lasting far longer than intended.
|
- Fix estrus and egg lifespan lasting far longer than intended.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue