mirror of
https://gitgud.io/lutepickle/rjw_menstruation.git
synced 2024-08-14 22:46:52 +00:00
Compare commits
18 commits
4382decbc7
...
9afb3c0df0
Author | SHA1 | Date | |
---|---|---|---|
|
9afb3c0df0 | ||
|
32800a3499 | ||
|
ff95b8da39 | ||
|
8306439576 | ||
|
ebb486179b | ||
|
f79050483d | ||
|
d483e22ac2 | ||
|
7e5b2000da | ||
|
836d3d69c8 | ||
|
50310988ca | ||
|
82dea0f425 | ||
|
cdfe9b44b8 | ||
|
b21fc85a29 | ||
|
48f020d832 | ||
|
23ae342722 | ||
|
509eeabddc | ||
|
6fabfd6aaf | ||
|
ebbbf8ee7f |
11 changed files with 62 additions and 124 deletions
Binary file not shown.
|
@ -144,11 +144,5 @@
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
</value>
|
</value>
|
||||||
</Operation>
|
</Operation>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Patch>
|
</Patch>
|
|
@ -110,9 +110,6 @@ namespace RJW_Menstruation
|
||||||
else return base.ShouldBeInEstrus();
|
else return base.ShouldBeInEstrus();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override float RandomOvulationChance()
|
protected override float RandomOvulationChance => 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,6 @@ namespace RJW_Menstruation
|
||||||
protected float implantationChanceCache = -1.0f;
|
protected float implantationChanceCache = -1.0f;
|
||||||
protected int opcache = -1;
|
protected int opcache = -1;
|
||||||
protected float antisperm = 0.0f;
|
protected float antisperm = 0.0f;
|
||||||
protected float? originvagsize = null;
|
|
||||||
// RJW pregnancy, or Biotech pregnancy/labor/laborpushing
|
// RJW pregnancy, or Biotech pregnancy/labor/laborpushing
|
||||||
protected Hediff pregnancy = null;
|
protected Hediff pregnancy = null;
|
||||||
|
|
||||||
|
@ -179,7 +178,8 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
public float HoursBetweenSimulations => (float)TickInterval / GenDate.TicksPerHour;
|
public float HoursBetweenSimulations => (float)TickInterval / GenDate.TicksPerHour;
|
||||||
|
|
||||||
public Hediff Pregnancy {
|
public Hediff Pregnancy
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (pregnancy == null) return null;
|
if (pregnancy == null) return null;
|
||||||
|
@ -255,7 +255,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
public float TotalCum
|
public float TotalCum
|
||||||
{
|
{
|
||||||
get => cums?.Sum(cum => cum.Volume) ?? 0;
|
get => cums?.Sum(cum => cum.Volume) ?? 0;
|
||||||
}
|
}
|
||||||
public float TotalFertCum
|
public float TotalFertCum
|
||||||
{
|
{
|
||||||
|
@ -322,6 +322,7 @@ namespace RJW_Menstruation
|
||||||
// Implant factor will be based solely on pawn age, plus any rollover from ovulation chance
|
// Implant factor will be based solely on pawn age, plus any rollover from ovulation chance
|
||||||
float factor = 1.0f;
|
float factor = 1.0f;
|
||||||
StatDefOf.Fertility.GetStatPart<StatPart_FertilityByGenderAge>()?.TransformValue(StatRequest.For(Pawn), ref factor);
|
StatDefOf.Fertility.GetStatPart<StatPart_FertilityByGenderAge>()?.TransformValue(StatRequest.For(Pawn), ref factor);
|
||||||
|
if (factor <= 0.0f) return 0.0f;
|
||||||
if (OvulationChance > 1.0f) factor *= OvulationChance;
|
if (OvulationChance > 1.0f) factor *= OvulationChance;
|
||||||
return Props.baseImplantationChanceFactor * FertilityModifier * factor;
|
return Props.baseImplantationChanceFactor * FertilityModifier * factor;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +357,7 @@ namespace RJW_Menstruation
|
||||||
{
|
{
|
||||||
if (cums.NullOrEmpty()) yield return Translations.Info_noCum;
|
if (cums.NullOrEmpty()) yield return Translations.Info_noCum;
|
||||||
else foreach (Cum cum in cums)
|
else foreach (Cum cum in cums)
|
||||||
yield return string.Format("{0}: {1:0.##}ml", cum.notcum ? cum.notcumLabel : cum.pawn?.Label, cum.Volume);
|
yield return string.Format("{0}: {1:0.##}ml", cum.notcum ? cum.notcumLabel : cum.pawn?.Label, cum.Volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Color GetCumMixtureColor
|
public Color GetCumMixtureColor
|
||||||
|
@ -563,19 +564,6 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float OriginVagSize
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (originvagsize == null)
|
|
||||||
{
|
|
||||||
originvagsize = parent.Severity;
|
|
||||||
}
|
|
||||||
return originvagsize ?? 0.1f;
|
|
||||||
}
|
|
||||||
set => originvagsize = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CurStageIntervalTicks
|
public int CurStageIntervalTicks
|
||||||
{
|
{
|
||||||
get => currentIntervalTicks;
|
get => currentIntervalTicks;
|
||||||
|
@ -608,7 +596,7 @@ namespace RJW_Menstruation
|
||||||
else if (Pawn.story?.bodyType == BodyTypeDefOf.Female) discoveryTime = 0.35f;
|
else if (Pawn.story?.bodyType == BodyTypeDefOf.Female) discoveryTime = 0.35f;
|
||||||
// Estimated; there's no way to get the exact value after the fact without writing it into the save
|
// Estimated; there's no way to get the exact value after the fact without writing it into the save
|
||||||
float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * GenDate.HoursPerDay));
|
float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * GenDate.HoursPerDay));
|
||||||
|
|
||||||
return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity);
|
return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -656,7 +644,6 @@ namespace RJW_Menstruation
|
||||||
Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true);
|
Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true);
|
||||||
Scribe_Values.Look(ref eggstack, "eggstack", 0);
|
Scribe_Values.Look(ref eggstack, "eggstack", 0);
|
||||||
Scribe_Values.Look(ref estrusflag, "estrusflag", false);
|
Scribe_Values.Look(ref estrusflag, "estrusflag", false);
|
||||||
Scribe_Values.Look(ref originvagsize, "originvagsize", originvagsize, true);
|
|
||||||
Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", false);
|
Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", false);
|
||||||
Scribe_References.Look(ref pregnancy, "pregnancy");
|
Scribe_References.Look(ref pregnancy, "pregnancy");
|
||||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||||
|
@ -679,12 +666,10 @@ namespace RJW_Menstruation
|
||||||
ovulationFactor = 1f;
|
ovulationFactor = 1f;
|
||||||
noBleeding = false;
|
noBleeding = false;
|
||||||
opcache = -1;
|
opcache = -1;
|
||||||
|
|
||||||
if (Pawn.genes == null || !ModsConfig.BiotechActive) return;
|
|
||||||
foreach (MenstruationModExtension extension in Pawn.genes.GenesListForReading.Select(gene => gene.def.GetModExtension<MenstruationModExtension>()))
|
|
||||||
{
|
|
||||||
if (extension == null) continue;
|
|
||||||
|
|
||||||
|
if (Pawn.genes == null || !ModsConfig.BiotechActive) return;
|
||||||
|
foreach (MenstruationModExtension extension in Pawn.genes.GenesListForReading.Select(gene => gene.def.GetModExtension<MenstruationModExtension>()).Where(ext => ext != null))
|
||||||
|
{
|
||||||
eggLifeSpanTicks = (int)(eggLifeSpanTicks * extension.eggLifeTimeFactor);
|
eggLifeSpanTicks = (int)(eggLifeSpanTicks * extension.eggLifeTimeFactor);
|
||||||
if (extension.alwaysEstrus) estrusLevel = EstrusLevel.Visible;
|
if (extension.alwaysEstrus) estrusLevel = EstrusLevel.Visible;
|
||||||
else if (extension.neverEstrus) estrusLevel = EstrusLevel.None;
|
else if (extension.neverEstrus) estrusLevel = EstrusLevel.None;
|
||||||
|
@ -721,7 +706,7 @@ namespace RJW_Menstruation
|
||||||
{
|
{
|
||||||
if (Pawn.IsHashIntervalTick(recalculateTickInterval)) TickInterval = -1; // Every so often, force TickInterval to be recalculated in case the pawn's status changed.
|
if (Pawn.IsHashIntervalTick(recalculateTickInterval)) TickInterval = -1; // Every so often, force TickInterval to be recalculated in case the pawn's status changed.
|
||||||
if (!Pawn.IsHashIntervalTick(TickInterval)) return;
|
if (!Pawn.IsHashIntervalTick(TickInterval)) return;
|
||||||
|
|
||||||
if (!ShouldSimulate()) return;
|
if (!ShouldSimulate()) return;
|
||||||
|
|
||||||
// Initialize immediately if needed, but if there's an error, then don't spam it every tick
|
// Initialize immediately if needed, but if there's an error, then don't spam it every tick
|
||||||
|
@ -730,7 +715,7 @@ namespace RJW_Menstruation
|
||||||
Log.Warning($"{Pawn}'s womb is ticking, but was not initialized first");
|
Log.Warning($"{Pawn}'s womb is ticking, but was not initialized first");
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initError) Log.Warning($"Attempting to process {Pawn}'s womb uninitialized");
|
if (initError) Log.Warning($"Attempting to process {Pawn}'s womb uninitialized");
|
||||||
|
|
||||||
if (Pregnancy != null && curStage != Stage.Pregnant)
|
if (Pregnancy != null && curStage != Stage.Pregnant)
|
||||||
|
@ -740,7 +725,7 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
|
|
||||||
BeforeSimulator();
|
BeforeSimulator();
|
||||||
|
|
||||||
if (ShouldBeInfertile()) GoNextStage(Stage.Infertile);
|
if (ShouldBeInfertile()) GoNextStage(Stage.Infertile);
|
||||||
switch (curStage)
|
switch (curStage)
|
||||||
{
|
{
|
||||||
|
@ -817,7 +802,7 @@ namespace RJW_Menstruation
|
||||||
tip.Append(": ");
|
tip.Append(": ");
|
||||||
tip.Append(GetCurStageLabel);
|
tip.Append(GetCurStageLabel);
|
||||||
string fertInfo = GetFertilizingInfo;
|
string fertInfo = GetFertilizingInfo;
|
||||||
if(CurrentVisibleStage == Stage.Luteal && fertInfo.Length > 0)
|
if (CurrentVisibleStage == Stage.Luteal && fertInfo.Length > 0)
|
||||||
{
|
{
|
||||||
tip.AppendLine();
|
tip.AppendLine();
|
||||||
tip.Append(fertInfo);
|
tip.Append(fertInfo);
|
||||||
|
@ -828,7 +813,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
protected virtual int TicksToNextStage()
|
protected virtual int TicksToNextStage()
|
||||||
{
|
{
|
||||||
return Math.Max(0,(currentIntervalTicks - curStageTicks) / Configurations.CycleAcceleration);
|
return Math.Max(0, (currentIntervalTicks - curStageTicks) / Configurations.CycleAcceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string CompDebugString()
|
public override string CompDebugString()
|
||||||
|
@ -1173,7 +1158,7 @@ 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();
|
InitOvary();
|
||||||
|
|
||||||
if (currentIntervalTicks < 0)
|
if (currentIntervalTicks < 0)
|
||||||
|
@ -1361,7 +1346,7 @@ namespace RJW_Menstruation
|
||||||
//float fertFailChancePerHour = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor);
|
//float fertFailChancePerHour = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor);
|
||||||
//float fertFailChancePerInterval = Mathf.Pow(fertFailChancePerHour, (float)TickInterval / GenDate.TicksPerHour);
|
//float fertFailChancePerInterval = Mathf.Pow(fertFailChancePerHour, (float)TickInterval / GenDate.TicksPerHour);
|
||||||
float fertFailChancePerInterval = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor * HoursBetweenSimulations);
|
float fertFailChancePerInterval = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor * HoursBetweenSimulations);
|
||||||
|
|
||||||
if (Rand.Chance(fertFailChancePerInterval)) return null;
|
if (Rand.Chance(fertFailChancePerInterval)) return null;
|
||||||
|
|
||||||
Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1);
|
Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1);
|
||||||
|
@ -1491,7 +1476,7 @@ namespace RJW_Menstruation
|
||||||
float interspeciesFactor = InterspeciesImplantFactor(egg.fertilizer);
|
float interspeciesFactor = InterspeciesImplantFactor(egg.fertilizer);
|
||||||
float implantChance = Configurations.ImplantationChance * ImplantChance * interspeciesFactor;
|
float implantChance = Configurations.ImplantationChance * ImplantChance * interspeciesFactor;
|
||||||
Log.Message($"Fertilized egg of {Pawn} failed to implant (chance {implantChance.ToStringPercent()}, " +
|
Log.Message($"Fertilized egg of {Pawn} failed to implant (chance {implantChance.ToStringPercent()}, " +
|
||||||
(interspeciesFactor < 1.0f ? $"interspecies factor {interspeciesFactor.ToStringPercent()}, " : "" ) +
|
(interspeciesFactor < 1.0f ? $"interspecies factor {interspeciesFactor.ToStringPercent()}, " : "") +
|
||||||
$"father {egg.fertilizer})");
|
$"father {egg.fertilizer})");
|
||||||
}
|
}
|
||||||
deadeggs.Add(egg);
|
deadeggs.Add(egg);
|
||||||
|
@ -1577,9 +1562,6 @@ namespace RJW_Menstruation
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected void EggDecay()
|
protected void EggDecay()
|
||||||
{
|
{
|
||||||
HashSet<Egg> deadeggs = new HashSet<Egg>();
|
HashSet<Egg> deadeggs = new HashSet<Egg>();
|
||||||
|
@ -1656,7 +1638,7 @@ namespace RJW_Menstruation
|
||||||
eggnum = 1f;
|
eggnum = 1f;
|
||||||
}
|
}
|
||||||
eggnum *= ovulationFactor;
|
eggnum *= ovulationFactor;
|
||||||
int toOvulate = (int)eggnum + eggstack;
|
int toOvulate = Math.Max(1, (int)eggnum + eggstack);
|
||||||
|
|
||||||
int ovulated = 0;
|
int ovulated = 0;
|
||||||
for (int i = 0; i < toOvulate; i++)
|
for (int i = 0; i < toOvulate; i++)
|
||||||
|
@ -1667,7 +1649,7 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
ovarypower -= ovulated;
|
ovarypower -= ovulated;
|
||||||
eggstack = 0;
|
eggstack = 0;
|
||||||
if (Configurations.Debug && ovulated != toOvulate)
|
if (Configurations.Debug && ovulated < toOvulate)
|
||||||
Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({OvulationChance.ToStringPercent()} chance)");
|
Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({OvulationChance.ToStringPercent()} chance)");
|
||||||
|
|
||||||
GoNextStage(Stage.Luteal);
|
GoNextStage(Stage.Luteal);
|
||||||
|
@ -1814,10 +1796,10 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
else pawnMemories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer);
|
else pawnMemories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer);
|
||||||
}
|
}
|
||||||
else if (Pawn.relations.OpinionOf(cummer) <= -5)
|
else if (Pawn.relations.OpinionOf(cummer) <= -5)
|
||||||
pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer);
|
pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer);
|
||||||
else if (Pawn.IsInEstrus() && Pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup)
|
else if (Pawn.IsInEstrus() && Pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup)
|
||||||
pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer);
|
pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer);
|
||||||
else if (!Pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !Pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer))
|
else if (!Pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !Pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer))
|
||||||
{
|
{
|
||||||
if (Pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) pawnMemories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer);
|
if (Pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) pawnMemories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer);
|
||||||
|
@ -1914,16 +1896,13 @@ namespace RJW_Menstruation
|
||||||
else return Rand.Range(0.6f, 1.0f);
|
else return Rand.Range(0.6f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual float RandomOvulationChance()
|
protected virtual float RandomOvulationChance => (float)Props.ovulationIntervalHours / GenDate.HoursPerDay;
|
||||||
{
|
|
||||||
return (float)Props.ovulationIntervalHours / GenDate.HoursPerDay;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Stage RandomStage()
|
protected Stage RandomStage()
|
||||||
{
|
{
|
||||||
Stage stage = Rand.ElementByWeight(
|
Stage stage = Rand.ElementByWeight(
|
||||||
Stage.Follicular, Props.follicularIntervalDays - Props.bleedingIntervalDays,
|
Stage.Follicular, Props.follicularIntervalDays - Props.bleedingIntervalDays,
|
||||||
Stage.Ovulatory, RandomOvulationChance(),
|
Stage.Ovulatory, RandomOvulationChance,
|
||||||
Stage.Luteal, Props.lutealIntervalDays,
|
Stage.Luteal, Props.lutealIntervalDays,
|
||||||
Stage.Bleeding, Props.bleedingIntervalDays);
|
Stage.Bleeding, Props.bleedingIntervalDays);
|
||||||
|
|
||||||
|
@ -2035,28 +2014,6 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
public class HediffComp_Anus : HediffComp
|
public class HediffComp_Anus : HediffComp
|
||||||
{
|
{
|
||||||
protected float? originanussize;
|
public CompProperties_Anus Props => (CompProperties_Anus)props;
|
||||||
|
|
||||||
public float OriginAnusSize
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (originanussize == null)
|
|
||||||
{
|
|
||||||
originanussize = parent.Severity;
|
|
||||||
}
|
|
||||||
return originanussize ?? 0.1f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CompExposeData()
|
|
||||||
{
|
|
||||||
base.CompExposeData();
|
|
||||||
Scribe_Values.Look(ref originanussize, "originanussize", originanussize, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CompPostTick(ref float severityAdjustment)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,14 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
protected override void InitializeExtraValues()
|
protected override void InitializeExtraValues()
|
||||||
{
|
{
|
||||||
base.InitializeExtraValues();
|
base.InitializeExtraValues();
|
||||||
if (averageCycleIntervalTicks < 0)
|
if (averageCycleIntervalTicks < 0)
|
||||||
{
|
{
|
||||||
averageCycleIntervalTicks = (int)(Props.cycleIntervalDays.RandomInRange * GenDate.TicksPerDay / cycleSpeed);
|
averageCycleIntervalTicks = (int)(Props.cycleIntervalDays.RandomInRange * GenDate.TicksPerDay / cycleSpeed);
|
||||||
if (ticksToNextCycle < -50000)
|
if (ticksToNextCycle < -50000)
|
||||||
ticksToNextCycle = Rand.Range(0, averageCycleIntervalTicks);
|
ticksToNextCycle = Rand.Range(0, averageCycleIntervalTicks);
|
||||||
// Make the cutoff halfway into cycle, just to be sure there isn't a double-cycle the first time
|
// Make the cutoff halfway into cycle, just to be sure there isn't a double-cycle the first time
|
||||||
if ((curStage == Stage.Follicular || curStage == Stage.Luteal || curStage == Stage.Bleeding)
|
if ((curStage == Stage.Follicular || curStage == Stage.Ovulatory || curStage == Stage.Luteal || curStage == Stage.Bleeding)
|
||||||
&& (averageCycleIntervalTicks - ticksToNextCycle) / 2 >= GenDate.TicksPerDay * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed)
|
&& (averageCycleIntervalTicks - ticksToNextCycle) / 2 >= GenDate.TicksPerDay * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed)
|
||||||
GoNextStage(Stage.Anestrus);
|
GoNextStage(Stage.Anestrus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace RJW_Menstruation
|
||||||
else if (gestationProgress < 0.8f) icon = fetustex + "04";
|
else if (gestationProgress < 0.8f) icon = fetustex + "04";
|
||||||
else icon = fetustex + "05";
|
else icon = fetustex + "05";
|
||||||
|
|
||||||
return TryGetTwinsIcon(icon, babycount) ?? ContentFinder<Texture2D>.Get((icon), true);
|
return TryGetTwinsIcon(icon, babycount) ?? ContentFinder<Texture2D>.Get(icon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Texture2D TryGetTwinsIcon(string path, int babycount)
|
public static Texture2D TryGetTwinsIcon(string path, int babycount)
|
||||||
|
@ -160,7 +160,7 @@ namespace RJW_Menstruation
|
||||||
|
|
||||||
List<Hediff_InsectEgg> insectEggs = new List<Hediff_InsectEgg>();
|
List<Hediff_InsectEgg> insectEggs = new List<Hediff_InsectEgg>();
|
||||||
comp.Pawn.health.hediffSet.GetHediffs(ref insectEggs);
|
comp.Pawn.health.hediffSet.GetHediffs(ref insectEggs);
|
||||||
if (!insectEggs.NullOrEmpty() && insectEggs.Sum(hediff => hediff.eggssize) > 1.0f) return null; // same logic as "Stuffed" in GetInsectEggedIcon
|
if (insectEggs?.Sum(hediff => hediff.eggssize) > 1.0f) return null; // same logic as "Stuffed" in GetInsectEggedIcon
|
||||||
|
|
||||||
string icon = comp.WombTex;
|
string icon = comp.WombTex;
|
||||||
float cumpercent = comp.TotalCumPercent;
|
float cumpercent = comp.TotalCumPercent;
|
||||||
|
@ -183,7 +183,7 @@ namespace RJW_Menstruation
|
||||||
else if (cumpercent < 0.89f) icon += "_Cum_15";
|
else if (cumpercent < 0.89f) icon += "_Cum_15";
|
||||||
else if (cumpercent < 0.95f) icon += "_Cum_16";
|
else if (cumpercent < 0.95f) icon += "_Cum_16";
|
||||||
else icon += "_Cum_17";
|
else icon += "_Cum_17";
|
||||||
Texture2D cumtex = ContentFinder<Texture2D>.Get((icon), true);
|
Texture2D cumtex = ContentFinder<Texture2D>.Get(icon, true);
|
||||||
return cumtex;
|
return cumtex;
|
||||||
}
|
}
|
||||||
public static Texture2D GetInsectEggedIcon(this HediffComp_Menstruation comp)
|
public static Texture2D GetInsectEggedIcon(this HediffComp_Menstruation comp)
|
||||||
|
@ -306,15 +306,13 @@ namespace RJW_Menstruation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Texture2D GetGenitalIcon(this Pawn pawn, HediffComp_Menstruation comp, bool drawOrigin = false)
|
public static Texture2D GetGenitalIcon(this Pawn pawn, HediffComp_Menstruation comp)
|
||||||
{
|
{
|
||||||
Hediff hediff = comp?.parent;
|
Hediff hediff = comp?.parent;
|
||||||
if (hediff == null) return ContentFinder<Texture2D>.Get("Genitals/Vagina00", true);
|
if (hediff == null) return ContentFinder<Texture2D>.Get("Genitals/Vagina00", true);
|
||||||
//HediffComp_Menstruation comp = hediff.GetMenstruationComp();
|
//HediffComp_Menstruation comp = hediff.GetMenstruationComp();
|
||||||
string icon;
|
string icon;
|
||||||
float severity;
|
float severity = hediff.Severity;
|
||||||
if (drawOrigin) severity = comp.OriginVagSize;
|
|
||||||
else severity = hediff.Severity;
|
|
||||||
if (comp != null) icon = comp.VagTex;
|
if (comp != null) icon = comp.VagTex;
|
||||||
else icon = "Genitals/Vagina";
|
else icon = "Genitals/Vagina";
|
||||||
|
|
||||||
|
@ -331,30 +329,18 @@ namespace RJW_Menstruation
|
||||||
else if (severity < 1.01f) icon += "10"; //cavernous
|
else if (severity < 1.01f) icon += "10"; //cavernous
|
||||||
else icon += "11"; //abyssal
|
else icon += "11"; //abyssal
|
||||||
|
|
||||||
return ContentFinder<Texture2D>.Get((icon), true);
|
return ContentFinder<Texture2D>.Get(icon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Texture2D GetAnalIcon(this Pawn pawn, bool drawOrigin = false)
|
public static Texture2D GetAnalIcon(this Pawn pawn)
|
||||||
{
|
{
|
||||||
Hediff hediff = pawn.health.hediffSet.hediffs.FirstOrDefault(h => VariousDefOf.AllAnuses.Contains(h.def)) ??
|
Hediff hediff = pawn.health.hediffSet.hediffs.FirstOrDefault(h => VariousDefOf.AllAnuses.Contains(h.def)) ??
|
||||||
pawn.health.hediffSet.hediffs.FirstOrDefault(h => h.def.defName.ToLower().Contains("anus"));
|
pawn.health.hediffSet.hediffs.FirstOrDefault(h => h.def.defName.ToLower().Contains("anus"));
|
||||||
if (hediff == null) return ContentFinder<Texture2D>.Get(("Genitals/Anal00"), true);
|
if (hediff == null) return ContentFinder<Texture2D>.Get("Genitals/Anal00", true);
|
||||||
|
|
||||||
|
string icon = ((CompProperties_Anus)hediff.GetAnusComp()?.props)?.analTex ?? "Genitals/Anal";
|
||||||
|
float severity = hediff.Severity;
|
||||||
|
|
||||||
string icon;
|
|
||||||
float severity;
|
|
||||||
HediffComp_Anus comp = hediff.GetAnusComp();
|
|
||||||
if (comp != null)
|
|
||||||
{
|
|
||||||
CompProperties_Anus Props = (CompProperties_Anus)comp.props;
|
|
||||||
icon = Props.analTex ?? "Genitals/Anal";
|
|
||||||
if (drawOrigin) severity = comp.OriginAnusSize;
|
|
||||||
else severity = hediff.Severity;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
icon = "Genitals/Anal";
|
|
||||||
severity = hediff.Severity;
|
|
||||||
}
|
|
||||||
if (severity < 0.20f) icon += "00"; //micro
|
if (severity < 0.20f) icon += "00"; //micro
|
||||||
else if (severity < 0.40f) icon += "01"; //tight
|
else if (severity < 0.40f) icon += "01"; //tight
|
||||||
else if (severity < 0.60f) icon += "02"; //average
|
else if (severity < 0.60f) icon += "02"; //average
|
||||||
|
@ -362,7 +348,7 @@ namespace RJW_Menstruation
|
||||||
else if (severity < 1.01f) icon += "04"; //cavernous
|
else if (severity < 1.01f) icon += "04"; //cavernous
|
||||||
else icon += "05"; //abyssal
|
else icon += "05"; //abyssal
|
||||||
|
|
||||||
return ContentFinder<Texture2D>.Get((icon), true);
|
return ContentFinder<Texture2D>.Get(icon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float GestationHours(this Hediff hediff)
|
public static float GestationHours(this Hediff hediff)
|
||||||
|
@ -453,7 +439,7 @@ namespace RJW_Menstruation
|
||||||
if (precept != null) return true;
|
if (precept != null) return true;
|
||||||
|
|
||||||
else return pawn.IsBreeder() ||
|
else return pawn.IsBreeder() ||
|
||||||
pawn.HasImpregnationFetish();
|
pawn.HasImpregnationFetish();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float DamagePants(this Pawn pawn, float fluidAmount)
|
public static float DamagePants(this Pawn pawn, float fluidAmount)
|
||||||
|
|
|
@ -225,9 +225,7 @@ namespace RJW_Menstruation
|
||||||
bool newHasStats = !DirtyDef.equippedStatOffsets.NullOrEmpty();
|
bool newHasStats = !DirtyDef.equippedStatOffsets.NullOrEmpty();
|
||||||
def = DirtyDef;
|
def = DirtyDef;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
OutfitForcedHandler forcedHandler = Wearer.outfits?.forcedHandler;
|
Wearer.outfits?.forcedHandler?.SetForced(this, false);
|
||||||
if (forcedHandler?.IsForced(this) ?? false)
|
|
||||||
forcedHandler.SetForced(this, false);
|
|
||||||
if (oldHasStats || newHasStats)
|
if (oldHasStats || newHasStats)
|
||||||
Wearer.health.capacities.Notify_CapacityLevelsDirty();
|
Wearer.health.capacities.Notify_CapacityLevelsDirty();
|
||||||
Wearer.apparel.Notify_ApparelChanged();
|
Wearer.apparel.Notify_ApparelChanged();
|
||||||
|
@ -274,7 +272,7 @@ namespace RJW_Menstruation
|
||||||
public override void DirtyEffect(int tickInterval)
|
public override void DirtyEffect(int tickInterval)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (wearTicks > MinHrstoDirtyEffect * GenDate.TicksPerHour && Rand.MTBEventOccurs(100.0f, GenDate.TicksPerHour, tickInterval) && !Wearer.apparel.IsLocked(this))
|
if (wearTicks > MinHrstoDirtyEffect * GenDate.TicksPerHour && Rand.MTBEventOccurs(100.0f, GenDate.TicksPerHour, tickInterval) && !(Wearer.apparel?.IsLocked(this) ?? false))
|
||||||
{
|
{
|
||||||
Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer));
|
Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer));
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,10 +388,9 @@ namespace RJW_Menstruation
|
||||||
Rect genitalIconRect = new Rect(rect.x, rect.y + fontheight, genitalRectWidth, genitalRectHeight);
|
Rect genitalIconRect = new Rect(rect.x, rect.y + fontheight, genitalRectWidth, genitalRectHeight);
|
||||||
Rect genitalVaginaLabelRect = new Rect(rect.x, rect.y + 10f, genitalRectWidth, fontheight);
|
Rect genitalVaginaLabelRect = new Rect(rect.x, rect.y + 10f, genitalRectWidth, fontheight);
|
||||||
Rect genitalAnusLabelRect = new Rect(rect.x, rect.y + fontheight + genitalRectHeight, genitalRectWidth, fontheight);
|
Rect genitalAnusLabelRect = new Rect(rect.x, rect.y + fontheight + genitalRectHeight, genitalRectWidth, fontheight);
|
||||||
bool showOrigin = Mouse.IsOver(genitalIconRect) && Input.GetMouseButton(0);
|
|
||||||
|
|
||||||
vagina = pawn.GetGenitalIcon(comp, showOrigin);
|
vagina = pawn.GetGenitalIcon(comp);
|
||||||
anal = pawn.GetAnalIcon(showOrigin);
|
anal = pawn.GetAnalIcon();
|
||||||
GUI.color = new Color(1.00f, 0.47f, 0.47f, 1);
|
GUI.color = new Color(1.00f, 0.47f, 0.47f, 1);
|
||||||
GUI.Box(rect, "", boxstyle);
|
GUI.Box(rect, "", boxstyle);
|
||||||
GUI.color = Utility.SafeSkinColor(pawn);
|
GUI.color = Utility.SafeSkinColor(pawn);
|
||||||
|
|
|
@ -276,7 +276,10 @@ namespace RJW_Menstruation
|
||||||
float res = 0;
|
float res = 0;
|
||||||
if (VariousDefOf.Hediff_Heavy_Lactating_Permanent != null)
|
if (VariousDefOf.Hediff_Heavy_Lactating_Permanent != null)
|
||||||
{
|
{
|
||||||
if (pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Heavy_Lactating_Permanent)) milkcomp = pawn.AllComps.FirstOrDefault(x => x.GetType().ToString().ToLower().Contains("hypermilkable"));
|
if (pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Heavy_Lactating_Permanent)
|
||||||
|
|| pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Lactating_Permanent)
|
||||||
|
|| pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Lactating_Natural)
|
||||||
|
|| pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Lactating_Drug)) milkcomp = pawn.AllComps.FirstOrDefault(x => x.GetType().ToString().ToLower().Contains("milkablehuman"));
|
||||||
else milkcomp = pawn.AllComps.FirstOrDefault(x => x.GetType().ToString().ToLower().Contains("milkable"));
|
else milkcomp = pawn.AllComps.FirstOrDefault(x => x.GetType().ToString().ToLower().Contains("milkable"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -58,9 +58,8 @@ namespace RJW_Menstruation
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (allraces != null) return allraces;
|
if (allraces != null) return allraces;
|
||||||
|
allraces = DefDatabase<ThingDef>.AllDefsListForReading.Where(thingdef => thingdef.race?.IsFlesh ?? false).ToList();
|
||||||
|
|
||||||
List<ThingDef> allThings = DefDatabase<ThingDef>.AllDefsListForReading;
|
|
||||||
allraces = allThings.FindAll(x => x.race != null && x.race.IsFlesh);
|
|
||||||
return allraces;
|
return allraces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,9 +68,8 @@ namespace RJW_Menstruation
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (allkinds != null) return allkinds;
|
if (allkinds != null) return allkinds;
|
||||||
|
allkinds = DefDatabase<PawnKindDef>.AllDefsListForReading.Where(pawnkinddef => pawnkinddef.race != null).ToList();
|
||||||
|
|
||||||
List<PawnKindDef> allKinds = DefDatabase<PawnKindDef>.AllDefsListForReading;
|
|
||||||
allkinds = allKinds.FindAll(x => x.race != null);
|
|
||||||
return allkinds;
|
return allkinds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +158,7 @@ namespace RJW_Menstruation
|
||||||
public static readonly HediffDef Hediff_Lactating_Natural = DefDatabase<HediffDef>.GetNamedSilentFail("Lactating_Natural");
|
public static readonly HediffDef Hediff_Lactating_Natural = DefDatabase<HediffDef>.GetNamedSilentFail("Lactating_Natural");
|
||||||
public static readonly HediffDef Hediff_Lactating_Permanent = DefDatabase<HediffDef>.GetNamedSilentFail("Lactating_Permanent");
|
public static readonly HediffDef Hediff_Lactating_Permanent = DefDatabase<HediffDef>.GetNamedSilentFail("Lactating_Permanent");
|
||||||
public static readonly HediffDef Hediff_Heavy_Lactating_Permanent = DefDatabase<HediffDef>.GetNamedSilentFail("Heavy_Lactating_Permanent");
|
public static readonly HediffDef Hediff_Heavy_Lactating_Permanent = DefDatabase<HediffDef>.GetNamedSilentFail("Heavy_Lactating_Permanent");
|
||||||
public static readonly JobDef Job_LactateSelf_MC = DefDatabase<JobDef>.GetNamedSilentFail("LactateSelf_MC");
|
public static readonly JobDef Job_LactateSelf_MC = DefDatabase<JobDef>.GetNamedSilentFail("MilkSelf");
|
||||||
|
|
||||||
// Defs from Sexperience Ideology
|
// Defs from Sexperience Ideology
|
||||||
public static readonly PreceptDef Pregnancy_Elevated = DefDatabase<PreceptDef>.GetNamedSilentFail("Pregnancy_Elevated");
|
public static readonly PreceptDef Pregnancy_Elevated = DefDatabase<PreceptDef>.GetNamedSilentFail("Pregnancy_Elevated");
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ModMetaData>
|
<ModMetaData>
|
||||||
|
<packageId>rjw.menstruation</packageId>
|
||||||
<name>RJW Menstruation Cycle</name>
|
<name>RJW Menstruation Cycle</name>
|
||||||
<author>lutepickle</author>
|
<author>lutepickle</author>
|
||||||
|
<url>https://gitgud.io/lutepickle/rjw_menstruation/</url>
|
||||||
<supportedVersions>
|
<supportedVersions>
|
||||||
<li>1.2</li>
|
<li>1.2</li>
|
||||||
<li>1.3</li>
|
<li>1.3</li>
|
||||||
|
@ -28,13 +30,17 @@
|
||||||
<li>Abraxas.RJW.RaceSupport</li>
|
<li>Abraxas.RJW.RaceSupport</li>
|
||||||
<li>rjw.milk.humanoid</li>
|
<li>rjw.milk.humanoid</li>
|
||||||
</loadAfter>
|
</loadAfter>
|
||||||
<packageId>rjw.menstruation</packageId>
|
<incompatibleWithByVersion>
|
||||||
|
<v1.4>
|
||||||
|
<li>conit.thebirdsandthebees</li> <!--Breaks fertility calculations-->
|
||||||
|
</v1.4>
|
||||||
|
</incompatibleWithByVersion>
|
||||||
<description>Adds menstruation mechanics to vaginas:
|
<description>Adds menstruation mechanics to vaginas:
|
||||||
|
|
||||||
Wombs cycle between follicular, luteal, and bleeding phases
|
Wombs cycle between follicular, luteal, and bleeding phases
|
||||||
Tracks eggs ovulated and cum in wombs to determine pregnancy
|
Tracks eggs ovulated and cum in wombs to determine pregnancy
|
||||||
Womb icon and status window
|
Womb icon and status window
|
||||||
Estrus effects
|
Estrus and pheromone effects
|
||||||
Race-specific fetus images for many vanilla animals
|
Race-specific fetus images for many vanilla animals
|
||||||
Pregnancies from multiple eggs and different fathers
|
Pregnancies from multiple eggs and different fathers
|
||||||
Identical siblings
|
Identical siblings
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue