diff --git a/1.3/Assemblies/RJW_Menstruation.dll b/1.3/Assemblies/RJW_Menstruation.dll
index 9f159dc..189a970 100644
Binary files a/1.3/Assemblies/RJW_Menstruation.dll and b/1.3/Assemblies/RJW_Menstruation.dll differ
diff --git a/1.3/Languages/English/Keyed/RJW_Menstruation.xml b/1.3/Languages/English/Keyed/RJW_Menstruation.xml
index bdb4a6f..908b411 100644
--- a/1.3/Languages/English/Keyed/RJW_Menstruation.xml
+++ b/1.3/Languages/English/Keyed/RJW_Menstruation.xml
@@ -37,7 +37,7 @@
Gather cum into bucket
Store cum in womb
Unknown
-
+
Enable womb icon
@@ -94,14 +94,12 @@
Dominant hybrid extension
Mother
Father
- Transition variance of nipples after pregnancy
- Set how much nipples/areolas should darken/widen on every pregnancy.
- Permanent transition variance of nipples
- Set how much nipples/areolas should darken/widen permanently on every pregnancy.
- Maximum transition
- Nipples/areolas won't be darker/wider than this value.
- Transition speed of nipples
- Set speed of transition of nipples/areolas.
1 = instant transition
+ Breast growth during pregnancy
+ Change how much a pregnant pawn's breasts will grow when pregnant. Some pawns will grow more than others.
+ Nipple change during pregnancy
+ Change how much a pregnant pawn's nipples will change during pregnancy.
+ Permanent nipple change after pregnancy
+ Adjusts approximately how much of a pregnant pawn's nipples will remain changed after the pregnancy ends.
Customize Hybrids
Open custom hybrid editor.
This will overrides hybrid definitions of XML files.
Allow shrink icon
diff --git a/1.3/MilkModule/Assemblies/MilkModule.dll b/1.3/MilkModule/Assemblies/MilkModule.dll
index 778684a..f032d8c 100644
Binary files a/1.3/MilkModule/Assemblies/MilkModule.dll and b/1.3/MilkModule/Assemblies/MilkModule.dll differ
diff --git a/1.3/SexperienceModule/Assemblies/SexperienceModule.dll b/1.3/SexperienceModule/Assemblies/SexperienceModule.dll
index fa2d04c..308d693 100644
Binary files a/1.3/SexperienceModule/Assemblies/SexperienceModule.dll and b/1.3/SexperienceModule/Assemblies/SexperienceModule.dll differ
diff --git a/1.3/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs b/1.3/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs
index b35b0a6..0a73ead 100644
--- a/1.3/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs
+++ b/1.3/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs
@@ -32,8 +32,7 @@ namespace MilkModule
{
if (breastcomp != null)
{
- breastcomp.AdjustAreolaSize(Rand.Range(0.0f, 0.0001f * Configurations.NipplePermanentTransitionVariance));
- breastcomp.AdjustNippleSize(Rand.Range(0.0f, 0.0001f * Configurations.NipplePermanentTransitionVariance));
+ breastcomp.AdjustNippleProgress(Rand.Range(0.0f, 0.01f));
}
}
diff --git a/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs b/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs
index 2de9e87..ee5ec1d 100644
--- a/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs
+++ b/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs
@@ -24,8 +24,7 @@ namespace MilkModule
if (__instance.parent is Pawn pawn) comp = pawn.GetBreastComp();
if (comp != null)
{
- comp.AdjustAreolaSize(Rand.Range(0.0f, 0.01f * Configurations.NipplePermanentTransitionVariance));
- comp.AdjustNippleSize(Rand.Range(0.0f, 0.01f * Configurations.NipplePermanentTransitionVariance));
+ comp.AdjustNippleProgress(Rand.Range(0.0f, 0.01f));
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs
index 2ef752e..319f64a 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs
@@ -21,10 +21,12 @@ namespace RJW_Menstruation
public const int EnzygoticTwinsChanceAdjustDefault = 2;
public const int MaxEnzygoticTwinsDefault = 9;
public const int BleedingAmountDefault = 50;
- public const float NippleTransitionVarianceDefault = 0.2f;
- public const float NipplePermanentTransitionVarianceDefault = 0.02f;
- public const float NippleMaximumTransitionDefault = 0.4f;
- public const float NippleTransitionSpeedDefault = 0.035f;
+ public const float MaxBreastIncrementFactorDefault = 1.0f;
+ public const float MaxBreastIncrementFactorMax = 2.5f;
+ public const float MaxNippleIncrementFactorDefault = 1.0f;
+ public const float MaxNippleIncrementFactorMax = 2.5f;
+ public const float PermanentNippleChangeDefault = 0.1f;
+ public const float PermanentNippleChangeMax = 0.25f;
public const float EggLifespanMultiplierDefault = 1.0f;
public const float VaginaMorphPowerDefault = 0.2f;
@@ -67,19 +69,9 @@ namespace RJW_Menstruation
public static float EggLifespanMultiplier = EggLifespanMultiplierDefault;
public static bool EnableBirthVaginaMorph = false;
public static float VaginaMorphPower = VaginaMorphPowerDefault;
-
- public static float NippleTransitionVariance = NippleTransitionVarianceDefault;
- public static float NipplePermanentTransitionVariance = NipplePermanentTransitionVarianceDefault;
- public static float NippleMaximumTransition = NippleMaximumTransitionDefault;
- public static float NippleTransitionSpeed = NippleTransitionSpeedDefault;
- public static float NippleTransitionRatio
- {
- get
- {
- return NippleTransitionVariance * NippleTransitionSpeed;
- }
- }
-
+ public static float MaxBreastIncrementFactor = MaxBreastIncrementFactorDefault;
+ public static float MaxNippleIncrementFactor = MaxNippleIncrementFactorDefault;
+ public static float PermanentNippleChange = PermanentNippleChangeDefault;
public static void SettoDefault()
{
ImplantationChanceAdjust = ImplantationChanceAdjustDefault;
@@ -101,10 +93,9 @@ namespace RJW_Menstruation
MaxEnzygoticTwins = MaxEnzygoticTwinsDefault;
BleedingAmount = BleedingAmountDefault;
MotherFirst = false;
- NippleTransitionVariance = NippleTransitionVarianceDefault;
- NipplePermanentTransitionVariance = NipplePermanentTransitionVarianceDefault;
- NippleMaximumTransition = NippleMaximumTransitionDefault;
- NippleTransitionSpeed = NippleTransitionSpeedDefault;
+ MaxBreastIncrementFactor = MaxBreastIncrementFactorDefault;
+ MaxNippleIncrementFactor= MaxNippleIncrementFactorDefault;
+ PermanentNippleChange = PermanentNippleChangeDefault;
EggLifespanMultiplier = EggLifespanMultiplierDefault;
VaginaMorphPower = VaginaMorphPowerDefault;
}
@@ -214,10 +205,9 @@ namespace RJW_Menstruation
Scribe_Values.Look(ref ShowFlag, "ShowFlag", ShowFlag, true);
Scribe_Values.Look(ref UseHybridExtention, "UseHybridExtention", UseHybridExtention, true);
Scribe_Values.Look(ref MotherFirst, "MotherFirst", MotherFirst, true);
- Scribe_Values.Look(ref NippleTransitionVariance, "NippleTransitionVariance", NippleTransitionVariance, true);
- Scribe_Values.Look(ref NipplePermanentTransitionVariance, "NipplePermanentTransitionVariance", NipplePermanentTransitionVariance, true);
- Scribe_Values.Look(ref NippleMaximumTransition, "NippleMaximumTransition", NippleMaximumTransition, true);
- Scribe_Values.Look(ref NippleTransitionSpeed, "NippleTransitionSpeed", NippleTransitionSpeed, true);
+ Scribe_Values.Look(ref MaxBreastIncrementFactor, "MaxBreastIncrementFactor", MaxBreastIncrementFactor, true);
+ Scribe_Values.Look(ref MaxNippleIncrementFactor, "MaxNippleIncrementFactor", MaxNippleIncrementFactor, true);
+ Scribe_Values.Look(ref PermanentNippleChange, "PermanentNippleChange", PermanentNippleChange, true);
Scribe_Values.Look(ref AllowShrinkIcon, "AllowShrinkIcon", AllowShrinkIcon, true);
Scribe_Values.Look(ref EggLifespanMultiplier, "EggLifespanMultiplier", EggLifespanMultiplier, true);
Scribe_Values.Look(ref EnableBirthVaginaMorph, "EnableBirthVaginaMorph", EnableBirthVaginaMorph, true);
@@ -259,8 +249,8 @@ namespace RJW_Menstruation
public RJW_Menstruation(ModContentPack content) : base(content)
{
GetSettings();
- Configurations.HARActivated = ModLister.HasActiveModWithName("Humanoid Alien Races 2.0");
- Configurations.LLActivated = ModLister.HasActiveModWithName("RimJobWorld - Licentia Labs");
+ Configurations.HARActivated = ModLister.GetActiveModWithIdentifier("erdelf.HumanoidAlienRaces") != null;
+ Configurations.LLActivated = ModLister.GetActiveModWithIdentifier("LustLicentia.RJWLabs") != null;
}
@@ -294,7 +284,7 @@ namespace RJW_Menstruation
Widgets.CheckboxLabeled(middleAndRightCells.RightHalf(), Translations.Option_EnableGatherCumGizmo_Label, ref Configurations.EnableGatherCumGizmo, false, null, null, true);
if (Configurations.EnableWombIcon || Configurations.EnableButtonInHT)
{
- Listing_Standard wombsection = listmain.BeginSection(400);
+ Listing_Standard wombsection = listmain.BeginSection(350);
wombsection.CheckboxLabeled(Translations.Option9_Label, ref Configurations.DrawWombStatus, Translations.Option9_Desc);
if (Configurations.DrawWombStatus)
{
@@ -352,25 +342,20 @@ namespace RJW_Menstruation
Configurations.ShowFlag ^= Configurations.PawnFlags.Hostile;
}
- Adjust = (int)(Configurations.NippleTransitionVariance * 1000);
- wombsection.Label(Translations.Option24_Label + " " + Configurations.NippleTransitionVariance * 100 + " / 100", -1, Translations.Option24_Desc);
+ Adjust = (int)(Configurations.MaxBreastIncrementFactor * 1000 / Configurations.MaxBreastIncrementFactorMax);
+ wombsection.Label(Translations.Option_MaxBreastIncrementFactor_Label + " " + Configurations.MaxBreastIncrementFactor * 100 + "%", -1, Translations.Option_MaxBreastIncrementFactor_Desc);
Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
- Configurations.NippleTransitionVariance = (float)Adjust / 1000;
+ Configurations.MaxBreastIncrementFactor = (float)Adjust / (1000 / Configurations.MaxBreastIncrementFactorMax);
- Adjust = (int)(Configurations.NipplePermanentTransitionVariance * 1000);
- wombsection.Label(Translations.Option25_Label + " " + Configurations.NipplePermanentTransitionVariance * 100 + " / 100", -1, Translations.Option25_Desc);
+ Adjust = (int)(Configurations.MaxNippleIncrementFactor * 1000 / Configurations.MaxNippleIncrementFactorMax);
+ wombsection.Label(Translations.Option_MaxNippleIncrementFactor_Label + " " + Configurations.MaxNippleIncrementFactor * 100 + "%", -1, Translations.Option_MaxNippleIncrementFactor_Desc);
Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
- Configurations.NipplePermanentTransitionVariance = (float)Adjust / 1000;
+ Configurations.MaxNippleIncrementFactor = (float)Adjust / (1000 / Configurations.MaxNippleIncrementFactorMax);
- Adjust = (int)(Configurations.NippleMaximumTransition * 1000);
- wombsection.Label(Translations.Option26_Label + " " + Configurations.NippleMaximumTransition * 100 + " / 100", -1, Translations.Option26_Desc);
+ Adjust = (int)(Configurations.PermanentNippleChange * 1000 / Configurations.PermanentNippleChangeMax);
+ wombsection.Label(Translations.Option_PermanentNippleChange_Label + " " + Configurations.PermanentNippleChange, -1, Translations.Option_PermanentNippleChange_Desc);
Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
- Configurations.NippleMaximumTransition = (float)Adjust / 1000;
-
- Adjust = (int)(Configurations.NippleTransitionSpeed * 1000);
- wombsection.Label(Translations.Option27_Label + " " + Configurations.NippleTransitionSpeed, -1, Translations.Option27_Desc);
- Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
- Configurations.NippleTransitionSpeed = (float)Adjust / 1000;
+ Configurations.PermanentNippleChange = (float)Adjust / (1000 / Configurations.PermanentNippleChangeMax);
listmain.EndSection(wombsection);
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs
index 44f787d..3a8fdb5 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs
@@ -11,7 +11,7 @@ namespace RJW_Menstruation
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Follicular;
- Messages.Message($"{p} is now follicular", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"{p} is now follicular", p, MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Set pawn's state to ovulatory", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
@@ -19,7 +19,7 @@ namespace RJW_Menstruation
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
- Messages.Message($"{p} is now ovulatory", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"{p} is now ovulatory", p, MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Set pawn's state to luteal", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
@@ -27,7 +27,7 @@ namespace RJW_Menstruation
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Luteal;
- Messages.Message($"{p} is now luteal", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"{p} is now luteal", p, MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Set pawn's state to bleeding", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
@@ -35,7 +35,7 @@ namespace RJW_Menstruation
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Bleeding;
- Messages.Message($"{p} is now bleeding", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"{p} is now bleeding", p, MessageTypeDefOf.NeutralEvent, false);
}
/*
[DebugAction("RJW Menstruation", "Set pawn's state to recovering", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
@@ -55,14 +55,14 @@ namespace RJW_Menstruation
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.RemoveAllCums();
- Messages.Message($"All cum removed from {p}'s womb", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"All cum removed from {p}'s womb", p, MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Add egg to pawn's next ovulation", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void AddEgg(Pawn p)
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.eggstack++;
- Messages.Message($"1 egg added to {p}'s next ovulation ({p.GetFirstMenstruationComp().eggstack})", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"1 egg added to {p}'s next ovulation ({p.GetFirstMenstruationComp().eggstack})", p, MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Recalculate pawn's ovary power", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
@@ -70,7 +70,7 @@ namespace RJW_Menstruation
{
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.ovarypower = comp.GetOvaryPowerByAge();
- Messages.Message($"{p}'s ovarypower recalculated ({p.GetFirstMenstruationComp().ovarypower})", MessageTypeDefOf.NeutralEvent, false);
+ Messages.Message($"{p}'s ovarypower recalculated ({p.GetFirstMenstruationComp().ovarypower})", p, MessageTypeDefOf.NeutralEvent, false);
}
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/HARCompatibility.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/HARCompatibility.cs
index c274d8d..863eaa4 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/HARCompatibility.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/HARCompatibility.cs
@@ -1,4 +1,6 @@
-using System.Linq;
+using AlienRace;
+using System.Collections.Generic;
+using UnityEngine;
using Verse;
namespace RJW_Menstruation
@@ -8,24 +10,38 @@ namespace RJW_Menstruation
public static bool IsHAR(this Pawn pawn)
{
- return pawn.def.GetType().ToString().StartsWith("AlienRace");
+ if (!Configurations.HARActivated) return false;
+ return pawn?.def is ThingDef_AlienRace;
}
- public static ThingComp GetHARComp(this Pawn pawn)
+ public static AlienPartGenerator.AlienComp GetHARComp(this Pawn pawn)
{
- return pawn?.GetComps()?.First(x => x.GetType().Namespace.EqualsIgnoreCase("AlienRace") && x.GetType().Name.EndsWith("AlienComp"));
+ return pawn?.TryGetComp();
}
- public static string GetHARCrown(this Pawn pawn)
+ public static void CopyHARProperties(Pawn baby, Pawn original)
{
- return (string)pawn.GetHARComp().GetMemberValue("crownType");
+ AlienPartGenerator.AlienComp babyHARComp = baby.GetHARComp();
+ AlienPartGenerator.AlienComp originalHARComp = original.GetHARComp();
+ if (babyHARComp == null || originalHARComp == null) return;
+ babyHARComp.crownType = originalHARComp.crownType;
+
+ foreach(KeyValuePair> channel in originalHARComp.ColorChannels)
+ {
+ babyHARComp.OverwriteColorChannel(channel.Key, channel.Value.first, channel.Value.second);
+ }
+ babyHARComp.headMaskVariant = originalHARComp.headMaskVariant;
+ babyHARComp.bodyMaskVariant = originalHARComp.bodyMaskVariant;
}
- public static void SetHARCrown(this Pawn pawn, string crown)
+ // HAR doesn't populate variants until the graphics are called for, so this has to happen late
+ public static void CopyHARPropertiesPostBirth(Pawn baby, Pawn original)
{
- pawn.GetHARComp().SetMemberValue("crownType", crown);
+ AlienPartGenerator.AlienComp babyHARComp = baby.GetHARComp();
+ AlienPartGenerator.AlienComp originalHARComp = original.GetHARComp();
+ if (babyHARComp == null || originalHARComp == null) return;
+ if (originalHARComp.addonVariants != null) // Testing has shown that the addons are valid by this point, but it's better to be safe
+ babyHARComp.addonVariants = new List(originalHARComp.addonVariants);
}
-
-
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs
index 4a38f7a..a275479 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs
@@ -1,8 +1,8 @@
-using HugsLib;
-using RimWorld;
+using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
+using System.Linq;
using UnityEngine;
using Verse;
@@ -10,6 +10,7 @@ namespace RJW_Menstruation
{
public class CompProperties_Breast : HediffCompProperties
{
+ public static readonly ColorInt DefaultBlacknippleColor = new ColorInt(55, 20, 0);
public string BreastTex = "Breasts/Breast";
public ColorInt BlacknippleColor = new ColorInt(55, 20, 0);
@@ -31,117 +32,98 @@ namespace RJW_Menstruation
public class HediffComp_Breast : HediffComp
{
- public const float DEFAULTALPHA = -1;
- public const float DEFAULTAREOLA = -1;
- public const float DEFAULTNIPPLE = -1;
- public const float VARIANT = 0.2f;
- public const int TICKINTERVAL = 3750;
- public const float MAX_BREAST_INCREMENT = 0.10f;
- public const float BREAST_GROWTH_START = 1f / 6f;
- public const float BREAST_GROWTH_END = 1f / 3f;
+ public const int tickInterval = GenDate.TicksPerHour * 3 / 2;
+ public const float breastGrowthStart = 1f / 6f;
+ public const float breastGrowthEnd = 1f / 3f;
+ public static readonly SimpleCurve nippleTransitions = new SimpleCurve()
+ {
+ new CurvePoint(0f,0f),
+ new CurvePoint(0.1f,0f),
+ new CurvePoint(0.333f,0.167f),
+ new CurvePoint(0.667f,0.833f),
+ new CurvePoint(1.0f,1.0f)
+ };
+ public const float nippleChange = 0.2f;
public CompProperties_Breast Props;
- protected float alphaPermanent = -1;
- protected float alphaCurrent = -1;
- protected float alpha = -1;
- protected float areolaSizePermanent = -1f;
- protected float areolaSizeCurrent = -1f;
- protected float areolaSize = -1f;
- protected float nippleSizePermanent = -1f;
- protected float nippleSizeCurrent = -1f;
- protected float nippleSize = -1f;
protected long ageOfLastBirth = 0;
+ protected float maxBreastIncrement = -1f;
protected float breastSizeIncreased = 0f;
protected string debugGrowthStatus = "(Growth/shrink not yet calculated; run for 1.5h to update)";
- protected float originalpha = -1f;
- protected float originareola = -1f;
- protected float originnipple = -1f;
- protected Color cachedcolor;
- protected bool loaded = false;
- protected bool pregnant = false;
- public Action action;
+ protected float nippleProgress = 0f;
+ protected float baseAlpha = -1f; // Will grow in response to pregnancy
+ protected float baseAreola = -1f;
+ protected float baseNipple = -1f;
+ protected float cachedAlpha = -1f; // Calculated dynamically instead of saved
+ protected float cachedAreola = -1f; // Actual size = these * breast size
+ protected float cachedNipple = -1f;
+ protected float babyHalfAge = -1f;
+ protected Color cachedColor;
+ protected bool loaded = false;
+
protected float BabyHalfAge
{
get
{
- float res = 0;
- List ages = parent.pawn.RaceProps.lifeStageAges;
+ if (babyHalfAge > 0f) return babyHalfAge;
+ List ages = parent.pawn.def.race.lifeStageAges;
if (ages?.Count > 1)
- res = ages[1].minAge / 2;
+ babyHalfAge = ages[1].minAge / 2;
- if (res <= 0) res = 1.2f / 2; // Default to human
+ if (babyHalfAge <= 0) babyHalfAge = 1.2f / 2; // Default to human
if (RJWPregnancySettings.phantasy_pregnancy)
- res /= GenDate.DaysPerYear;
+ babyHalfAge /= GenDate.DaysPerYear;
- return res;
+ return babyHalfAge;
}
}
protected void ShrinkBreasts()
{
// The natural rate will take them from full to empty during the second half of their child's babyhood
- float shrinkRate = TICKINTERVAL * MAX_BREAST_INCREMENT / (BabyHalfAge * GenDate.TicksPerYear);
+ float shrinkRate = tickInterval * MaxBreastIncrement / (BabyHalfAge * GenDate.TicksPerYear);
float shrinkAmount = Mathf.Min(shrinkRate, breastSizeIncreased);
breastSizeIncreased -= shrinkAmount;
parent.Severity -= shrinkAmount;
}
- public float MaxAlpha
+ protected float MaxBreastIncrement
{
get
{
- return originalpha + Configurations.NippleMaximumTransition;
+ return maxBreastIncrement * Configurations.MaxBreastIncrementFactor;
}
}
- public float MaxAreola
- {
- get
- {
- return originareola + Configurations.NippleMaximumTransition;
- }
- }
- public float MaxNipple
- {
- get
- {
- return originnipple + Configurations.NippleMaximumTransition;
- }
- }
-
- public float OriginAlpha => originalpha;
- public float OriginNipple => originnipple;
- public float OriginAreola => originareola;
- public Color OriginColor => Colors.CMYKLerp(parent?.pawn?.story?.SkinColor ?? Color.white, Props.BlackNippleColor, originalpha);
public Color NippleColor
{
get
{
- return cachedcolor;
+ return cachedColor;
}
}
public float Alpha
{
get
{
- return alphaCurrent;
+ return cachedAlpha;
}
}
public float NippleSize
{
get
{
- return nippleSizeCurrent;
+ return cachedNipple * parent.Severity;
}
}
public float AreolaSize
{
get
{
- return areolaSizeCurrent;
+ return cachedAreola * parent.Severity;
}
}
@@ -156,25 +138,50 @@ namespace RJW_Menstruation
public override void CompExposeData()
{
base.CompExposeData();
- Scribe_Values.Look(ref alphaPermanent, "alphaPermanent", DEFAULTALPHA, true);
- Scribe_Values.Look(ref alphaCurrent, "alphaCurrent", DEFAULTALPHA, true);
- Scribe_Values.Look(ref alpha, "alpha", DEFAULTALPHA, true);
- Scribe_Values.Look(ref areolaSizePermanent, "areolaSizePermanent", DEFAULTAREOLA, true);
- Scribe_Values.Look(ref areolaSizeCurrent, "areolaSizeCurrent", DEFAULTAREOLA, true);
- Scribe_Values.Look(ref areolaSize, "areolaSize", DEFAULTAREOLA, true);
- Scribe_Values.Look(ref nippleSizePermanent, "nippleSizePermanent", DEFAULTNIPPLE, true);
- Scribe_Values.Look(ref nippleSizeCurrent, "nippleSizeCurrent", DEFAULTNIPPLE, true);
- Scribe_Values.Look(ref nippleSize, "nippleSize", DEFAULTNIPPLE, true);
- Scribe_Values.Look(ref ageOfLastBirth, "ageOfLastBirth", ageOfLastBirth, true);
- Scribe_Values.Look(ref breastSizeIncreased, "breastSizeIncreased", breastSizeIncreased, true);
- Scribe_Values.Look(ref originalpha, "originalpha", originalpha, true);
- Scribe_Values.Look(ref originareola, "originareola", originareola, true);
- Scribe_Values.Look(ref originnipple, "originnipple", originnipple, true);
- Scribe_Values.Look(ref pregnant, "pregnant", pregnant, true);
+
+ if (Scribe.mode == LoadSaveMode.LoadingVars)
+ { // For compatibility
+ Scribe_Values.Look(ref baseAlpha, "alphaPermanent", baseAlpha / 2, false);
+ Scribe_Values.Look(ref baseAreola, "areolaSizePermanent", baseAreola / 2, false);
+ Scribe_Values.Look(ref baseNipple, "nippleSizePermanent", baseNipple / 2, false);
+ baseAlpha *= 2;
+ baseAreola *= 2;
+ baseNipple *= 2;
+ }
+ Scribe_Values.Look(ref ageOfLastBirth, "ageOfLastBirth", ageOfLastBirth, true);
+ Scribe_Values.Look(ref maxBreastIncrement, "maxBreastIncrement", maxBreastIncrement, true);
+ Scribe_Values.Look(ref breastSizeIncreased, "breastSizeIncreased", breastSizeIncreased, true);
+ Scribe_Values.Look(ref nippleProgress, "nippleProgress", nippleProgress, true);
+ Scribe_Values.Look(ref baseAlpha, "baseAlpha", baseAlpha, true);
+ Scribe_Values.Look(ref baseAreola, "baseAreola", baseAreola, true);
+ Scribe_Values.Look(ref baseNipple, "baseNipple", baseNipple, true);
}
- public override void CompPostTick(ref float severityAdjustment) { }
+ public override void CompPostTick(ref float severityAdjustment)
+ {
+ base.CompPostTick(ref severityAdjustment);
+ // If an exception makes it out, RW will remove the hediff, so catch it here
+ try
+ {
+ if (
+ !parent.pawn.IsHashIntervalTick(tickInterval) ||
+ !parent.pawn.Spawned || // TODO: Add option to simulate off-map pawns
+ parent.pawn.health.Dead
+ )
+ {
+ return;
+ }
+ CalculateBreastSize();
+ CalculateNipples();
+ UpdateNipples();
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error processing breasts of {parent.pawn}: {ex}");
+ }
+
+ }
public override void CompPostPostAdd(DamageInfo? dinfo)
{
@@ -189,8 +196,6 @@ namespace RJW_Menstruation
Log.Warning($"Attempted to remove breast comp from wrong pawn ({parent.pawn}).");
return;
}
- HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(action);
- if (Configurations.Debug) Log.Message(parent.pawn.Label + " breast tick scheduler removed");
base.CompPostPostRemoved();
}
@@ -202,15 +207,12 @@ namespace RJW_Menstruation
foreach (Pawn child in parent.pawn.relations.Children)
{
bool isFetus = false;
- foreach (Hediff_BasePregnancy preg in parent.pawn.health.hediffSet.GetHediffs())
+ if (parent.pawn.health.hediffSet.GetHediffs().Any(preg => preg.babies.Contains(child)))
{
- if (preg.babies.Contains(child))
- {
- isFetus = true;
- break;
- }
+ isFetus = true;
+ break;
}
-
+
if (
parent.pawn.ageTracker.BirthAbsTicks - child.ageTracker.BirthAbsTicks > ageOfLastBirth &&
!isFetus &&
@@ -225,70 +227,54 @@ namespace RJW_Menstruation
public void Initialize()
{
Props = (CompProperties_Breast)props;
- action = Transition;
+ if (maxBreastIncrement <= 0f)
+ {
+ maxBreastIncrement = Utility.RandGaussianLike(0.088f, 0.202f);
+ }
if (ageOfLastBirth == 0)
{
ageOfLastBirth = CalculateLastBirth();
}
-
- if (alphaPermanent < 0f)
+ if (baseAlpha <= 0f)
{
- alphaPermanent = (Utility.RandGaussianLike(0.0f, 0.3f) + Rand.Range(0.0f, 0.5f)) / 2;
- originalpha = alphaPermanent;
- alpha = alphaPermanent;
- alphaCurrent = alphaPermanent;
+ baseAlpha = Utility.RandGaussianLike(0.0f, 0.3f) + Rand.Range(0.0f, 0.5f);
}
- if (areolaSizePermanent < 0f)
+ if (baseAreola <= 0f)
{
- areolaSizePermanent = Utility.RandGaussianLike(0f, parent.Severity);
- originareola = areolaSizePermanent;
- areolaSize = areolaSizePermanent;
- areolaSizeCurrent = areolaSizePermanent;
+ baseAreola = Utility.RandGaussianLike(0.0f, 1.0f);
}
- if (nippleSizePermanent < 0f)
+ if (baseNipple <= 0f)
{
- nippleSizePermanent = Utility.RandGaussianLike(0f, parent.Severity);
- originnipple = nippleSizePermanent;
- nippleSize = nippleSizePermanent;
- nippleSizeCurrent = nippleSizePermanent;
+ baseNipple = Utility.RandGaussianLike(0.0f, 1.0f);
}
- UpdateColor();
+ UpdateNipples();
loaded = true;
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(action, TICKINTERVAL, parent.pawn);
}
-
-
- public void Transition()
+ protected void CalculateBreastSize()
{
- alphaCurrent = Mathf.Lerp(alphaCurrent, alpha, Configurations.NippleTransitionRatio);
- areolaSizeCurrent = Mathf.Lerp(areolaSizeCurrent, areolaSize, Configurations.NippleTransitionRatio);
- nippleSizeCurrent = Mathf.Lerp(nippleSizeCurrent, nippleSize, Configurations.NippleTransitionRatio);
- UpdateColor();
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(action, TICKINTERVAL, parent.pawn);
-
// Scenario A: the youngest child is less than halfway into babyhood: Full size
if (ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > parent.pawn.ageTracker.AgeBiologicalTicks)
{
debugGrowthStatus = "Full size due to young child";
- if (breastSizeIncreased < MAX_BREAST_INCREMENT)
+ if (breastSizeIncreased < MaxBreastIncrement)
{
- parent.Severity += (MAX_BREAST_INCREMENT - breastSizeIncreased);
- breastSizeIncreased = MAX_BREAST_INCREMENT;
+ parent.Severity += (MaxBreastIncrement - breastSizeIncreased);
+ breastSizeIncreased = MaxBreastIncrement;
}
}
// Scenario B: Pregnant, grow in the second half of first trimester
else if (parent.pawn.IsPregnant())
{
- float pregnancySize = Mathf.InverseLerp(BREAST_GROWTH_START, BREAST_GROWTH_END, parent.pawn.GetFarthestPregnancyProgress()) * MAX_BREAST_INCREMENT;
+ float pregnancySize = Mathf.InverseLerp(breastGrowthStart, breastGrowthEnd, parent.pawn.GetFarthestPregnancyProgress()) * MaxBreastIncrement;
if (breastSizeIncreased > pregnancySize)
{
debugGrowthStatus = "Shrinking due to being oversize for pregnancy";
// Breasts still large from the last kid
ShrinkBreasts();
}
- else if (breastSizeIncreased < MAX_BREAST_INCREMENT)
+ else if (breastSizeIncreased < MaxBreastIncrement)
{
// Time to grow
float growAmount = pregnancySize - breastSizeIncreased;
@@ -310,106 +296,88 @@ namespace RJW_Menstruation
else debugGrowthStatus = "Base size";
}
- public void ChangeColorFermanant(float alpha)
+ protected void CalculateNipples()
{
- alphaPermanent = alpha;
+ float newNippleProgress;
+ if (ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > parent.pawn.ageTracker.AgeBiologicalTicks)
+ newNippleProgress = 1f;
+ else if (parent.pawn.IsPregnant())
+ newNippleProgress = nippleTransitions.Evaluate(parent.pawn.GetFarthestPregnancyProgress());
+ else
+ newNippleProgress = 0f;
+
+ if (newNippleProgress == nippleProgress) return; // Nothing to change
+ else if (newNippleProgress > nippleProgress)
+ {
+ float progressDifference = newNippleProgress - nippleProgress;
+ // All nipple growth has a slight effect on the base
+ // Not mathematically precise in hitting the goal at the end of the term, but close enough
+ baseAlpha *= 1.0f + progressDifference * Configurations.PermanentNippleChange;
+ if (baseAlpha > 1.0f) baseAlpha = 1.0f;
+ baseAreola *= 1.0f + progressDifference * Configurations.PermanentNippleChange;
+ if (baseAreola > 1.0f) baseAreola = 1.0f;
+ baseNipple *= 1.0f + progressDifference * Configurations.PermanentNippleChange;
+ if (baseNipple > 1.0f) baseNipple = 1.0f;
+ nippleProgress = newNippleProgress;
+ }
+ else
+ {
+ nippleProgress -= tickInterval / (BabyHalfAge * GenDate.TicksPerYear);
+ if (nippleProgress < newNippleProgress) nippleProgress = newNippleProgress;
+ }
}
- public void ChangeColor(float alpha)
+ public void AdjustNippleProgress(float amount)
{
- this.alpha = alpha;
+ nippleProgress = Mathf.Clamp01(nippleProgress + amount);
+ UpdateNipples();
}
- public void PregnancyTransition()
+ public void AdjustNippleSizeImmediately(float amount)
{
- alphaPermanent = Math.Min(MaxAlpha, alphaPermanent + Configurations.NipplePermanentTransitionVariance.VariationRange(VARIANT));
- areolaSizePermanent = Math.Min(MaxAreola, areolaSizePermanent + Configurations.NipplePermanentTransitionVariance.VariationRange(VARIANT));
- nippleSizePermanent = Math.Min(MaxNipple, nippleSizePermanent + Configurations.NipplePermanentTransitionVariance.VariationRange(VARIANT));
- alpha = Math.Min(MaxAlpha, alpha + Configurations.NippleTransitionVariance.VariationRange(VARIANT));
- areolaSize = Math.Min(MaxAreola, areolaSize + Configurations.NippleTransitionVariance.VariationRange(VARIANT));
- nippleSize = Math.Min(MaxNipple, nippleSize + Configurations.NippleTransitionVariance.VariationRange(VARIANT));
- pregnant = true;
+ baseNipple = Mathf.Clamp01(baseNipple + amount);
+ UpdateNipples();
}
- public void BirthTransition()
+ public void AdjustAreolaSizeImmediately(float amount)
{
- alpha = alphaPermanent;
- areolaSize = areolaSizePermanent;
- nippleSize = nippleSizePermanent;
- pregnant = false;
- ageOfLastBirth = parent.pawn.ageTracker.AgeBiologicalTicks;
+ baseAreola = Mathf.Clamp01(baseAreola + amount);
+ UpdateNipples();
}
-
- public void AdjustBreastSize(float amount)
+ public void UpdateNipples()
{
- parent.Severity += amount;
- breastSizeIncreased += amount;
+ cachedAlpha = baseAlpha + nippleProgress * nippleChange;
+ cachedAreola = baseAreola + nippleProgress * nippleChange;
+ cachedNipple = baseNipple + nippleProgress * nippleChange;
+
+ // For some reason, Props can go null when RJW relocates the chest (e.g. some animals), so catch that
+ cachedColor = Colors.CMYKLerp(parent.pawn.story?.SkinColor ?? Color.white, (Props?.BlackNippleColor ?? CompProperties_Breast.DefaultBlacknippleColor.ToColor), Alpha);
}
- public void AdjustNippleSize(float amount)
+ public void CopyBreastProperties(HediffComp_Breast original)
{
- nippleSizePermanent = Math.Min(MaxNipple, nippleSizePermanent + amount);
- nippleSize = Math.Min(MaxNipple, nippleSize + amount);
- }
-
- public void AdjustAreolaSize(float amount)
- {
- areolaSizePermanent = Math.Min(MaxAreola, areolaSizePermanent + amount);
- areolaSize = Math.Min(MaxAreola, areolaSize + amount);
- }
-
- public void RestoreBreastSize(float ratio)
- {
- float variance = breastSizeIncreased * Math.Min(ratio, 1.0f);
- breastSizeIncreased -= variance;
- parent.Severity -= variance;
- }
-
- public void AdjustNippleSizeImmidiately(float amount)
- {
- originnipple = Math.Max(0, originnipple + amount);
- nippleSizePermanent = Math.Min(MaxNipple, nippleSizePermanent + amount);
- nippleSize = Math.Min(MaxNipple, nippleSize + amount);
- nippleSizeCurrent = nippleSize;
- }
-
- public void AdjustAreolaSizeImmidiately(float amount)
- {
- originareola = Math.Max(0, originareola + amount);
- areolaSizePermanent = Math.Min(MaxAreola, areolaSizePermanent + amount);
- areolaSize = Math.Min(MaxAreola, areolaSize + amount);
- areolaSizeCurrent = areolaSize;
- }
-
-
-
- public void UpdateColor()
- {
- cachedcolor = Colors.CMYKLerp(parent?.pawn?.story?.SkinColor ?? Color.white, Props.BlackNippleColor, Alpha);
+ maxBreastIncrement = original.maxBreastIncrement;
+ baseAlpha = original.baseAlpha;
+ baseAreola = original.baseAreola;
+ baseNipple = original.baseNipple;
+ UpdateNipples();
}
public string DebugInfo()
{
- return "Increase: " + breastSizeIncreased +
+ return "Size: " + parent.Severity +
+ "\nIncrease: " + breastSizeIncreased +
"\n" + debugGrowthStatus +
- "\nAlpha: " + alpha +
- "\nNippleSize: " + nippleSize +
- "\nAreolaSize: " + areolaSize +
- "\nAlphaCurrent: " + alphaCurrent +
- "\nNippleSizeCurrent: " + nippleSizeCurrent +
- "\nAreolaSizeCurrent: " + areolaSizeCurrent +
- "\nAlphaOrigin: " + originalpha +
- "\nNippleSizeOrigin: " + originnipple +
- "\nAreolaSizeOrigin: " + originareola +
- "\nAlphaMax: " + MaxAlpha +
- "\nNippleSizeMax: " + MaxNipple +
- "\nAreolaSizeMax: " + MaxAreola +
- "\nPermanentAlpha:" + alphaPermanent +
- "\nPermanentNipple:" + nippleSizePermanent +
- "\nPermanentAreola:" + areolaSizePermanent;
+ "\nNipple progress: " + nippleProgress +
+ "\nBase alpha: " + baseAlpha +
+ "\nAlpha: " + cachedAlpha +
+ "\nBase areola: " + baseAreola +
+ "\nAreola: " + cachedAreola +
+ "\nDisplayed areola: " + AreolaSize +
+ "\nBase nipple: " + baseNipple +
+ "\nNipple: " + cachedNipple +
+ "\nDisplayed nipple: " + NippleSize;
}
-
}
-
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs
index a4e75af..fc07cb6 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs
@@ -1,5 +1,4 @@
-using HugsLib;
-using RimWorld;
+using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
@@ -70,7 +69,6 @@ namespace RJW_Menstruation
public CompProperties_Menstruation Props;
public Stage curStage = Stage.Follicular;
public int curStageHrs = 0;
- public Action actionref;
public bool loaded = false;
public int ovarypower = -100000;
public int eggstack = 0;
@@ -139,7 +137,22 @@ namespace RJW_Menstruation
{
get
{
- if (opcache < 0) opcache = (int)(72f * parent.pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy);
+ if (opcache >= 0) return opcache;
+ // Climacteric will set in 6 (human) years before egg exhaustion
+ float avglittersize;
+ try
+ {
+ avglittersize = Mathf.Max(Rand.ByCurveAverage(parent.pawn.def.race.litterSizeCurve), 1.0f);
+ }
+ catch
+ {
+ // Any exceptions in that will have been reported elsewhere in the code by now
+ avglittersize = 1.0f;
+ };
+ opcache = (int)(RaceCyclesPerYear() *
+ avglittersize *
+ 6f *
+ (parent.pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy));
return opcache;
}
}
@@ -487,7 +500,17 @@ namespace RJW_Menstruation
{
get
{
- return Mathf.Clamp01(curStageHrs / CurStageIntervalHours);
+ if (pregnancy == null) return Mathf.Clamp01(curStageHrs / CurStageIntervalHours);
+ if (pregnancy.is_discovered || Configurations.infoDetail == Configurations.DetailLevel.All) return pregnancy.Severity;
+
+ // Luteal will appear to progress, hitting the end of the phase when the pregnancy is discovered
+ float discoveryTime = 0.5f;
+ if (parent.pawn.story?.bodyType == BodyTypeDefOf.Thin) discoveryTime = 0.25f;
+ else if (parent.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
+ float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * 24));
+
+ return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity);
}
}
@@ -530,11 +553,69 @@ namespace RJW_Menstruation
public override void CompPostTick(ref float severityAdjustment)
{
- //initializer moved to SpawnSetup
- //if (!loaded)
- //{
- // Initialize();
- //}
+ base.CompPostTick(ref severityAdjustment);
+ // If an exception makes it out, RW will remove the hediff, so catch it here
+ try
+ {
+ if (
+ !parent.pawn.IsHashIntervalTick(tickInterval) ||
+ !parent.pawn.Spawned || // TODO: Add option to simulate off-map pawns
+ parent.pawn.health.Dead ||
+ (parent.pawn.IsAnimal() && !Configurations.EnableAnimalCycle)
+ )
+ {
+ return;
+ }
+
+ CumOut();
+ if (pregnancy == null && parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) curStage = Stage.Young;
+ switch (curStage)
+ {
+ case Stage.Follicular:
+ FollicularAction(false);
+ break;
+ case Stage.Ovulatory:
+ OvulatoryAction();
+ break;
+ case Stage.Luteal:
+ LutealAction(false);
+ break;
+ case Stage.Bleeding:
+ BleedingAction(false);
+ break;
+ case Stage.Pregnant:
+ PregnantAction();
+ break;
+ case Stage.Recover:
+ RecoverAction();
+ break;
+ case Stage.None:
+ break;
+ case Stage.Young:
+ YoungAction();
+ break;
+ case Stage.ClimactericFollicular:
+ FollicularAction(true);
+ break;
+ case Stage.ClimactericLuteal:
+ LutealAction(true);
+ break;
+ case Stage.ClimactericBleeding:
+ BleedingAction(true);
+ break;
+ case Stage.Anestrus:
+ AnestrusAction();
+ break;
+ default:
+ GoNextStage(Stage.Follicular);
+ break;
+ }
+ AfterSimulator();
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error processing womb of {parent.pawn}: {ex}");
+ }
}
public override void CompPostPostRemoved()
@@ -546,8 +627,6 @@ namespace RJW_Menstruation
Log.Warning($"Attempted to remove menstruation comp from wrong pawn ({parent.pawn}).");
return;
}
- HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(actionref);
- if (Configurations.Debug) Log.Message(parent.pawn.Label + " menstruation tick scheduler removed");
pregnancy?.Miscarry();
base.CompPostPostRemoved();
}
@@ -871,7 +950,6 @@ namespace RJW_Menstruation
{
if (cums == null) cums = new List();
curStage = Stage.None;
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), GetNextUpdate(), parent.pawn, false);
loaded = true;
return;
}
@@ -912,18 +990,6 @@ namespace RJW_Menstruation
}
}
- if (parent.pawn.IsAnimal())
- {
- if (Configurations.EnableAnimalCycle)
- {
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), GetNextUpdate(), parent.pawn, false);
- }
- }
- else
- {
- if (pregnancy == null && parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(Stage.Young), GetNextUpdate(), parent.pawn, false);
- else HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), GetNextUpdate(), parent.pawn, false);
- }
//Log.Message(parent.pawn.Label + " - Initialized menstruation comp");
loaded = true;
}
@@ -995,7 +1061,7 @@ namespace RJW_Menstruation
else if (ovarypower < OvaryPowerThreshold)
{
Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn);
- hediff.Severity = 0.008f * (OvaryPowerThreshold - ovarypower);
+ hediff.Severity = Mathf.InverseLerp(OvaryPowerThreshold, 0, ovarypower);
parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
}
}
@@ -1146,14 +1212,12 @@ namespace RJW_Menstruation
PregnancyHelper.PregnancyDecider(parent.pawn, egg.fertilizer);
// I hate having to do this, but it gets the newest pregnancy
pregnancy = parent.pawn.health.hediffSet.GetHediffs().MaxBy(hediff => hediff.loadID);
- currentIntervalHours = (int)pregnancy?.GestationHours();
pregnant = true;
break;
}
else
{
pregnancy = Hediff_BasePregnancy.Create(parent.pawn, egg.fertilizer);
- currentIntervalHours = (int)pregnancy?.GestationHours();
pregnant = true;
deadeggs.Add(egg);
}
@@ -1317,7 +1381,7 @@ namespace RJW_Menstruation
float eggnum;
try
{
- eggnum = Rand.ByCurve(parent.pawn.RaceProps.litterSizeCurve);
+ eggnum = Rand.ByCurve(parent.pawn.def.race.litterSizeCurve);
}
catch (NullReferenceException)
{
@@ -1325,7 +1389,7 @@ namespace RJW_Menstruation
}
catch (ArgumentException e)
{
- Log.Warning($"Invalid litterSizeCurve for {parent.pawn.RaceProps}: {e}");
+ Log.Warning($"Invalid litterSizeCurve for {parent.pawn.def}: {e}");
eggnum = 1;
}
eggnum += eggstack;
@@ -1351,7 +1415,7 @@ namespace RJW_Menstruation
else if (Configurations.EnableMenopause && ovarypower < OvaryPowerThreshold)
{
Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn);
- hediff.Severity = 0.008f * i;
+ hediff.Severity = Mathf.InverseLerp(OvaryPowerThreshold, 0, ovarypower);
parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
GoNextStage(Stage.ClimactericLuteal);
}
@@ -1394,10 +1458,6 @@ namespace RJW_Menstruation
EggDecay();
if (Implant())
{
- if (Breast != null)
- {
- Breast.PregnancyTransition();
- }
GoNextStage(Stage.Pregnant);
}
else
@@ -1459,10 +1519,6 @@ namespace RJW_Menstruation
else
{
if (pregnancy != null) pregnancy = null;
- if (Breast != null)
- {
- Breast.BirthTransition();
- }
GoNextStage(Stage.Recover);
}
}
@@ -1584,108 +1640,12 @@ namespace RJW_Menstruation
TaleRecorder.RecordTale(VariousDefOf.TaleCameInside, new object[] { cummer, parent.pawn });
}
- private Action PeriodSimulator(Stage targetstage)
- {
- Action action = null;
- switch (targetstage)
- {
- case Stage.Follicular:
- action = delegate
- {
- FollicularAction(false);
- };
- break;
- case Stage.Ovulatory:
- action = OvulatoryAction;
- break;
- case Stage.Luteal:
- action = delegate
- {
- LutealAction(false);
- };
- break;
- case Stage.Bleeding:
- action = delegate
- {
- BleedingAction(false);
- };
- break;
- case Stage.Pregnant:
- action = PregnantAction;
- break;
- case Stage.Recover:
- action = RecoverAction;
- break;
- case Stage.None:
- action = delegate
- {
- StayCurrentStageConst(Stage.None);
- };
- break;
- case Stage.Young:
- action = YoungAction;
- break;
- case Stage.ClimactericFollicular:
- action = delegate
- {
- FollicularAction(true);
- };
- break;
- case Stage.ClimactericLuteal:
- action = delegate
- {
- LutealAction(true);
- };
- break;
- case Stage.ClimactericBleeding:
- action = delegate
- {
- BleedingAction(true);
- };
- break;
- case Stage.Anestrus:
- action = AnestrusAction;
- break;
- default:
- curStage = Stage.Follicular;
- curStageHrs = 0;
- if (currentIntervalHours < 0) currentIntervalHours = PeriodRandomizer(curStage);
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(Stage.Follicular), GetNextUpdate(), parent.pawn, false);
- break;
- }
- action += delegate
- {
- if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) curStage = Stage.Young;
- //CumOut();
- AfterSimulator();
- };
- action = CumOut + action;
-
- actionref = action;
- return actionref;
-
-
-
-
- }
-
- protected int GetNextUpdate()
- {
- // Ticks past the hour. Will be equal except for game start or load
- int currentOffset = Find.TickManager.TicksGame % tickInterval;
- int nextOffset = (parent.pawn.HashOffset() % tickInterval + tickInterval) % tickInterval; // Messy, but HashOffset is negative a lot
-
- // The -1/+1 to ensure that equality works out to 1 hour and not 0 ticks
- return ((nextOffset - currentOffset + tickInterval - 1) % tickInterval) + 1;
- }
-
protected void GoNextStage(Stage nextstage, bool calculateHours = true)
{
curStageHrs = 0;
float variabilityFactor = nextstage == Stage.ClimactericFollicular || nextstage == Stage.ClimactericLuteal || nextstage == Stage.ClimactericBleeding ? 6.0f : 1.0f;
if (calculateHours) currentIntervalHours = PeriodRandomizer(nextstage, variabilityFactor);
curStage = nextstage;
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), GetNextUpdate(), parent.pawn, false);
}
protected virtual void GoOvulatoryStage(bool climacteric)
@@ -1696,13 +1656,11 @@ namespace RJW_Menstruation
//stage can be interrupted in other reasons
protected void StayCurrentStage()
{
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), GetNextUpdate(), parent.pawn, false);
}
//stage never changes
protected void StayCurrentStageConst(Stage curstage)
{
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curstage), GetNextUpdate(), parent.pawn, false);
}
protected void GoFollicularOrBleeding()
@@ -1745,6 +1703,8 @@ namespace RJW_Menstruation
return (int)(Props.bleedingIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f));
case Stage.Recover:
return (int)(Props.recoveryIntervalDays * 24 * Rand.Range(-0.05f, 0.05f));
+ case Stage.Pregnant:
+ return (int)MenstruationUtility.GestationHours(pregnancy);
default: // Often unused
return 1;
}
@@ -1772,24 +1732,32 @@ namespace RJW_Menstruation
protected Stage RandomStage()
{
- int rand = Rand.ElementByWeight(
- 0, Props.follicularIntervalDays - Props.bleedingIntervalDays,
- 1, Props.lutealIntervalDays,
- 2, Props.bleedingIntervalDays);
+ Stage stage = Rand.ElementByWeight(
+ Stage.Follicular, Props.follicularIntervalDays - Props.bleedingIntervalDays,
+ Stage.Luteal, Props.lutealIntervalDays,
+ Stage.Bleeding, Props.bleedingIntervalDays);
- switch (rand)
+ switch (stage)
{
- case 0:
+ case Stage.Follicular:
curStageHrs = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * 24);
- return Stage.Follicular;
- case 1:
+ break;
+ case Stage.Luteal:
curStageHrs = Rand.Range(0, Props.lutealIntervalDays * 24);
- return Stage.Luteal;
- case 2:
+ break;
+ case Stage.Bleeding:
curStageHrs = Rand.Range(0, Props.bleedingIntervalDays * 24);
- return Stage.Bleeding;
- default: return Stage.Follicular;
+ break;
}
+ return stage;
+ }
+
+ public void CopyCycleProperties(HediffComp_Menstruation original)
+ {
+ cycleSpeed = original.cycleSpeed;
+ cycleVariability = original.cycleVariability;
+ ovarypower = original.ovarypower;
+ crampPain = original.crampPain;
}
public class Egg : IExposable
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs
index 56eff5c..79ef1c0 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs
@@ -9,6 +9,8 @@ namespace RJW_Menstruation
{
public class Hediff_MultiplePregnancy : Hediff_BasePregnancy
{
+ protected Dictionary enzygoticSiblings; // Each pawn and who they split from
+
public override void DiscoverPregnancy()
{
PregnancyThought();
@@ -185,6 +187,68 @@ namespace RJW_Menstruation
//baby.story.birthLastName = last_name;
}
+ protected void CopyBodyPartProperties(Hediff part, Hediff originalPart)
+ {
+ CompHediffBodyPart comp = part.TryGetComp();
+ CompHediffBodyPart originalComp = originalPart.TryGetComp();
+
+ if (comp != null && originalComp != null)
+ {
+ // the string properties should be the same between both pawns anyways, besides the name of the owner
+ part.Severity = originalPart.Severity;
+ comp.SizeBase = originalComp.SizeBase;
+ comp.SizeOwner = originalComp.SizeOwner;
+ comp.EffSize = originalComp.EffSize;
+ comp.FluidAmmount = originalComp.FluidAmmount;
+ comp.FluidModifier = originalComp.FluidModifier;
+ }
+
+ HediffComp_Menstruation originalMenstruationComp = originalPart.GetMenstruationComp();
+ if (originalMenstruationComp != null)
+ {
+ part.GetMenstruationComp()?.CopyCycleProperties(originalMenstruationComp);
+ }
+ HediffComp_Breast originalBreastComp = originalPart.GetBreastComp();
+ if (originalBreastComp != null)
+ {
+ part.GetBreastComp()?.CopyBreastProperties(originalBreastComp);
+ }
+ }
+
+ protected void CopyBodyPartRecord(Pawn baby, Pawn original, BodyPartRecord babyBPR, BodyPartRecord originalBPR)
+ {
+ if (babyBPR == null || originalBPR == null) return;
+
+ RemoveBabyParts(baby, Genital_Helper.get_PartsHediffList(baby, babyBPR));
+ foreach (Hediff originalPart in Genital_Helper.get_PartsHediffList(original, originalBPR))
+ {
+ Hediff part = SexPartAdder.MakePart(originalPart.def, baby, babyBPR);
+ CopyBodyPartProperties(part, originalPart);
+ baby.health.AddHediff(part, babyBPR);
+ }
+ }
+
+ // Baby is the sibling to be changed, original is the first of the set and the one to copy to the rest.
+ public virtual void ProcessIdenticalSibling(Pawn baby, Pawn original)
+ {
+ // They'll be the same pawnkind, which lets us make a lot of useful assumptions
+ // However, some RNG might still be involved in genital generation (e.g. futas), so the easiest method is to clear out and re-generate
+ // A bit wasteful since Hediff_BasePregnancy.PostBirth already redid the genitals
+ CopyBodyPartRecord(baby, original, Genital_Helper.get_genitalsBPR(baby), Genital_Helper.get_genitalsBPR(original));
+ CopyBodyPartRecord(baby, original, Genital_Helper.get_breastsBPR(baby), Genital_Helper.get_breastsBPR(original));
+ CopyBodyPartRecord(baby, original, Genital_Helper.get_anusBPR(baby), Genital_Helper.get_anusBPR(original));
+ if (baby.IsHAR())
+ HARCompatibility.CopyHARPropertiesPostBirth(baby, original);
+ }
+
+ public override void PostBirth(Pawn mother, Pawn father, Pawn baby)
+ {
+ base.PostBirth(mother, father, baby);
+ // Has to happen on birth since RJW redoes the genitals at birth
+ if (!enzygoticSiblings.NullOrEmpty() && enzygoticSiblings.TryGetValue(baby, out Pawn original) && baby != original)
+ ProcessIdenticalSibling(baby, original);
+ }
+
// From RJW's trait code
protected List GetInheritableTraits(Pawn mother, Pawn father)
{
@@ -279,13 +343,17 @@ namespace RJW_Menstruation
return traitpool;
}
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_Collections.Look(ref enzygoticSiblings, "enzygoticSiblings", keyLookMode: LookMode.Reference, valueLookMode: LookMode.Reference);
+ }
+
protected override void GenerateBabies()
{
AddNewBaby(pawn, father);
}
-
-
protected void Train(Pawn baby, Pawn mother)
{
if (xxx.is_human(baby) || baby.Faction != Faction.OfPlayer) return;
@@ -348,27 +416,25 @@ namespace RJW_Menstruation
);
int division = 1;
- HairDef firsthair = null;
- Color firsthaircolor = Color.white;
- BodyTypeDef firstbody = null;
- CrownType firstcrown = CrownType.Undefined;
+ Pawn firstbaby = null;
string firstheadpath = null;
- string firstHARcrown = null;
int traitSeed = Rand.Int;
List parentTraits = GetInheritableTraits(mother, father);
while (Rand.Chance(Configurations.EnzygoticTwinsChance) && division < Configurations.MaxEnzygoticTwins) division++;
for (int i = 0; i < division; i++)
{
Pawn baby = GenerateBaby(request, mother, father, parentTraits, traitSeed);
+ if (baby == null) break;
if (division > 1)
{
- if (i == 0 && baby.story != null)
+ if (i == 0) firstbaby = baby;
+ else enzygoticSiblings?.Add(baby, firstbaby);
+
+ if (baby.story == null) continue;
+
+ if (i == 0)
{
- firsthair = baby.story.hairDef;
- firsthaircolor = baby.story.hairColor;
request.FixedGender = baby.gender;
- firstbody = baby.story.bodyType;
- firstcrown = baby.story.crownType;
firstheadpath = (string)baby.story.GetMemberValue("headGraphicPath");
if (firstheadpath == null)
{
@@ -376,36 +442,25 @@ namespace RJW_Menstruation
if (head != null) baby.story.SetMemberValue("headGraphicPath", head.GraphicPath);
firstheadpath = (string)baby.story.GetMemberValue("headGraphicPath");
}
- if (Configurations.HARActivated && baby.IsHAR())
- {
- firstHARcrown = baby.GetHARCrown();
- }
}
else
{
- if (baby.story != null)
- {
- baby.story.hairDef = firsthair;
- baby.story.hairColor = firsthaircolor;
- baby.story.bodyType = firstbody;
- baby.story.crownType = firstcrown;
- baby.story.SetMemberValue("headGraphicPath", firstheadpath);
+ baby.story.hairDef = firstbaby.story.hairDef;
+ baby.story.hairColor = firstbaby.story.hairColor;
+ baby.story.bodyType = firstbaby.story.bodyType;
+ baby.story.crownType = firstbaby.story.crownType;
+ baby.story.SetMemberValue("headGraphicPath", firstheadpath);
- if (Configurations.HARActivated && baby.IsHAR())
- {
- baby.SetHARCrown(firstHARcrown);
- }
+ if (baby.IsHAR())
+ {
+ HARCompatibility.CopyHARProperties(baby, firstbaby);
}
}
}
-
- if (baby != null) babies.Add(baby);
+ babies.Add(baby);
}
-
-
-
return true;
}
@@ -665,8 +720,17 @@ namespace RJW_Menstruation
pawn.story.traits.allTraits = selectedTraits;
}
+ public override void Initialize(Pawn mother, Pawn dad)
+ {
+ enzygoticSiblings = new Dictionary();
+ base.Initialize(mother, dad);
+ }
-
+ public string DueDate()
+ {
+ if (pawn.Map == null) return "";
+ return GenDate.DateFullStringWithHourAt(GenDate.TickGameToAbs((int)p_end_tick), Find.WorldGrid.LongLatOf(pawn.Map.Tile));
+ }
}
///
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs
index 22bf735..2c8c2c9 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs
@@ -43,12 +43,18 @@ namespace RJW_Menstruation
{
Texture2D icon, icon_overay;
string description = "";
- if (Configurations.Debug) description += comp.curStage + ": " + comp.curStageHrs + "\n" + "fertcums: " + comp.TotalFertCum + "\n" + "ovarypower: " + comp.ovarypower + "\n" + "eggs: " + comp.GetNumofEggs + "\n";
+ if (Configurations.Debug) {
+ description += comp.curStage + ": " + comp.curStageHrs + "\n" +
+ (comp.Pregnancy is Hediff_MultiplePregnancy preg ? "due: " + preg.DueDate() + "\n" : "") +
+ "fertcums: " + comp.TotalFertCum + "\n" +
+ "ovarypower: " + comp.ovarypower + "\n" +
+ "eggs: " + comp.GetNumofEggs + "\n";
+ }
else description += comp.GetCurStageLabel + "\n";
if (pawn.IsPregnant())
{
Hediff_BasePregnancy hediff = comp.Pregnancy;
- if (Utility.ShowFetusImage(hediff))
+ if (hediff != null && Utility.ShowFetusImage(hediff))
{
icon = comp.GetPregnancyIcon(hediff);
if (hediff is Hediff_BasePregnancy h)
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs
index 2265058..f26ca4c 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs
@@ -1,5 +1,4 @@
using HarmonyLib;
-using HugsLib;
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
@@ -16,14 +15,12 @@ namespace RJW_Menstruation
//Log.Message("Initialize on spawnsetup");
foreach (HediffComp_Menstruation comp in __instance.GetMenstruationComps())
{
- HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(comp.actionref);
comp.Initialize();
}
HediffComp_Breast bcomp = __instance.GetBreastComp();
if (bcomp != null)
{
- HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(bcomp.action);
bcomp.Initialize();
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj b/1.3/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj
index 198c10f..f73a2ef 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj
@@ -89,12 +89,12 @@
-
- ..\..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll
+
+ ..\..\..\..\..\..\..\..\workshop\content\294100\839005762\1.3\Assemblies\AlienRace.dll
False
-
- ..\..\..\..\..\..\..\..\workshop\content\294100\818773962\v1.3\Assemblies\HugsLib.dll
+
+ ..\..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll
False
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs
index 6a1f8b8..c34c0e9 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs
@@ -48,7 +48,7 @@ namespace RJW_Menstruation
{
protected override void SurgeryResult(HediffComp_Breast breast)
{
- breast.AdjustAreolaSizeImmidiately(0.1f);
+ breast.AdjustAreolaSizeImmediately(0.2f);
}
}
@@ -56,7 +56,7 @@ namespace RJW_Menstruation
{
protected override void SurgeryResult(HediffComp_Breast breast)
{
- breast.AdjustAreolaSizeImmidiately(-0.1f);
+ breast.AdjustAreolaSizeImmediately(-0.2f);
}
}
@@ -64,7 +64,7 @@ namespace RJW_Menstruation
{
protected override void SurgeryResult(HediffComp_Breast breast)
{
- breast.AdjustNippleSizeImmidiately(0.1f);
+ breast.AdjustNippleSizeImmediately(0.2f);
}
}
@@ -72,7 +72,7 @@ namespace RJW_Menstruation
{
protected override void SurgeryResult(HediffComp_Breast breast)
{
- breast.AdjustNippleSizeImmidiately(-0.1f);
+ breast.AdjustNippleSizeImmediately(-0.2f);
}
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs
index 6189613..320763d 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs
@@ -98,14 +98,6 @@ namespace RJW_Menstruation
public static readonly string Option23_Label = "Option23_Label".Translate();
public static readonly string Option23_Label_1 = "Option23_Label_1".Translate();
public static readonly string Option23_Label_2 = "Option23_Label_2".Translate();
- public static readonly string Option24_Label = "Option24_Label".Translate();
- public static readonly string Option24_Desc = "Option24_Desc".Translate();
- public static readonly string Option25_Label = "Option25_Label".Translate();
- public static readonly string Option25_Desc = "Option25_Desc".Translate();
- public static readonly string Option26_Label = "Option26_Label".Translate();
- public static readonly string Option26_Desc = "Option26_Desc".Translate();
- public static readonly string Option27_Label = "Option27_Label".Translate();
- public static readonly string Option27_Desc = "Option27_Desc".Translate();
public static readonly string Option28_Label = "Option28_Label".Translate();
public static readonly string Option28_Tooltip = "Option28_Tooltip".Translate();
public static readonly string Option29_Label = "Option29_Label".Translate();
@@ -116,6 +108,12 @@ namespace RJW_Menstruation
public static readonly string Option31_Desc = "Option31_Desc".Translate();
public static readonly string Option32_Label = "Option32_Label".Translate();
public static readonly string Option32_Desc = "Option32_Desc".Translate();
+ public static readonly string Option_MaxBreastIncrementFactor_Label = "Option_MaxBreastIncrementFactor_Label".Translate();
+ public static readonly string Option_MaxBreastIncrementFactor_Desc = "Option_MaxBreastIncrementFactor_Desc".Translate();
+ public static readonly string Option_MaxNippleIncrementFactor_Label = "Option_MaxNippleIncrementFactor_Label".Translate();
+ public static readonly string Option_MaxNippleIncrementFactor_Desc = "Option_MaxNippleIncrementFactor_Desc".Translate();
+ public static readonly string Option_PermanentNippleChange_Label = "Option_PermanentNippleChange_Label".Translate();
+ public static readonly string Option_PermanentNippleChange_Desc = "Option_PermanentNippleChange_Desc".Translate();
public static readonly string Option_EnableGatherCumGizmo_Label = "Option_EnableGatherCumGizmo_Label".Translate();
public static readonly string Option_EstrusOverride_Label = "Option_EstrusOverride_Label".Translate();
public static readonly string Option_EstrusOverride_Desc = "Option_EstrusOverride_Desc".Translate();
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs
index 21ed45b..7ec6033 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs
@@ -32,11 +32,11 @@ namespace RJW_Menstruation
private Texture2D anal;
private Color cumcolor;
- private readonly GUIStyle fontstylecenter = new GUIStyle() { alignment = TextAnchor.MiddleCenter };
- private readonly GUIStyle fontstyleright = new GUIStyle() { alignment = TextAnchor.MiddleRight };
- private readonly GUIStyle fontstyleleft = new GUIStyle() { alignment = TextAnchor.MiddleLeft };
- private readonly GUIStyle boxstyle = new GUIStyle(GUI.skin.textArea);
- private readonly GUIStyle buttonstyle = new GUIStyle(GUI.skin.button);
+ private static GUIStyle fontstylecenter = null;
+ private static GUIStyle fontstyleright = null;
+ private static GUIStyle fontstyleleft = null;
+ private static GUIStyle boxstyle = null;
+ private static GUIStyle buttonstyle = null;
public Pawn Pawn
{
@@ -137,6 +137,16 @@ namespace RJW_Menstruation
}
+ public override void PreOpen()
+ {
+ base.PreOpen();
+ if (fontstylecenter == null) fontstylecenter = new GUIStyle() { alignment = TextAnchor.MiddleCenter };
+ if (fontstyleright == null) fontstyleright = new GUIStyle() { alignment = TextAnchor.MiddleRight };
+ if (fontstyleleft == null) fontstyleleft = new GUIStyle() { alignment = TextAnchor.MiddleLeft };
+ if (boxstyle == null) boxstyle = new GUIStyle(GUI.skin.textArea);
+ if (buttonstyle == null) buttonstyle = new GUIStyle(GUI.skin.button);
+ }
+
private void MainContents(Rect mainRect)
{
@@ -370,7 +380,7 @@ namespace RJW_Menstruation
- pawn.DrawBreastIcon(BreastIconRect, Mouse.IsOver(BreastIconRect) && Input.GetMouseButton(0));
+ pawn.DrawBreastIcon(BreastIconRect);
GUI.color = Color.white;
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs
index 38d40a3..5e4ab93 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs
@@ -159,7 +159,7 @@ namespace RJW_Menstruation
}
}
- public static void DrawBreastIcon(this Pawn pawn, Rect rect, bool drawOrigin = false)
+ public static void DrawBreastIcon(this Pawn pawn, Rect rect)
{
Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("breast"));
Texture2D breast, nipple, areola;
@@ -167,7 +167,7 @@ namespace RJW_Menstruation
{
HediffComp_Breast comp = hediff.TryGetComp();
string icon;
- if (comp != null) icon = comp.Props.BreastTex ?? "Breasts/Breast_Breast";
+ if (comp != null) icon = comp.Props?.BreastTex ?? "Breasts/Breast_Breast";
else
{
breast = ContentFinder.Get("Breasts/Breast_Breast00", false);
@@ -191,16 +191,8 @@ namespace RJW_Menstruation
string nippleicon, areolaicon;
float nipplesize, areolasize;
- if (drawOrigin)
- {
- nipplesize = comp.OriginNipple;
- areolasize = comp.OriginAreola;
- }
- else
- {
- nipplesize = comp.NippleSize;
- areolasize = comp.AreolaSize;
- }
+ nipplesize = comp.NippleSize;
+ areolasize = comp.AreolaSize;
nippleicon = icon + "_Nipple0" + GetNippleIndex(nipplesize);
areolaicon = icon + "_Areola0" + GetAreolaIndex(areolasize);
@@ -212,14 +204,8 @@ namespace RJW_Menstruation
GUI.color = pawn.story.SkinColor;
GUI.DrawTexture(rect, breast, ScaleMode.ScaleToFit);
- if (drawOrigin)
- {
- GUI.color = comp.OriginColor;
- }
- else
- {
- GUI.color = comp.NippleColor;
- }
+ GUI.color = comp.NippleColor;
+
GUI.DrawTexture(rect, areola, ScaleMode.ScaleToFit);
GUI.DrawTexture(rect, nipple, ScaleMode.ScaleToFit);
diff --git a/About/About.xml b/About/About.xml
index ac2c696..4dbf4bb 100644
--- a/About/About.xml
+++ b/About/About.xml
@@ -13,12 +13,6 @@
steam://url/CommunityFilePage/2009463077
https://github.com/pardeike/HarmonyRimWorld/releases/latest
-
- UnlimitedHugs.HugsLib
- HugsLib
- https://github.com/UnlimitedHugs/RimworldHugsLib/releases/latest
- steam://url/CommunityFilePage/818773962
-
rim.job.world
RimJobWorld
@@ -26,12 +20,13 @@
- UnlimitedHugs.HugsLib
brrainz.harmony
+ erdelf.HumanoidAlienRaces
rim.job.world
Abraxas.RJW.RaceSupport
rjw.milk.humanoid
rjw.sexperience
+ rjw.cum
rjw.menstruation
Adds menstruation mechanics to vaginas
diff --git a/About/Manifest.xml b/About/Manifest.xml
index d56ea34..8984142 100644
--- a/About/Manifest.xml
+++ b/About/Manifest.xml
@@ -1,7 +1,7 @@
RJW Menstruation
- 1.0.7.0
+ 1.0.7.1
@@ -12,6 +12,7 @@
Abraxas.RJW.RaceSupport
rjw.milk.humanoid
rjw.sexperience
+ rjw.cum
diff --git a/changelogs.txt b/changelogs.txt
index 45dff74..9dbd28c 100644
--- a/changelogs.txt
+++ b/changelogs.txt
@@ -1,3 +1,15 @@
+Version 1.0.7.1
+ - Null reference error fix for multiple wombs when one is pregnant.
+ - Fix the progress bar on pregnancy again. Also make undiscovered pregnancies a little more subtle.
+ - Nipple size/transition system rewritten to be simpler under the hood. Should work with existing saves, but you might find sizes to be different, especially for very large or very small breasts.
+ - Replaced HugsLib-based scheduler with normal ticking. This should reduce some 'phantom cycle' bugs.
+ - Redone calculation to determine low eggs remaining. This should cause climacteric to be applied at a more appropriate time in the pawn's life, especially for those with very long cycles.
+ - Identical twins conceived after this update will have identical sex part sizes, properties, etc. upon being born.
+ - Identical twins of HAR races will have identical coloration, part variations, and masking.
+ - For modders:
+ - The function Hediff_MultiplePregnancy.ProcessIdenticalSibling is called on every identical sibling when born except the first. Any race-specfic genetic properties can be patched in there.
+ - Any mods that add comps to RJW parts should copy what they need to on a postfix to Hediff_MultiplePregnancy.CopyBodyPartProperties, e.g. how menstruation itself does in that function.
+
Version 1.0.7.0
- Not save compatible with previous versions. Expect glitches and many red errors if you try. However, things should stabilize eventually.
- Designed for RJW 5.0.0, but should work with previous versions.