diff --git a/1.3/Assemblies/RJW_Menstruation.dll b/1.3/Assemblies/RJW_Menstruation.dll
index b340755..7cef547 100644
Binary files a/1.3/Assemblies/RJW_Menstruation.dll and b/1.3/Assemblies/RJW_Menstruation.dll differ
diff --git a/1.3/Defs/TaleDefs/Tales_Cum.xml b/1.3/Defs/TaleDefs/Tales_Cum.xml
new file mode 100644
index 0000000..b5a37c7
--- /dev/null
+++ b/1.3/Defs/TaleDefs/Tales_Cum.xml
@@ -0,0 +1,31 @@
+
+
+ CameInside
+
+ Tale_DoublePawn
+ Volatile
+ FUCKER
+ FUCKED
+ 1.5
+
+
+ tale_noun->[FUCKER_nameDef] coming inside of [FUCKED_nameDef]
+ image->[FUCKER_nameFull]'s penis deep inside of [FUCKED_nameFull]'s vagina [circumstance_group]
+ image->[FUCKER_nameFull]'s penis vanishing into [FUCKED_nameFull]'s vagina [circumstance_group]
+ image->[FUCKED_nameFull]'s vagina being filled by [FUCKER_nameFull]'s penis [circumstance_group]
+ image->[FUCKED_nameFull]'s vagina gripping [FUCKER_nameFull]'s penis tight [cirsumstance_group]
+ circumstance_phrase->while [FUCKER_nameDef] grits [FUCKER_possessive] teeth
+ circumstance_phrase->while [FUCKER_nameDef] wears a triumphant smirk
+ circumstance_phrase->as [FUCKED_nameDef] shudders in ecstasy
+ circumstance_phrase->as [FUCKER_nameDef] shoots [FUCKER_possessive] load into [FUCKED_nameDef]
+ circumstance_phrase->while [FUCKED_nameDef] looks into [FUCKER_nameDef]'s eyes with a smile
+ desc_sentence->[FUCKER_nameDef]'s cum oozes out of [FUCKED_nameDef]'s vagina and drips onto the floor.
+ desc_sentence->[FUCKER_nameDef]'s sperm races into [FUCKED_nameDef]'s womb and enters [FUCKED_possessive] egg.
+ desc_sentence->[FUCKER_nameDef]'s cum shoots into [FUCKED_nameDef]'s womb.
+ desc_sentence->[FUCKED_nameDef]'s womb is filled with cum.
+ desc_sentence->Sweat runs down [FUCKER_nameDef]'s face.
+ desc_sentence->[FUCKED_nameDef] is panting heavily.
+
+
+
+
\ No newline at end of file
diff --git a/1.3/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml b/1.3/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml
index 32aa104..d10b3fe 100644
--- a/1.3/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml
+++ b/1.3/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml
@@ -8,7 +8,6 @@
排卵
黄体期
月经来潮
- 已受精
怀孕
产后恢复
无
diff --git a/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml b/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml
index eb4314f..3ce1dfe 100644
--- a/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml
+++ b/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml
@@ -8,7 +8,6 @@
排卵
黃體期
月經來潮
- 已受精
懷孕
從出生中恢復
無
diff --git a/1.3/Languages/English/Keyed/RJW_Menstruation.xml b/1.3/Languages/English/Keyed/RJW_Menstruation.xml
index 2f84c88..bdb4a6f 100644
--- a/1.3/Languages/English/Keyed/RJW_Menstruation.xml
+++ b/1.3/Languages/English/Keyed/RJW_Menstruation.xml
@@ -8,7 +8,6 @@
Ovulation
Luteal
In period
- Luteal
Pregnant
Recovering from birth
None
diff --git a/1.3/Languages/Korean/Keyed/RJW_Menstruation.xml b/1.3/Languages/Korean/Keyed/RJW_Menstruation.xml
index 6370588..829fcf5 100644
--- a/1.3/Languages/Korean/Keyed/RJW_Menstruation.xml
+++ b/1.3/Languages/Korean/Keyed/RJW_Menstruation.xml
@@ -8,7 +8,6 @@
배란
황체기
생리중
- 황체기
임신
회복기
없음
diff --git a/1.3/Languages/Spanish/Keyed/RJW_Menstruation.xml b/1.3/Languages/Spanish/Keyed/RJW_Menstruation.xml
index 7e28a7a..e428b7d 100644
--- a/1.3/Languages/Spanish/Keyed/RJW_Menstruation.xml
+++ b/1.3/Languages/Spanish/Keyed/RJW_Menstruation.xml
@@ -8,7 +8,6 @@
Ovulación
Luteal
En periodo
- Luteal
Embarazada
Recuperándose del nacimiento
Ninguna
diff --git a/1.3/MilkModule/Assemblies/MilkModule.dll b/1.3/MilkModule/Assemblies/MilkModule.dll
index 9b9615a..778684a 100644
Binary files a/1.3/MilkModule/Assemblies/MilkModule.dll and b/1.3/MilkModule/Assemblies/MilkModule.dll differ
diff --git a/1.3/Patches/Hediffs_PrivateParts.xml b/1.3/Patches/Hediffs_PrivateParts.xml
index 9dce268..662def7 100644
--- a/1.3/Patches/Hediffs_PrivateParts.xml
+++ b/1.3/Patches/Hediffs_PrivateParts.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
@@ -16,15 +16,13 @@
10
1.0
1.0
- 0.05
- 14
+ 14
14
6
30
1
Womb/Womb
Genitals/Vagina
- 420
true
@@ -40,8 +38,7 @@
10
1.0
1.0
- 0.05
- 14
+ 14
14
0
30
@@ -89,8 +86,7 @@
10
2.0
2.0
- 0.05
- 14
+ 14
14
0
0
diff --git a/1.3/Patches/Hediffs_PrivateParts_Animal.xml b/1.3/Patches/Hediffs_PrivateParts_Animal.xml
index adfb808..8ffacb0 100644
--- a/1.3/Patches/Hediffs_PrivateParts_Animal.xml
+++ b/1.3/Patches/Hediffs_PrivateParts_Animal.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
@@ -18,8 +18,7 @@
8
1.0
1.0
- 0.05
- 14
+ 14
166
8
15
@@ -40,8 +39,7 @@
6
1.0
2.0
- 0.05
- 9
+ 9
10
0
15
@@ -63,8 +61,7 @@
25
1.0
1.0
- 0.05
- 7
+ 7
14
0
30
@@ -87,8 +84,7 @@
50
0.5
0.2
- 0.05
- 270
+ 270
30
0
300
@@ -109,8 +105,7 @@
10
1.0
1.0
- 0.05
- 5
+ 5
16
0
15
@@ -131,8 +126,7 @@
5
1.0
2.0
- 0.05
- 6
+ 6
9
0
3
@@ -153,8 +147,7 @@
5
2.0
2.0
- 0.05
- 12
+ 12
9
0
3
@@ -175,8 +168,7 @@
10
2.0
2.0
- 0.05
- 14
+ 14
14
0
3
diff --git a/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml b/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml
index 7628c4d..556660e 100644
--- a/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml
+++ b/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
@@ -18,8 +18,7 @@
18
1.0
1.0
- 0.05
- 10
+ 10
10
4
30
@@ -40,8 +39,7 @@
8
1.0
1.0
- 0.05
- 8
+ 8
12
0
0
@@ -62,8 +60,7 @@
15
1.0
1.0
- 0.05
- 10
+ 10
12
0
30
@@ -84,8 +81,7 @@
8
1.0
1.0
- 0.05
- 6
+ 6
12
0
30
@@ -106,8 +102,7 @@
12
1.0
1.0
- 0.05
- 14
+ 14
20
0
30
@@ -128,8 +123,7 @@
2
0.1
0.1
- 0.05
- 14
+ 14
14
0
0
@@ -150,8 +144,7 @@
10
0.1
0.1
- 0.05
- 14
+ 14
14
0
0
diff --git a/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml b/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml
index 59505fa..e0d0729 100644
--- a/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml
+++ b/1.3/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
@@ -16,15 +16,13 @@
10
1.0
1.0
- 0.05
- 1800
+ 1800
1800
6
30
1
Womb/Womb
Genitals/Vagina
- 620
true
@@ -50,15 +48,13 @@
10
1.0
1.0
- 0.05
- 7
+ 7
10
0
10
1
Womb/Womb
Genitals/Vagina
- 620
true
@@ -86,15 +82,13 @@
10
0.2
0.2
- 0.05
- 14
+ 14
14
0
10
1
Womb/Womb
Genitals/Vagina
- 420
true
diff --git a/1.3/SexperienceModule/Assemblies/SexperienceModule.dll b/1.3/SexperienceModule/Assemblies/SexperienceModule.dll
index 55382de..79ed7a6 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 e331d6b..b35b0a6 100644
--- a/1.3/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs
+++ b/1.3/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs
@@ -1,13 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Verse;
-using Verse.AI;
-using RimWorld;
-using Milk;
+using Milk;
using RJW_Menstruation;
+using Verse;
namespace MilkModule
{
@@ -51,7 +44,7 @@ namespace MilkModule
if (pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Heavy_Lactating_Permanent))
{
result = pawn.TryGetComp();
-
+
}
else
{
@@ -125,6 +118,6 @@ namespace MilkModule
//
//
//}
-
+
}
diff --git a/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs b/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs
index 8fbcb96..2de9e87 100644
--- a/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs
+++ b/1.3/source/RJW_Menstruation/MilkModule/Milk_Patch.cs
@@ -1,14 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Reflection;
-using HarmonyLib;
-using Verse;
-using RimWorld;
+using HarmonyLib;
using Milk;
using RJW_Menstruation;
+using System.Reflection;
+using Verse;
namespace MilkModule
{
@@ -16,7 +10,7 @@ namespace MilkModule
{
static First()
{
- var har = new Harmony("RJW_Menstruation_MilkModule");
+ Harmony har = new Harmony("RJW_Menstruation_MilkModule");
har.PatchAll(Assembly.GetExecutingAssembly());
}
}
diff --git a/1.3/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs b/1.3/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs
index 019d075..c526740 100644
--- a/1.3/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs
+++ b/1.3/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs
index 739e645..2ef752e 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs
@@ -10,12 +10,12 @@ namespace RJW_Menstruation
{
public const float ImplantationChanceDefault = 0.65f;
public const int ImplantationChanceAdjustDefault = 65;
- public const float FertilizeChanceDefault = 0.10f;
- public const int FertilizeChanceAdjustDefault = 100;
- public const float CumDecayRatioDefault = 0.30f;
- public const int CumDecayRatioAdjustDefault = 300;
- public const float CumFertilityDecayRatioDefault = 0.2f;
- public const int CumFertilityDecayRatioAdjustDefault = 200;
+ public const float FertilizeChanceDefault = 0.15f;
+ public const int FertilizeChanceAdjustDefault = 150;
+ public const float CumDecayRatioDefault = 0.15f;
+ public const int CumDecayRatioAdjustDefault = 150;
+ public const float CumFertilityDecayRatioDefault = 0.05f;
+ public const int CumFertilityDecayRatioAdjustDefault = 50;
public const int CycleAccelerationDefault = 6;
public const float EnzygoticTwinsChanceDefault = 0.002f;
public const int EnzygoticTwinsChanceAdjustDefault = 2;
@@ -79,7 +79,7 @@ namespace RJW_Menstruation
return NippleTransitionVariance * NippleTransitionSpeed;
}
}
-
+
public static void SettoDefault()
{
ImplantationChanceAdjust = ImplantationChanceAdjustDefault;
@@ -152,14 +152,14 @@ namespace RJW_Menstruation
{
List removeList = new List();
if (!HybridOverride.NullOrEmpty())
- foreach(HybridInformations o in HybridOverride)
+ foreach (HybridInformations o in HybridOverride)
{
if (o.IsNull) removeList.Add(o);
if (o.DefName == def.defName) return true;
}
if (!removeList.NullOrEmpty())
{
- foreach(HybridInformations o in removeList)
+ foreach (HybridInformations o in removeList)
{
HybridOverride.Remove(o);
}
@@ -226,7 +226,7 @@ namespace RJW_Menstruation
base.ExposeData();
}
-
+
}
@@ -242,7 +242,7 @@ namespace RJW_Menstruation
{
get
{
- int days = VariousDefOf.VaginaCompProperties.bleedingIntervalDays;
+ int days = VariousDefOf.HumanVaginaCompProperties.bleedingIntervalDays;
return days * 0.03f * Configurations.BleedingAmount * 6;
}
}
@@ -300,7 +300,7 @@ namespace RJW_Menstruation
{
wombsection.CheckboxLabeled(Translations.Option18_Label, ref Configurations.DrawEggOverlay, Translations.Option18_Desc);
}
-
+
wombsection.CheckboxLabeled(Translations.Option10_Label, ref Configurations.DrawVaginaStatus, Translations.Option10_Desc);
wombsection.CheckboxLabeled(Translations.Option29_Label, ref Configurations.AllowShrinkIcon, Translations.Option29_Desc);
if (wombsection.ButtonText(Translations.Option11_Label + ": " + Configurations.LevelString(Configurations.infoDetail)))
@@ -353,17 +353,17 @@ namespace RJW_Menstruation
}
Adjust = (int)(Configurations.NippleTransitionVariance * 1000);
- wombsection.Label(Translations.Option24_Label + " " + Configurations.NippleTransitionVariance* 100 + " / 100", -1,Translations.Option24_Desc);
- Adjust = (int)wombsection.Slider(Adjust,0,1000);
+ wombsection.Label(Translations.Option24_Label + " " + Configurations.NippleTransitionVariance * 100 + " / 100", -1, Translations.Option24_Desc);
+ Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
Configurations.NippleTransitionVariance = (float)Adjust / 1000;
Adjust = (int)(Configurations.NipplePermanentTransitionVariance * 1000);
- wombsection.Label(Translations.Option25_Label + " " + Configurations.NipplePermanentTransitionVariance*100 + " / 100", -1, Translations.Option25_Desc);
+ wombsection.Label(Translations.Option25_Label + " " + Configurations.NipplePermanentTransitionVariance * 100 + " / 100", -1, Translations.Option25_Desc);
Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
Configurations.NipplePermanentTransitionVariance = (float)Adjust / 1000;
Adjust = (int)(Configurations.NippleMaximumTransition * 1000);
- wombsection.Label(Translations.Option26_Label + " " + Configurations.NippleMaximumTransition* 100 + " / 100", -1, Translations.Option26_Desc);
+ wombsection.Label(Translations.Option26_Label + " " + Configurations.NippleMaximumTransition * 100 + " / 100", -1, Translations.Option26_Desc);
Adjust = (int)wombsection.Slider(Adjust, 0, 1000);
Configurations.NippleMaximumTransition = (float)Adjust / 1000;
@@ -383,7 +383,8 @@ namespace RJW_Menstruation
Configurations.ImplantationChanceAdjust = (int)listmain.Slider(Configurations.ImplantationChanceAdjust, 0, 1000);
Configurations.ImplantationChance = (float)Configurations.ImplantationChanceAdjust / 100;
- listmain.Label(Translations.Option4_Label + " " + Configurations.FertilizeChance * 100 + "%", -1, Translations.Option4_Desc);
+ string tenMl = String.Format("10 ml: {0:0}%", (1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, 10)) * 100f);
+ listmain.LabelDouble(Translations.Option4_Label + " " + Configurations.FertilizeChance * 100 + "%", tenMl, Translations.Option4_Desc);
Configurations.FertilizeChanceAdjust = (int)listmain.Slider(Configurations.FertilizeChanceAdjust, 0, 1000);
Configurations.FertilizeChance = (float)Configurations.FertilizeChanceAdjust / 1000;
@@ -399,7 +400,7 @@ namespace RJW_Menstruation
Configurations.EggLifespanMultiplier = (float)Adjust / 20;
- int semenlifespan = (int)(-5 / ((float)Math.Log10((1 - Configurations.CumFertilityDecayRatio)*10) - 1)) + 1;
+ int semenlifespan = (int)(-5 / ((float)Math.Log10((1 - Configurations.CumFertilityDecayRatio) * (1 - Configurations.CumDecayRatio) * 10) - 1)) + 1;
string estimatedlifespan;
if (semenlifespan < 0)
{
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Cum.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Cum.cs
index 2976f05..d969e18 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Cum.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Cum.cs
@@ -11,8 +11,7 @@ namespace RJW_Menstruation
public Pawn pawn;
protected float volume; // ml
- protected float fertvolume;
- public float fertFactor = 1.0f;
+ public float fertility = 1.0f;
public bool notcum = false; // for other fluids
public string notcumLabel = "";
protected bool useCustomColor = false;
@@ -32,7 +31,7 @@ namespace RJW_Menstruation
{
get
{
- return fertvolume;
+ return volume * fertility;
}
}
@@ -62,23 +61,20 @@ namespace RJW_Menstruation
{
get
{
+ if (DNAcache != null) return DNAcache;
+ try
+ {
+ DNAcache = pawn.def.GetModExtension();
+ }
+ catch (NullReferenceException)
+ {
+ DNAcache = ThingDefOf.Human.GetModExtension();
+ }
if (DNAcache == null)
{
- try
- {
- DNAcache = pawn.def.GetModExtension();
- }
- catch (NullReferenceException)
- {
- DNAcache = ThingDefOf.Human.GetModExtension();
- }
- if (DNAcache == null)
- {
- DNAcache = ThingDefOf.Human.GetModExtension();
- }
- return DNAcache;
+ DNAcache = ThingDefOf.Human.GetModExtension();
}
- else return DNAcache;
+ return DNAcache;
}
}
protected PawnDNAModExtension DNAcache = null;
@@ -130,7 +126,7 @@ namespace RJW_Menstruation
{
this.pawn = pawn;
volume = 1.0f;
- fertvolume = 1.0f;
+ fertility = 1.0f;
}
///
@@ -145,7 +141,7 @@ namespace RJW_Menstruation
{
this.pawn = pawn;
this.volume = volume;
- this.fertvolume = volume;
+ this.fertility = 0f;
this.notcum = true;
this.notcumLabel = notcumlabel;
this.notcumthickness = decayresist;
@@ -156,7 +152,7 @@ namespace RJW_Menstruation
{
this.pawn = pawn;
this.volume = volume;
- this.fertvolume = volume * fertility;
+ this.fertility = fertility;
this.filthDef = filthDef;
}
@@ -167,9 +163,8 @@ namespace RJW_Menstruation
Scribe_References.Look(ref pawn, "pawn", true);
Scribe_References.Look(ref internalThing, "internalThing", true);
Scribe_Values.Look(ref volume, "volume", volume, true);
- Scribe_Values.Look(ref fertvolume, "fertvolume", fertvolume, true);
+ Scribe_Values.Look(ref fertility, "fertility", fertility, true);
Scribe_Values.Look(ref notcumthickness, "notcumthickness", notcumthickness, true);
- Scribe_Values.Look(ref fertFactor, "fertFactor", fertFactor, true);
Scribe_Values.Look(ref notcum, "notcum", notcum, true);
Scribe_Values.Look(ref notcumLabel, "notcumLabel", notcumLabel, true);
Scribe_Values.Look(ref useCustomColor, "useCustomColor", useCustomColor, true);
@@ -183,11 +178,11 @@ namespace RJW_Menstruation
cumthickness = cumthickness.LerpMultiple(DecayResist, 0.3f, speed);
}
- public void MergeWithCum(float volumein, float fertility, ThingDef updatefilthDef = null)
+ public void MergeWithCum(float volumein, float fertility, ThingDef updatefilthDef = null)
{
if (updatefilthDef != null) filthDef = updatefilthDef;
volume += volumein;
- fertvolume += volumein*fertility;
+ this.fertility = (this.volume * this.fertility + volumein * fertility) / (this.volume + volumein);
cumthickness = Mathf.Lerp(cumthickness, 1.0f, volumein / volume);
}
@@ -195,12 +190,13 @@ namespace RJW_Menstruation
{
if (updatefilthDef != null) filthDef = updatefilthDef;
volume += volumein;
+ fertility = volume * fertility / (volume + volumein);
notcumthickness = Mathf.Lerp(notcumthickness, thickness, volumein / volume);
}
public bool ShouldRemove()
{
- if ((notcum || fertvolume < 0.001f) && volume < 0.01f) return true;
+ if ((notcum || FertVolume < 0.001f) && volume < 0.01f) return true;
return false;
}
@@ -209,17 +205,16 @@ namespace RJW_Menstruation
{
float totalleak = volume;
volume *= Math.Max(0, (1 - (Configurations.CumDecayRatio * (1 - DecayResist)) * leakfactor));
- fertvolume *= Math.Max(0, 1 - (Configurations.CumFertilityDecayRatio * (1 - DecayResist) + antisperm));
+ fertility *= Math.Max(0, 1 - (Configurations.CumFertilityDecayRatio * (1 - DecayResist) + antisperm));
CutMinor();
totalleak -= volume;
return totalleak;
}
-
+
public float DismishForce(float portion, float leakfactor = 1.0f)
{
float totalleak = volume;
- volume *= Math.Max(0, 1 - (portion * (1 - DecayResist/10)) * leakfactor);
- fertvolume *= Math.Max(0, 1 - (portion * (1 - DecayResist)) * leakfactor);
+ volume *= Math.Max(0, 1 - (portion * (1 - DecayResist / 10)) * leakfactor);
CutMinor();
totalleak -= volume;
return totalleak;
@@ -227,24 +222,20 @@ namespace RJW_Menstruation
public void CumEffects(Pawn pawn)
{
- if (!notcum && DNA != null && volume >= 1.0f)
- {
- List doers = DNA.ingestionOutcomeDoers;
-
- if (!doers.NullOrEmpty()) for (int i = 0; i < doers.Count; i++)
- {
- doers[i].DoIngestionOutcome(pawn, CumThing);
- }
- }
+ if (notcum || DNA == null || volume < 1.0f) return;
+
+ List doers = DNA.ingestionOutcomeDoers;
+
+ if (!doers.NullOrEmpty()) for (int i = 0; i < doers.Count; i++)
+ {
+ doers[i].DoIngestionOutcome(pawn, CumThing);
+ }
}
protected void CutMinor()
{
if (volume < 0.01f) volume = 0f;
- if (fertvolume < 0.001f) fertvolume = 0f;
}
-
-
}
public class CumMixture : Cum, IDisposable
@@ -259,7 +250,7 @@ namespace RJW_Menstruation
cums = new List();
}
- public CumMixture(Pawn pawn, float volume, List cums, Color color, ThingDef mixtureDef, bool pure)
+ public CumMixture(Pawn pawn, float volume, List cums, Color color, ThingDef mixtureDef, bool pure)
{
this.pawn = pawn;
this.volume = volume;
@@ -272,7 +263,7 @@ namespace RJW_Menstruation
public void Dispose()
{
cums.Clear();
-
+
}
public override void ExposeData()
@@ -284,17 +275,12 @@ namespace RJW_Menstruation
public string GetIngredients()
{
string res = "";
- if (!cums.NullOrEmpty()) for(int i=0; i memories = pawn.needs?.mood?.thoughts?.memories?.Memories.FindAll(
- x =>
+ x =>
x.def == VariousDefOf.CameInsideF
|| x.def == VariousDefOf.CameInsideFFetish
|| x.def == VariousDefOf.HaterCameInsideF);
- if (!memories.NullOrEmpty())
+ if (memories.NullOrEmpty()) return;
+ foreach (Thought_Memory m in memories)
{
- foreach (Thought_Memory m in memories)
- {
- if (m.def == VariousDefOf.HaterCameInsideF) m.moodPowerFactor = 0.5f;
- else m.moodPowerFactor = 0.3f;
-
- }
- if (pawn.Has(Quirk.Breeder)) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill);
- else pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.TookContraceptivePill);
+ if (m.def == VariousDefOf.HaterCameInsideF) m.moodPowerFactor = 0.5f;
+ else m.moodPowerFactor = 0.3f;
+
}
+ if (pawn.Has(Quirk.Breeder)) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill);
+ else pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.TookContraceptivePill);
}
-
}
-
-
-
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs
index bb507f3..3062feb 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs
@@ -1,10 +1,10 @@
-using Verse;
-using rjw;
+using rjw;
using rjw.Modules.Interactions.Contexts;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Rules.PartKindUsageRules;
using rjw.Modules.Shared;
using System.Collections.Generic;
+using Verse;
namespace RJW_Menstruation.Interactions
{
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 72b5d38..4a38f7a 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,21 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Verse;
+using HugsLib;
using RimWorld;
-using UnityEngine;
-using HugsLib;
using rjw;
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Verse;
namespace RJW_Menstruation
{
public class CompProperties_Breast : HediffCompProperties
{
public string BreastTex = "Breasts/Breast";
- public ColorInt BlacknippleColor = new ColorInt(55,20,0);
-
+ public ColorInt BlacknippleColor = new ColorInt(55, 20, 0);
+
public Color BlackNippleColor
{
@@ -24,7 +21,7 @@ namespace RJW_Menstruation
return BlacknippleColor.ToColor;
}
}
-
+
public CompProperties_Breast()
{
@@ -174,7 +171,7 @@ namespace RJW_Menstruation
Scribe_Values.Look(ref originareola, "originareola", originareola, true);
Scribe_Values.Look(ref originnipple, "originnipple", originnipple, true);
Scribe_Values.Look(ref pregnant, "pregnant", pregnant, true);
-
+
}
public override void CompPostTick(ref float severityAdjustment) { }
@@ -187,17 +184,14 @@ namespace RJW_Menstruation
public override void CompPostPostRemoved()
{
-
- if (parent?.pawn?.GetBreastComp() == this)
+ if (parent.pawn.health.hediffSet.hediffs.Contains(parent))
{
- Log.Warning("Something tried to remove hediff with wrong way.");
- }
- else
- {
- HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(action);
- Log.Message(parent.pawn.Label + "breast tick scheduler removed");
- base.CompPostPostRemoved();
+ 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();
}
protected long CalculateLastBirth()
@@ -207,13 +201,16 @@ namespace RJW_Menstruation
{
foreach (Pawn child in parent.pawn.relations.Children)
{
-
- bool isFetus;
- if (PregnancyHelper.GetPregnancy(parent.pawn) is Hediff_BasePregnancy preg)
+ bool isFetus = false;
+ foreach (Hediff_BasePregnancy preg in parent.pawn.health.hediffSet.GetHediffs())
{
- isFetus = preg.babies.Contains(child);
+ if (preg.babies.Contains(child))
+ {
+ isFetus = true;
+ break;
+ }
}
- else isFetus = false;
+
if (
parent.pawn.ageTracker.BirthAbsTicks - child.ageTracker.BirthAbsTicks > ageOfLastBirth &&
!isFetus &&
@@ -221,7 +218,7 @@ namespace RJW_Menstruation
)
youngestAge = parent.pawn.ageTracker.BirthAbsTicks - child.ageTracker.BirthAbsTicks;
}
- }
+ }
return youngestAge;
}
@@ -234,10 +231,10 @@ namespace RJW_Menstruation
{
ageOfLastBirth = CalculateLastBirth();
}
-
+
if (alphaPermanent < 0f)
{
- alphaPermanent = (Utility.RandGaussianLike(0.0f, 0.3f) + Rand.Range(0.0f,0.5f))/2;
+ alphaPermanent = (Utility.RandGaussianLike(0.0f, 0.3f) + Rand.Range(0.0f, 0.5f)) / 2;
originalpha = alphaPermanent;
alpha = alphaPermanent;
alphaCurrent = alphaPermanent;
@@ -261,7 +258,7 @@ namespace RJW_Menstruation
HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(action, TICKINTERVAL, parent.pawn);
}
-
+
public void Transition()
{
@@ -284,7 +281,7 @@ namespace RJW_Menstruation
// 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.GetPregnancyProgress()) * MAX_BREAST_INCREMENT;
+ float pregnancySize = Mathf.InverseLerp(BREAST_GROWTH_START, BREAST_GROWTH_END, parent.pawn.GetFarthestPregnancyProgress()) * MAX_BREAST_INCREMENT;
if (breastSizeIncreased > pregnancySize)
{
debugGrowthStatus = "Shrinking due to being oversize for pregnancy";
@@ -396,9 +393,9 @@ namespace RJW_Menstruation
{
return "Increase: " + breastSizeIncreased +
"\n" + debugGrowthStatus +
- "\nAlpha: " + alpha +
- "\nNippleSize: " + nippleSize +
- "\nAreolaSize: " + areolaSize +
+ "\nAlpha: " + alpha +
+ "\nNippleSize: " + nippleSize +
+ "\nAreolaSize: " + areolaSize +
"\nAlphaCurrent: " + alphaCurrent +
"\nNippleSizeCurrent: " + nippleSizeCurrent +
"\nAreolaSizeCurrent: " + areolaSizeCurrent +
@@ -408,7 +405,7 @@ namespace RJW_Menstruation
"\nAlphaMax: " + MaxAlpha +
"\nNippleSizeMax: " + MaxNipple +
"\nAreolaSizeMax: " + MaxAreola +
- "\nPermanentAlpha:" + alphaPermanent +
+ "\nPermanentAlpha:" + alphaPermanent +
"\nPermanentNipple:" + nippleSizePermanent +
"\nPermanentAreola:" + areolaSizePermanent;
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs
index b457176..91be3e1 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs
@@ -1,10 +1,4 @@
-using HugsLib;
-using RimWorld;
-using rjw;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using UnityEngine;
+using RimWorld;
using Verse;
namespace RJW_Menstruation
@@ -36,60 +30,33 @@ namespace RJW_Menstruation
}
}
- protected override void FollicularAction()
+ // The maximum theoretical rate of ovulation is inducing the moment it goes follicular and no pregnancies
+ // There will be far more eggs than will ever actually be produced, but it fits the induced ovulator philosophy
+ protected override float RaceCyclesPerYear()
{
- if (!IsBreedingSeason())
- {
- GoNextStage(Stage.Anestrus);
- return;
- }
- if (curStageHrs >= FollicularIntervalHours)
- {
- estrusflag = false;
- lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor);
- GoNextStage(Stage.Luteal);
- }
+ int breedingSeasons = 0;
+ if (Props.breedingSeason == SeasonalBreed.Always) breedingSeasons = 4;
else
{
- curStageHrs += Configurations.CycleAcceleration;
- if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24)
- {
- estrusflag = true;
- SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation);
- }
- StayCurrentStage();
+ if ((Props.breedingSeason & SeasonalBreed.Spring) != 0) breedingSeasons++;
+ if ((Props.breedingSeason & SeasonalBreed.Summer) != 0) breedingSeasons++;
+ if ((Props.breedingSeason & SeasonalBreed.Fall) != 0) breedingSeasons++;
+ if ((Props.breedingSeason & SeasonalBreed.Winter) != 0) breedingSeasons++;
}
+ float breedingRatio = breedingSeasons / 4.0f;
+ return breedingRatio * GenDate.DaysPerYear / ((float)(Props.lutealIntervalDays + Props.bleedingIntervalDays) / Configurations.CycleAccelerationDefault);
}
- protected override void ClimactericFollicularAction()
+ // There's really no good way to estimate the number of times it's been induced, so this is all we can do
+ protected override int PawnEggsUsed(float pawnCyclesElapsed, float avglittersize)
{
- if (!Configurations.EnableMenopause)
- {
- RemoveClimactericEffect();
- StayCurrentStage();
- }
- else if (curStageHrs >= (follicularIntervalhours - bleedingIntervalhours) * CycleFactor)
- {
- estrusflag = false;
- lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor);
- GoNextStage(Stage.ClimactericLuteal);
- }
- else if (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.2f) // Might randomly skip to luteal early)
- {
- estrusflag = false;
- lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6);
- GoNextStage(Stage.ClimactericLuteal);
- }
- else
- {
- curStageHrs += Configurations.CycleAcceleration;
- if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24)
- {
- estrusflag = true;
- SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation);
- }
- StayCurrentStage();
- }
+ return 0;
+ }
+
+ protected override void GoOvulatoryStage(bool climacteric)
+ {
+ estrusflag = false;
+ GoNextStage(climacteric ? Stage.ClimactericLuteal : Stage.Luteal);
}
protected override void AfterCumIn(Pawn cummer)
@@ -99,7 +66,7 @@ namespace RJW_Menstruation
{
case Stage.Follicular:
case Stage.ClimactericFollicular:
- curStage = Stage.Ovulatory;
+ GoNextStage(Stage.Ovulatory);
break;
}
}
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 9fb5bfb..a4e75af 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
@@ -27,8 +27,7 @@ namespace RJW_Menstruation
public float maxCumCapacity; // ml
public float baseImplantationChanceFactor;
public float basefertilizationChanceFactor;
- public float deviationFactor;
- public int folicularIntervalDays = 14; //before ovulation including beginning of bleeding
+ public int follicularIntervalDays = 14; //before ovulation including beginning of bleeding
public int lutealIntervalDays = 14; //after ovulation until bleeding
public int bleedingIntervalDays = 6; //must be less than folicularIntervalDays
public int recoveryIntervalDays = 10; //additional infertile days after gave birth
@@ -36,7 +35,6 @@ namespace RJW_Menstruation
public string wombTex = "Womb/Womb"; //fertiledays = ovaluationday - spermlifespan ~ ovaluationday + egglifespanday
public string vagTex = "Genitals/Vagina"; //fertiledays = ovaluationday - spermlifespan ~ ovaluationday + egglifespanday
public bool infertile = false;
- public int ovaryPower = 600000000; // default: almost unlimited ovulation
public bool concealedEstrus = false;
public SeasonalBreed breedingSeason = SeasonalBreed.Always;
public int estrusDaysBeforeOvulation = 3;
@@ -65,7 +63,10 @@ namespace RJW_Menstruation
const float minmakefilthvalue = 1.0f;
//const int ovarypowerthreshold = 72;
- public const int tickInterval = GenDate.TicksPerHour;
+ const int tickInterval = GenDate.TicksPerHour;
+ const int maxImplantDelayHours = 30 * 24;
+ const int minImplantAgeHours = 3 * 24;
+
public CompProperties_Menstruation Props;
public Stage curStage = Stage.Follicular;
public int curStageHrs = 0;
@@ -81,7 +82,6 @@ namespace RJW_Menstruation
Ovulatory,
Luteal,
Bleeding,
- Fertilized, //Obsoleted
Pregnant,
Recover,
None,
@@ -107,11 +107,9 @@ namespace RJW_Menstruation
protected List cums;
protected List eggs;
- protected int follicularIntervalhours = -1;
- protected int lutealIntervalhours = -1;
- protected int bleedingIntervalhours = -1;
- protected int recoveryIntervalhours = -1;
- protected int currentIntervalhours = -1;
+ protected float cycleSpeed = -1;
+ protected float cycleVariability = -1;
+ protected int currentIntervalHours = -1;
protected float crampPain = -1;
protected Need sexNeed = null;
protected string customwombtex = null;
@@ -121,6 +119,21 @@ namespace RJW_Menstruation
protected HediffComp_Breast breastcache = null;
protected float antisperm = 0.0f;
protected float? originvagsize = null;
+ protected Hediff_BasePregnancy pregnancy = null;
+
+ public Hediff_BasePregnancy Pregnancy {
+ get
+ {
+ if (pregnancy == null) return null;
+ else if (!parent.pawn.health.hediffSet.hediffs.Contains(pregnancy))
+ {
+ pregnancy = null;
+ return null;
+ }
+ else return pregnancy;
+ }
+ set => pregnancy = value;
+ }
public int OvaryPowerThreshold
{
@@ -131,51 +144,28 @@ namespace RJW_Menstruation
}
}
- public int FollicularIntervalHours
- {
- get
- {
- return (int)((follicularIntervalhours - bleedingIntervalhours) * CycleFactor);
- }
- }
-
public float TotalCum
{
get
{
- float res = 0;
if (cums.NullOrEmpty()) return 0;
- foreach (Cum cum in cums)
- {
- res += cum.Volume;
- }
- return res;
+ return cums.Sum(cum => cum.Volume);
}
}
public float TotalFertCum
{
get
{
- float res = 0;
if (cums.NullOrEmpty()) return 0;
- foreach (Cum cum in cums)
- {
- if (!cum.notcum) res += cum.FertVolume;
- }
- return res;
+ return cums.Sum(cum => cum.FertVolume);
}
}
public float TotalCumPercent
{
get
{
- float res = 0;
if (cums.NullOrEmpty()) return 0;
- foreach (Cum cum in cums)
- {
- res += cum.Volume;
- }
- return res / Props.maxCumCapacity;
+ return cums.Sum(cum => cum.Volume) / Props.maxCumCapacity;
}
}
public float CumCapacity
@@ -183,16 +173,7 @@ namespace RJW_Menstruation
get
{
float res = Props.maxCumCapacity * parent.pawn.BodySize;
- if (curStage != Stage.Pregnant || (parent.pawn.GetRJWPregnancy()?.Severity ?? 0f) < 0.175f) res *= 500f;
- return res;
- }
- }
- public float CumInFactor
- {
- get
- {
- float res = 1.0f;
- if (parent.pawn.health.hediffSet.HasHediff(VariousDefOf.RJW_IUD)) res = 0.01f;
+ if (curStage != Stage.Pregnant || (pregnancy?.Severity ?? 0f) < 0.175f) res *= 500f;
return res;
}
}
@@ -220,12 +201,12 @@ namespace RJW_Menstruation
{
get
{
- if (!cums.NullOrEmpty()) foreach (Cum cum in cums)
+ if (cums.NullOrEmpty()) yield return Translations.Info_noCum;
+ else foreach (Cum cum in cums)
{
if (!cum.notcum) yield return String.Format(cum.pawn?.Label + ": {0:0.##}ml", cum.Volume);
else yield return String.Format(cum.notcumLabel + ": {0:0.##}ml", cum.Volume);
}
- else yield return Translations.Info_noCum;
}
}
public Color GetCumMixtureColor
@@ -234,16 +215,15 @@ namespace RJW_Menstruation
{
Color mixedcolor = Color.white;
- if (!cums.NullOrEmpty())
+ if (cums.NullOrEmpty()) return mixedcolor;
+
+ float mixedsofar = 0;
+ foreach (Cum cum in cums)
{
- float mixedsofar = 0;
- foreach (Cum cum in cums)
+ if (cum.Volume > 0)
{
- if (cum.Volume > 0)
- {
- mixedcolor = Colors.CMYKLerp(mixedcolor, cum.Color, cum.Volume / (mixedsofar + cum.Volume));
- mixedsofar += cum.Volume;
- }
+ mixedcolor = Colors.CMYKLerp(mixedcolor, cum.Color, cum.Volume / (mixedsofar + cum.Volume));
+ mixedsofar += cum.Volume;
}
}
return mixedcolor;
@@ -256,7 +236,7 @@ namespace RJW_Menstruation
{
if (curStage == Stage.Pregnant)
{
- if (Configurations.InfoDetail == Configurations.DetailLevel.All || (PregnancyHelper.GetPregnancy(parent.pawn)?.Visible ?? false))
+ if (Configurations.InfoDetail == Configurations.DetailLevel.All || (pregnancy?.Visible ?? false))
return Stage.Pregnant;
else
return Stage.Luteal;
@@ -279,8 +259,6 @@ namespace RJW_Menstruation
return Translations.Stage_Luteal;
case Stage.Bleeding:
return Translations.Stage_Bleeding;
- case Stage.Fertilized:
- return Translations.Stage_Fertilized;
case Stage.Pregnant:
return Translations.Stage_Pregnant;
case Stage.Recover:
@@ -304,7 +282,7 @@ namespace RJW_Menstruation
}
public virtual string GetCurStageDesc
{
- get
+ get
{
switch (CurrentVisibleStage)
{
@@ -316,14 +294,12 @@ namespace RJW_Menstruation
return Translations.Stage_Luteal_Desc;
case Stage.Bleeding:
return Translations.Stage_Bleeding_Desc;
- case Stage.Fertilized:
- return Translations.Stage_Luteal_Desc;
case Stage.Pregnant:
return Translations.Stage_Pregnant_Desc;
case Stage.Recover:
return Translations.Stage_Recover_Desc;
case Stage.None:
- case Stage.Young:
+ case Stage.Young:
return Translations.Stage_None_Desc;
case Stage.ClimactericFollicular:
return Translations.Stage_Follicular_Desc + " " + Translations.Stage_Climacteric_Desc;
@@ -367,24 +343,23 @@ namespace RJW_Menstruation
{
get
{
+ if (eggs.NullOrEmpty()) return "";
+
string res = "";
- if (!eggs.NullOrEmpty())
+ int fertilized = 0;
+ foreach (Egg egg in eggs)
{
- int fertilized = 0;
- foreach (Egg egg in eggs)
- {
- if (egg.fertilized) fertilized++;
- }
- if (fertilized != 0) res += fertilized + " " + Translations.Dialog_WombInfo05;
- if (fertilized != 0 && eggs.Count - fertilized != 0) res += ", ";
- if (cums.NullOrEmpty() || TotalFertCum == 0)
- {
- if (eggs.Count - fertilized != 0) res += eggs.Count - fertilized + " " + Translations.Dialog_WombInfo07;
- }
- else
- {
- if (eggs.Count - fertilized != 0) res += eggs.Count - fertilized + " " + Translations.Dialog_WombInfo06;
- }
+ if (egg.fertilized) fertilized++;
+ }
+ if (fertilized != 0) res += fertilized + " " + Translations.Dialog_WombInfo05;
+ if (fertilized != 0 && eggs.Count - fertilized != 0) res += ", ";
+ if (cums.NullOrEmpty() || TotalFertCum == 0)
+ {
+ if (eggs.Count - fertilized != 0) res += eggs.Count - fertilized + " " + Translations.Dialog_WombInfo07;
+ }
+ else
+ {
+ if (eggs.Count - fertilized != 0) res += eggs.Count - fertilized + " " + Translations.Dialog_WombInfo06;
}
return res;
}
@@ -393,16 +368,8 @@ namespace RJW_Menstruation
{
get
{
- if (!eggs.NullOrEmpty())
- {
- if (!cums.NullOrEmpty()) foreach (Cum cum in cums)
- {
- if (cum.FertVolume > 0) return true;
- }
- return false;
-
- }
- else return false;
+ if (eggs.NullOrEmpty() || cums.NullOrEmpty()) return false;
+ return cums.Any(cum => cum.FertVolume > 0);
}
}
///
@@ -445,7 +412,7 @@ namespace RJW_Menstruation
{
case Stage.Follicular:
case Stage.ClimactericFollicular:
- return curStageHrs > 0.7f * (follicularIntervalhours - bleedingIntervalhours);
+ return curStageHrs > 0.7f * currentIntervalHours;
case Stage.Ovulatory:
return true;
case Stage.Luteal:
@@ -512,24 +479,7 @@ namespace RJW_Menstruation
{
get
{
- switch (curStage)
- {
- case Stage.Follicular:
- case Stage.ClimactericFollicular:
- return FollicularIntervalHours;
- case Stage.Luteal:
- case Stage.ClimactericLuteal:
- return lutealIntervalhours;
- case Stage.Bleeding:
- case Stage.ClimactericBleeding:
- return bleedingIntervalhours;
- case Stage.Recover:
- return recoveryIntervalhours;
- case Stage.Pregnant:
- return currentIntervalhours;
- default:
- return float.PositiveInfinity;
- }
+ return currentIntervalHours;
}
}
@@ -557,17 +507,16 @@ namespace RJW_Menstruation
Scribe_Collections.Look(ref eggs, saveDestroyedThings: true, label: "eggs", lookMode: LookMode.Deep, ctorArgs: new object[0]);
Scribe_Values.Look(ref curStage, "curStage", curStage, true);
Scribe_Values.Look(ref curStageHrs, "curStageHrs", curStageHrs, true);
- Scribe_Values.Look(ref follicularIntervalhours, "follicularIntervalhours", follicularIntervalhours, true);
- Scribe_Values.Look(ref lutealIntervalhours, "lutealIntervalhours", lutealIntervalhours, true);
- Scribe_Values.Look(ref bleedingIntervalhours, "bleedingIntervalhours", bleedingIntervalhours, true);
- Scribe_Values.Look(ref recoveryIntervalhours, "recoveryIntervalhours", recoveryIntervalhours, true);
- Scribe_Values.Look(ref currentIntervalhours, "currentIntervalhours", currentIntervalhours, true);
+ Scribe_Values.Look(ref cycleSpeed, "cycleSpeed", cycleSpeed, true);
+ Scribe_Values.Look(ref cycleVariability, "cycleVariability", cycleVariability, true);
+ Scribe_Values.Look(ref currentIntervalHours, "currentIntervalHours", currentIntervalHours, true);
Scribe_Values.Look(ref crampPain, "crampPain", crampPain, true);
Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true);
Scribe_Values.Look(ref eggstack, "eggstack", eggstack, true);
Scribe_Values.Look(ref estrusflag, "estrusflag", estrusflag, true);
Scribe_Values.Look(ref originvagsize, "originvagsize", originvagsize, true);
Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", DoCleanWomb, true);
+ Scribe_References.Look(ref pregnancy, "pregnancy");
}
@@ -590,22 +539,19 @@ namespace RJW_Menstruation
public override void CompPostPostRemoved()
{
- if (parent?.pawn?.GetMenstruationComp() == this)
+ // If a hediff is removed from a pawn that does not have it, CompPostPostRemoved is still called on the pawn that does.
+ // If it was a legitimate removal, then it won't be in this pawn's hediff list anymore, as that removal occurs first
+ if (parent.pawn.health.hediffSet.hediffs.Contains(parent))
{
- Log.Warning("Something tried to remove hediff with wrong way.");
- }
- else
- {
- HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(actionref);
- Log.Message(parent.pawn.Label + "tick scheduler removed");
- base.CompPostPostRemoved();
+ 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();
}
-
-
-
-
///
/// Get fluid in womb that not a cum
///
@@ -627,24 +573,21 @@ namespace RJW_Menstruation
///
public Cum GetCum(Pawn pawn)
{
- if (!cums.NullOrEmpty()) foreach (Cum cum in cums)
- {
- if (!cum.notcum && cum.pawn.Equals(pawn)) return cum;
- }
- return null;
+ if (cums.NullOrEmpty()) return null;
+ return cums.Find(cum => !cum.notcum && cum.pawn == pawn);
}
///
/// Inject pawn's cum into womb
///
///
- ///
+ ///
///
///
- public void CumIn(Pawn pawn, float injectedvolume, float fertility = 1.0f, ThingDef filthdef = null)
+ public void CumIn(Pawn pawn, float volume, float fertility = 1.0f, ThingDef filthdef = null)
{
- float volume = injectedvolume * CumInFactor;
if (volume <= 0) return;
+ if (parent.pawn.health.hediffSet.HasHediff(VariousDefOf.RJW_IUD)) fertility /= 100f;
float cumd = TotalCumPercent;
float tmp = TotalCum + volume;
if (tmp > CumCapacity)
@@ -678,7 +621,7 @@ namespace RJW_Menstruation
}
cumd = TotalCumPercent - cumd;
- parent.pawn.records.AddTo(VariousDefOf.AmountofCreampied, injectedvolume);
+ parent.pawn.records.AddTo(VariousDefOf.AmountofCreampied, volume);
AfterCumIn(pawn);
AfterFluidIn(cumd);
}
@@ -733,7 +676,7 @@ namespace RJW_Menstruation
protected virtual void AfterCumIn(Pawn cummer)
{
ThoughtCumInside(cummer);
-
+ TaleCumInside(cummer);
}
protected virtual void AfterNotCumIn()
@@ -868,7 +811,7 @@ namespace RJW_Menstruation
///
///
///
- public CumMixture MixtureOut(ThingDef mixtureDef ,float portion = 0.1f)
+ public CumMixture MixtureOut(ThingDef mixtureDef, float portion = 0.1f)
{
if (cums.NullOrEmpty()) return null;
Color color = GetCumMixtureColor;
@@ -902,121 +845,135 @@ namespace RJW_Menstruation
cums.Clear();
}
-
+
///
/// Fertilize eggs and return the result
///
///
- protected bool FertilizationCheck()
+ protected void FertilizationCheck()
{
- if (!eggs.NullOrEmpty())
+ if (eggs.NullOrEmpty()) return;
+ foreach (Egg egg in eggs)
{
- bool onefertilized = false;
- foreach (Egg egg in eggs)
+ if (!egg.fertilized) egg.fertilizer = Fertilize();
+ if (egg.fertilizer != null)
{
- if (!egg.fertilized) egg.fertilizer = Fertilize();
- if (egg.fertilizer != null)
- {
- egg.fertilized = true;
- egg.lifespanhrs += 240;
- onefertilized = true;
- }
+ egg.fertilized = true;
}
- return onefertilized;
}
- else return false;
}
public void Initialize()
{
Props = (CompProperties_Menstruation)props;
- if (!Props.infertile)
- {
- if (follicularIntervalhours < 0)
- {
- follicularIntervalhours = PeriodRandomizer(Props.folicularIntervalDays * 24, Props.deviationFactor);
- if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) curStage = Stage.Young;
- else if (!IsBreedingSeason()) curStage = Stage.Anestrus;
- else curStage = RandomStage();
- }
-
- if (lutealIntervalhours < 0) lutealIntervalhours = PeriodRandomizer(Props.lutealIntervalDays * 24, Props.deviationFactor);
- if (bleedingIntervalhours < 0) bleedingIntervalhours = PeriodRandomizer(Props.bleedingIntervalDays * 24, Props.deviationFactor);
- if (recoveryIntervalhours < 0) recoveryIntervalhours = PeriodRandomizer(Props.recoveryIntervalDays * 24, Props.deviationFactor);
- if (crampPain < 0) crampPain = PainRandomizer();
- if (cums == null) cums = new List();
- if (eggs == null) eggs = new List();
-
-
- InitOvary();
-
- Hediff_BasePregnancy pregnancy = parent.pawn.GetRJWPregnancy();
- if (pregnancy != null)
- {
- Hediff hediff = PregnancyHelper.GetPregnancy(parent.pawn);
- if (hediff != null)
- {
- if (hediff is Hediff_BasePregnancy preg)
- {
- currentIntervalhours = (int)(preg.GestationHours());
- curStage = Stage.Pregnant;
- }
- }
- }
-
- 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);
- }
- }
- else
+ if (Props.infertile)
{
if (cums == null) cums = new List();
curStage = Stage.None;
HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(curStage), GetNextUpdate(), parent.pawn, false);
+ loaded = true;
+ return;
+ }
+
+ if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f);
+ if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent();
+ if (currentIntervalHours < 0)
+ {
+ if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) curStage = Stage.Young;
+ else if (!IsBreedingSeason()) curStage = Stage.Anestrus;
+ else curStage = RandomStage();
+ if (curStage == Stage.Follicular)
+ currentIntervalHours = PeriodRandomizer(Stage.Follicular) - PeriodRandomizer(Stage.Bleeding);
+ else
+ currentIntervalHours = PeriodRandomizer(curStage);
+ if (currentIntervalHours <= 0) currentIntervalHours = 1;
+ else if (currentIntervalHours < curStageHrs) curStageHrs = currentIntervalHours;
+ }
+ if (crampPain < 0) crampPain = PainRandomizer();
+ if (cums == null) cums = new List();
+ if (eggs == null) eggs = new List();
+
+
+ InitOvary();
+
+ if (pregnancy == null)
+ {
+ // If this womb isn't marked pregnant, search for pregnancies that have no womb and claim one
+ foreach (Hediff_BasePregnancy preg in parent.pawn.health.hediffSet.GetHediffs())
+ {
+ if (preg.GetMenstruationComp() == null)
+ {
+ currentIntervalHours = (int)preg.GestationHours();
+ curStage = Stage.Pregnant;
+ pregnancy = preg;
+ break;
+ }
+ }
+ }
+
+ 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;
}
- public int GetOvaryPowerByAge(Pawn pawn)
+ protected virtual float RaceCyclesPerYear()
{
- int power;
+ int breedingSeasons = 0;
+ if (Props.breedingSeason == SeasonalBreed.Always) breedingSeasons = 4;
+ else
+ {
+ if ((Props.breedingSeason & SeasonalBreed.Spring) != 0) breedingSeasons++;
+ if ((Props.breedingSeason & SeasonalBreed.Summer) != 0) breedingSeasons++;
+ if ((Props.breedingSeason & SeasonalBreed.Fall) != 0) breedingSeasons++;
+ if ((Props.breedingSeason & SeasonalBreed.Winter) != 0) breedingSeasons++;
+ }
+ float breedingRatio = breedingSeasons / 4.0f;
+ return breedingRatio * GenDate.DaysPerYear / ((float)(Props.follicularIntervalDays + Props.lutealIntervalDays) / Configurations.CycleAccelerationDefault);
+ }
+
+ protected virtual int PawnEggsUsed(float pawnCyclesElapsed, float avglittersize)
+ {
+ return (int)(pawnCyclesElapsed * avglittersize);
+ }
+
+ public int GetOvaryPowerByAge()
+ {
+ Pawn pawn = parent.pawn;
float avglittersize;
try
{
- if (pawn.def.race.litterSizeCurve.Points.Count < 3) avglittersize = 1; // Account for busted littersizecurves
- else avglittersize = Rand.ByCurveAverage(pawn.def.race.litterSizeCurve);
+ avglittersize = Mathf.Max(Rand.ByCurveAverage(pawn.def.race.litterSizeCurve), 1.0f);
}
catch (NullReferenceException)
{
- avglittersize = 1;
+ avglittersize = 1.0f;
}
- //Old one. Sex minimum age based.
- //ovarypower = (int)(((Props.ovaryPower * Utility.RandGaussianLike(0.70f, 1.30f) * parent.pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy)
- // - (Math.Max(0, ageYear - RJWSettings.sex_minimum_age * parent.pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy))
- // * (60 / (Props.folicularIntervalDays + Props.lutealIntervalDays) * Configurations.CycleAcceleration)) * avglittersize);
+ float fertStartAge = pawn.RaceProps.lifeStageAges?.Find(stage => stage.def.reproductive)?.minAge ?? 0.0f;
+ float fertEndAge = pawn.RaceProps.lifeExpectancy * (pawn.IsAnimal() ? RJWPregnancySettings.fertility_endage_female_animal : RJWPregnancySettings.fertility_endage_female_humanlike);
+ if (fertEndAge < fertStartAge) fertEndAge = fertStartAge;
- //New one.
- float fertendage, lifenormalized;
- if (pawn.IsAnimal()) fertendage = RJWPregnancySettings.fertility_endage_female_animal * 100f;
- else fertendage = RJWPregnancySettings.fertility_endage_female_humanlike * 80f;
- lifenormalized = pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy;
- fertendage *= lifenormalized;
- power = (int)((fertendage - pawn.ageTracker.AgeBiologicalYearsFloat) * (60f / (Props.folicularIntervalDays + Props.lutealIntervalDays) * Configurations.CycleAcceleration) * avglittersize);
- power = (int)Mathf.Max(0, Mathf.Min(Props.ovaryPower * Utility.RandGaussianLike(0.70f, 1.30f, 5) * lifenormalized, power));
+ float raceCyclesPerYear = RaceCyclesPerYear();
+ int lifetimeCycles = (int)(raceCyclesPerYear * (fertEndAge - fertStartAge));
+ int lifetimeEggs = (int)(lifetimeCycles * avglittersize * Utility.RandGaussianLike(0.70f, 1.30f, 5));
- return power;
+ float pawnCyclesPerYear = raceCyclesPerYear * cycleSpeed;
+ float pawnCyclesElapsed = Mathf.Max((pawn.ageTracker.AgeBiologicalYearsFloat - fertStartAge) * pawnCyclesPerYear, 0.0f);
+ int pawnEggsUsed = PawnEggsUsed(pawnCyclesElapsed, avglittersize);
+
+ return Math.Max(lifetimeEggs - pawnEggsUsed, 0);
}
protected void InitOvary()
@@ -1027,24 +984,19 @@ namespace RJW_Menstruation
}
else if (ovarypower < -50000)
{
- if (Props.ovaryPower > 10000000) ovarypower = Props.ovaryPower;
- else
+ ovarypower = GetOvaryPowerByAge();
+ if (ovarypower < 1)
{
- ovarypower = GetOvaryPowerByAge(parent.pawn);
- if (ovarypower < 1)
- {
- Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Menopause, parent.pawn);
- hediff.Severity = 0.2f;
- parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
- curStage = Stage.Young;
- }
- else if (ovarypower < OvaryPowerThreshold)
- {
- Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn);
- hediff.Severity = 0.008f * (OvaryPowerThreshold - ovarypower);
- parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
- }
-
+ Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Menopause, parent.pawn);
+ hediff.Severity = 0.2f;
+ parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
+ curStage = Stage.Young;
+ }
+ else if (ovarypower < OvaryPowerThreshold)
+ {
+ Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn);
+ hediff.Severity = 0.008f * (OvaryPowerThreshold - ovarypower);
+ parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
}
}
}
@@ -1074,14 +1026,25 @@ namespace RJW_Menstruation
public void SetEstrus(int days)
{
HediffDef estrusdef = Props.concealedEstrus ? VariousDefOf.Hediff_Estrus_Concealed : VariousDefOf.Hediff_Estrus;
- HediffWithComps hediff = (HediffWithComps)parent.pawn.health.hediffSet.GetFirstHediffOfDef(estrusdef);
+ Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(estrusdef);
+
+ if (Props.concealedEstrus)
+ {
+ if (parent.pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Estrus)) return;
+ }
+ else
+ {
+ Hediff concealedHediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_Estrus_Concealed);
+ if (concealedHediff != null) parent.pawn.health.RemoveHediff(concealedHediff);
+ }
+
if (hediff != null)
{
hediff.Severity = (float)days / Configurations.CycleAcceleration + 0.2f;
}
else
{
- hediff = (HediffWithComps)HediffMaker.MakeHediff(estrusdef, parent.pawn);
+ hediff = HediffMaker.MakeHediff(estrusdef, parent.pawn);
hediff.Severity = (float)days / Configurations.CycleAcceleration + 0.2f;
parent.pawn.health.AddHediff(hediff);
}
@@ -1091,8 +1054,8 @@ namespace RJW_Menstruation
{
if (Props.breedingSeason == SeasonalBreed.Always) return true;
Map map = parent.pawn.Map;
- if (map is null) map = Find.AnyPlayerHomeMap;
- if (map is null) return true;
+ if (map == null) map = Find.AnyPlayerHomeMap;
+ if (map == null) return true;
switch (GenLocalDate.Season(map))
{
case Season.Spring:
@@ -1116,11 +1079,9 @@ namespace RJW_Menstruation
List eligibleCum = cums.FindAll(cum => !cum.notcum && cum.FertVolume > 0 && cum.pawn != null && (RJWPregnancySettings.bestial_pregnancy_enabled || xxx.is_animal(parent.pawn) == xxx.is_animal(cum.pawn)));
if (eligibleCum.Count == 0) return null;
- float totalFertPower = 0;
- foreach (Cum cum in eligibleCum)
- totalFertPower += cum.FertVolume;
-
- if (Rand.Range(0.0f, 1.0f) > totalFertPower * Configurations.FertilizeChance * Props.basefertilizationChanceFactor)
+ float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume);
+
+ if (Rand.Range(0.0f, 1.0f) > 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor))
return null;
parent.pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1);
@@ -1133,101 +1094,90 @@ namespace RJW_Menstruation
}
// We shouldn't reach here, but floating point errors exist, so just to be sure, select whomever came the most
-
- float mostCum = 0;
- Pawn mostCummer = null;
-
- foreach (Cum cum in eligibleCum)
- {
- if(cum.FertVolume > mostCum)
- {
- mostCum = cum.FertVolume;
- mostCummer = cum.pawn;
- }
- }
-
- return mostCummer;
+ return eligibleCum.MaxBy(cum => cum.FertVolume).pawn;
}
-
+
protected bool Implant()
{
- if (!eggs.NullOrEmpty())
+ if (eggs.NullOrEmpty()) return false;
+
+ List deadeggs = new List();
+ bool pregnant = false;
+ foreach (Egg egg in eggs)
{
- List deadeggs = new List();
- bool pregnant = false;
- foreach (Egg egg in eggs)
+ if (!egg.fertilized ||
+ egg.fertstage < minImplantAgeHours ||
+ egg.position < Math.Min(Props.lutealIntervalDays * 24 / 2, maxImplantDelayHours))
+ continue;
+ else if (egg.fertilizer == null)
{
- if (!egg.fertilized || egg.fertstage < 168) continue;
- else if (egg.fertilizer is null)
+ deadeggs.Add(egg);
+ continue;
+ }
+ else if (parent.pawn.health.hediffSet.GetHediffs().Any() || pregnancy is Hediff_MechanoidPregnancy)
+ {
+ deadeggs.Add(egg);
+ continue;
+ }
+ else if (Rand.Range(0.0f, 1.0f) <= Configurations.ImplantationChance * ImplantFactor * InterspeciesImplantFactor(egg.fertilizer))
+ {
+ if (pregnancy != null)
{
- deadeggs.Add(egg);
- continue;
- }
- else if (Rand.Range(0.0f, 1.0f) <= Configurations.ImplantationChance * ImplantFactor * InterspeciesImplantFactor(egg.fertilizer))
- {
- Hediff_BasePregnancy pregnancy = parent.pawn.GetRJWPregnancy();
- if (pregnancy != null)
+ if (Configurations.UseMultiplePregnancy && Configurations.EnableHeteroOvularTwins)
{
- if (Configurations.UseMultiplePregnancy && Configurations.EnableHeteroOvularTwins)
+ if (pregnancy is Hediff_MultiplePregnancy h)
{
- if (pregnancy is Hediff_MultiplePregnancy h)
- {
- h.AddNewBaby(parent.pawn, egg.fertilizer);
- }
- pregnant = true;
- deadeggs.Add(egg);
+ h.AddNewBaby(parent.pawn, egg.fertilizer);
}
- else
- {
- pregnant = true;
- break;
- }
-
-
+ pregnant = true;
+ deadeggs.Add(egg);
}
else
{
- if (!Configurations.UseMultiplePregnancy)
- {
- PregnancyHelper.PregnancyDecider(parent.pawn, egg.fertilizer);
- Hediff_BasePregnancy hediff = (Hediff_BasePregnancy)PregnancyHelper.GetPregnancy(parent.pawn);
- currentIntervalhours = (int)hediff?.GestationHours();
- pregnant = true;
- break;
- }
- else
- {
- Hediff_BasePregnancy.Create(parent.pawn, egg.fertilizer);
- Hediff_BasePregnancy hediff = (Hediff_BasePregnancy)PregnancyHelper.GetPregnancy(parent.pawn);
- currentIntervalhours = (int)hediff?.GestationHours();
-
- pregnant = true;
- deadeggs.Add(egg);
- }
+ pregnant = true;
+ break;
}
-
}
- else deadeggs.Add(egg);
- }
-
- if (pregnant && (!Configurations.UseMultiplePregnancy || !Configurations.EnableHeteroOvularTwins))
- {
- eggs.Clear();
- deadeggs.Clear();
- return true;
- }
- else if (!deadeggs.NullOrEmpty())
- {
- foreach (Egg egg in deadeggs)
+ else
{
- eggs.Remove(egg);
+ if (!Configurations.UseMultiplePregnancy)
+ {
+ 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);
+ }
}
- deadeggs.Clear();
+
}
- if (pregnant) return true;
+ else deadeggs.Add(egg);
}
- return false;
+
+ if (pregnant && (!Configurations.UseMultiplePregnancy || !Configurations.EnableHeteroOvularTwins))
+ {
+ eggs.Clear();
+ deadeggs.Clear();
+ return true;
+ }
+ else if (!deadeggs.NullOrEmpty())
+ {
+ foreach (Egg egg in deadeggs)
+ {
+ eggs.Remove(egg);
+ }
+ deadeggs.Clear();
+ }
+ return pregnant;
}
protected void BleedOut()
@@ -1258,32 +1208,26 @@ namespace RJW_Menstruation
protected float AbsorbCum(float amount, Absorber absorber)
{
- if (absorber != null)
- {
- float absorbable = absorber.GetStatValue(VariousDefOf.MaxAbsorbable);
- absorber.SetColor(Colors.CMYKLerp(GetCumMixtureColor, absorber.DrawColor, 1f - amount / absorbable));
- if (!absorber.dirty)
- {
- absorber.absorbedfluids += amount;
- if (absorber.absorbedfluids > absorbable && !parent.pawn.apparel.IsLocked(absorber))
- {
- absorber.def = absorber.DirtyDef;
- //absorber.fluidColor = GetCumMixtureColor;
- absorber.dirty = true;
- }
- }
- else
- {
-
- //if (absorber.LeakAfterDirty) FilthMaker.TryMakeFilth(parent.pawn.Position, parent.pawn.Map, cum.FilthDef, cum.pawn.LabelShort);
- return amount;
- }
- }
- else
+ if (absorber == null)
{
//if (amount >= minmakefilthvalue) FilthMaker.TryMakeFilth(parent.pawn.Position, parent.pawn.Map, cum.FilthDef, cum.pawn.LabelShort);
return amount;
}
+
+ float absorbable = absorber.GetStatValue(VariousDefOf.MaxAbsorbable);
+ absorber.SetColor(Colors.CMYKLerp(GetCumMixtureColor, absorber.DrawColor, 1f - amount / absorbable));
+ if (absorber.dirty)
+ {
+ //if (absorber.LeakAfterDirty) FilthMaker.TryMakeFilth(parent.pawn.Position, parent.pawn.Map, cum.FilthDef, cum.pawn.LabelShort);
+ return amount;
+ }
+ absorber.absorbedfluids += amount;
+ if (absorber.absorbedfluids > absorbable && !parent.pawn.apparel.IsLocked(absorber))
+ {
+ absorber.def = absorber.DirtyDef;
+ //absorber.fluidColor = GetCumMixtureColor;
+ absorber.dirty = true;
+ }
return 0;
}
@@ -1305,10 +1249,13 @@ namespace RJW_Menstruation
List deadeggs = new List();
foreach (Egg egg in eggs)
{
- egg.lifespanhrs -= Configurations.CycleAcceleration;
egg.position += Configurations.CycleAcceleration;
- if (egg.lifespanhrs < 0) deadeggs.Add(egg);
if (egg.fertilized) egg.fertstage += Configurations.CycleAcceleration;
+ else
+ {
+ egg.lifespanhrs -= Configurations.CycleAcceleration;
+ if (egg.lifespanhrs < 0) deadeggs.Add(egg);
+ }
}
if (!deadeggs.NullOrEmpty())
{
@@ -1325,25 +1272,36 @@ namespace RJW_Menstruation
Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_MenstrualCramp, parent.pawn);
hediff.Severity = crampPain * Rand.Range(0.9f, 1.1f);
HediffCompProperties_SeverityPerDay Prop = (HediffCompProperties_SeverityPerDay)hediff.TryGetComp().props;
- Prop.severityPerDay = -hediff.Severity / (bleedingIntervalhours / 24) * Configurations.CycleAcceleration;
+ Prop.severityPerDay = -hediff.Severity / (currentIntervalHours / 24) * Configurations.CycleAcceleration;
parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
}
- protected virtual void FollicularAction()
+ protected virtual void FollicularAction(bool climacteric)
{
- if (!IsBreedingSeason())
+ if (climacteric && !Configurations.EnableMenopause)
{
+ RemoveClimactericEffect();
+ StayCurrentStage();
+ }
+ else if (!IsBreedingSeason())
+ {
+ estrusflag = false;
GoNextStage(Stage.Anestrus);
return;
}
- if (curStageHrs >= FollicularIntervalHours)
+ else if (curStageHrs >= currentIntervalHours)
{
- GoNextStage(Stage.Ovulatory);
+ GoOvulatoryStage(climacteric);
+ }
+ else if (climacteric && ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.2f) //skips ovulatory
+ {
+ estrusflag = false;
+ GoNextStage(Stage.ClimactericLuteal);
}
else
{
curStageHrs += Configurations.CycleAcceleration;
- if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24)
+ if (!estrusflag && curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24)
{
estrusflag = true;
SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation);
@@ -1359,17 +1317,18 @@ namespace RJW_Menstruation
float eggnum;
try
{
- eggnum = Rand.ByCurve(parent.pawn.RaceProps.litterSizeCurve) + eggstack;
+ eggnum = Rand.ByCurve(parent.pawn.RaceProps.litterSizeCurve);
}
- catch(NullReferenceException)
+ catch (NullReferenceException)
{
- eggnum = 1 + eggstack;
+ eggnum = 1;
}
- catch(ArgumentException e)
+ catch (ArgumentException e)
{
Log.Warning($"Invalid litterSizeCurve for {parent.pawn.RaceProps}: {e}");
- eggnum = 1 + eggstack;
+ eggnum = 1;
}
+ eggnum += eggstack;
do
{
@@ -1394,19 +1353,42 @@ namespace RJW_Menstruation
Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn);
hediff.Severity = 0.008f * i;
parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
- lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6);
GoNextStage(Stage.ClimactericLuteal);
}
else
{
- lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor);
GoNextStage(Stage.Luteal);
}
}
- protected virtual void LutealAction()
+ protected virtual void LutealAction(bool climacteric)
{
- if (!eggs.NullOrEmpty())
+ if (climacteric && !Configurations.EnableMenopause)
+ {
+ RemoveClimactericEffect();
+ StayCurrentStage();
+ }
+ else if (curStageHrs > currentIntervalHours)
+ {
+ eggs.Clear();
+ if (Props.bleedingIntervalDays == 0)
+ {
+ GoNextStage(climacteric ? Stage.ClimactericFollicular : Stage.Follicular);
+ }
+ else if (climacteric && (ovarypower < OvaryPowerThreshold / 4 || (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.3f))) //skips bleeding
+ {
+ GoNextStage(Stage.ClimactericFollicular);
+ }
+ else
+ {
+ if (crampPain >= 0.05f)
+ {
+ AddCrampPain();
+ }
+ GoNextStage(climacteric ? Stage.ClimactericBleeding : Stage.Bleeding);
+ }
+ }
+ else if (!eggs.NullOrEmpty())
{
FertilizationCheck();
EggDecay();
@@ -1424,43 +1406,37 @@ namespace RJW_Menstruation
StayCurrentStage();
}
}
- else if (curStageHrs <= lutealIntervalhours)
+ else
{
curStageHrs += Configurations.CycleAcceleration;
StayCurrentStage();
}
- else
- {
- eggs.Clear();
- if (Props.bleedingIntervalDays == 0)
- {
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
- GoNextStage(Stage.Follicular);
- }
- else
- {
- bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor);
- if (crampPain >= 0.05f)
- {
- AddCrampPain();
- }
- GoNextStage(Stage.Bleeding);
- }
- }
+
}
- protected virtual void BleedingAction()
+ protected virtual void BleedingAction(bool climacteric)
{
- if (curStageHrs >= bleedingIntervalhours)
+ if (climacteric && !Configurations.EnableMenopause)
+ {
+ RemoveClimactericEffect();
+ StayCurrentStage();
+ }
+ else if (curStageHrs >= currentIntervalHours)
{
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp);
if (hediff != null) parent.pawn.health.RemoveHediff(hediff);
- GoNextStage(Stage.Follicular);
+ int totalFollicularHours = PeriodRandomizer(climacteric ? Stage.ClimactericFollicular : Stage.Follicular, climacteric ? 6.0f : 1.0f); // The total amount of time for both bleeding and follicular
+ if (totalFollicularHours <= currentIntervalHours) // We've bled for so long that we completely missed the follicular phase
+ GoOvulatoryStage(climacteric);
+ else
+ {
+ currentIntervalHours = totalFollicularHours - currentIntervalHours; // I.e., the remaining follicular hours equals the total minus the bleeding hours elapsed
+ GoNextStage(climacteric ? Stage.ClimactericFollicular : Stage.Follicular, false);
+ }
}
else
{
- if (curStageHrs < bleedingIntervalhours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
+ if (curStageHrs < currentIntervalHours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
curStageHrs += Configurations.CycleAcceleration;
StayCurrentStage();
}
@@ -1475,24 +1451,25 @@ namespace RJW_Menstruation
Implant();
}
- if (parent.pawn.GetRJWPregnancy() != null)
+ if (parent.pawn.health.hediffSet.hediffs.Contains(pregnancy))
{
curStageHrs += 1;
StayCurrentStageConst(Stage.Pregnant);
}
else
{
+ if (pregnancy != null) pregnancy = null;
if (Breast != null)
{
Breast.BirthTransition();
}
GoNextStage(Stage.Recover);
- }
+ }
}
protected virtual void RecoverAction()
{
- if (curStageHrs >= recoveryIntervalhours)
+ if (curStageHrs >= currentIntervalHours)
{
if (Configurations.EnableMenopause && ovarypower < OvaryPowerThreshold)
{
@@ -1504,7 +1481,6 @@ namespace RJW_Menstruation
}
else
{
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
GoNextStage(Stage.Follicular);
}
}
@@ -1525,97 +1501,10 @@ namespace RJW_Menstruation
{
StayCurrentStageConst(Stage.Young);
}
- else GoNextStage(IsBreedingSeason() ? Stage.Follicular : Stage.Anestrus);
- }
-
- protected virtual void ClimactericFollicularAction()
- {
- if (!Configurations.EnableMenopause)
- {
- RemoveClimactericEffect();
- StayCurrentStage();
- }
- else if (curStageHrs >= (follicularIntervalhours - bleedingIntervalhours) * CycleFactor)
- {
- GoNextStage(Stage.Ovulatory);
- }
- else if (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.2f) //skips ovulatory
- {
- lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6);
- GoNextStage(Stage.ClimactericLuteal);
- }
else
{
- curStageHrs += Configurations.CycleAcceleration;
- StayCurrentStage();
- }
- }
-
- protected virtual void ClimactericLutealAction()
- {
- if (!Configurations.EnableMenopause)
- {
- RemoveClimactericEffect();
- StayCurrentStage();
- }
- else if (!eggs.NullOrEmpty())
- {
- FertilizationCheck();
- EggDecay();
- if (Implant()) GoNextStage(Stage.Pregnant);
- else
- {
- curStageHrs += Configurations.CycleAcceleration;
- StayCurrentStage();
- }
- }
- else if (curStageHrs <= lutealIntervalhours)
- {
- curStageHrs += Configurations.CycleAcceleration;
- StayCurrentStage();
- }
- else
- {
- eggs.Clear();
- if (Props.bleedingIntervalDays == 0)
- {
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor * 6);
- GoNextStage(Stage.ClimactericFollicular);
- }
- else if (ovarypower < OvaryPowerThreshold / 4 || (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.3f)) //skips bleeding
- {
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor * 6);
- GoNextStage(Stage.ClimactericFollicular);
- }
- else
- {
- bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor);
- if (crampPain >= 0.05f)
- {
- AddCrampPain();
- }
- GoNextStage(Stage.ClimactericBleeding);
- }
- }
- }
-
- protected virtual void ClimactericBleedingAction()
- {
- if (!Configurations.EnableMenopause)
- {
- RemoveClimactericEffect();
- StayCurrentStage();
- }
- else if (curStageHrs >= bleedingIntervalhours)
- {
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor * 6);
- GoNextStage(Stage.ClimactericFollicular);
- }
- else
- {
- if (curStageHrs < bleedingIntervalhours / 6) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
- curStageHrs += Configurations.CycleAcceleration;
- StayCurrentStage();
+ bool breedingSeason = IsBreedingSeason();
+ GoNextStage(breedingSeason ? Stage.Follicular : Stage.Anestrus, breedingSeason);
}
}
@@ -1633,60 +1522,67 @@ namespace RJW_Menstruation
protected virtual void ThoughtCumInside(Pawn cummer)
{
- if (xxx.is_human(parent.pawn) && xxx.is_human(cummer))
- {
- if ((cummer.Has(Quirk.Teratophile) != (parent.pawn.GetStatValue(StatDefOf.PawnBeauty) >= 0)) ||
- cummer.Has(Quirk.ImpregnationFetish) ||
- cummer.Has(Quirk.Breeder))
- {
- if (cummer.relations.OpinionOf(parent.pawn) <= -25)
- {
- cummer.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideM, parent.pawn);
- }
- else
- {
- cummer.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideM, parent.pawn);
- }
- }
+ if (!xxx.is_human(parent.pawn) || !xxx.is_human(cummer)) return;
- if (IsDangerDay)
+ if ((cummer.Has(Quirk.Teratophile) != (parent.pawn.GetStatValue(StatDefOf.PawnBeauty) >= 0)) ||
+ cummer.Has(Quirk.ImpregnationFetish) ||
+ cummer.Has(Quirk.Breeder))
+ {
+ if (cummer.relations.OpinionOf(parent.pawn) <= -25)
{
- if (parent.pawn.Has(Quirk.Breeder) || parent.pawn.Has(Quirk.ImpregnationFetish))
- {
- parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer);
- }
- else if (parent.pawn.relations.OpinionOf(cummer) <= -5)
- {
- parent.pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.CameInsideF, cummer);
- parent.pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.HaterCameInsideFEstrus, cummer);
- parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer);
- }
- else if (parent.pawn.IsInEstrus() && parent.pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup)
- {
- parent.pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.CameInsideF, cummer);
- parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer);
- }
- else if (!parent.pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !parent.pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer))
- {
- if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer);
- else parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideF, cummer);
- }
+ cummer.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideM, parent.pawn);
}
else
{
- if (parent.pawn.Has(Quirk.Breeder) || parent.pawn.Has(Quirk.ImpregnationFetish))
- {
- parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetishSafe, cummer);
- }
- else if (parent.pawn.relations.OpinionOf(cummer) <= -5)
- {
- parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideFSafe, cummer);
- }
+ cummer.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideM, parent.pawn);
+ }
+ }
+
+ if (IsDangerDay)
+ {
+ if (parent.pawn.Has(Quirk.Breeder) || parent.pawn.Has(Quirk.ImpregnationFetish))
+ {
+ parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer);
+ }
+ else if (parent.pawn.relations.OpinionOf(cummer) <= -5)
+ {
+ parent.pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.CameInsideF, cummer);
+ parent.pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.HaterCameInsideFEstrus, cummer);
+ parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer);
+ }
+ else if (parent.pawn.IsInEstrus() && parent.pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup)
+ {
+ parent.pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.CameInsideF, cummer);
+ parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer);
+ }
+ else if (!parent.pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !parent.pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer))
+ {
+ if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer);
+ else parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideF, cummer);
+ }
+ }
+ else
+ {
+ if (parent.pawn.Has(Quirk.Breeder) || parent.pawn.Has(Quirk.ImpregnationFetish))
+ {
+ parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetishSafe, cummer);
+ }
+ else if (parent.pawn.relations.OpinionOf(cummer) <= -5)
+ {
+ parent.pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideFSafe, cummer);
}
}
}
-
+ protected virtual void TaleCumInside(Pawn cummer)
+ {
+ // Only make the tale for human-on-human, consentual sex. Otherwise the art just gets too hard to phrase properly
+ if (!xxx.is_human(parent.pawn) || !xxx.is_human(cummer) || parent.pawn == cummer) return;
+ if (parent.pawn.CurJobDef != xxx.casual_sex && parent.pawn.CurJobDef != xxx.gettin_loved) return;
+ if (!(parent.pawn.IsColonist || parent.pawn.IsPrisonerOfColony) && !(cummer.IsColonist || cummer.IsPrisonerOfColony)) return;
+ if (!IsDangerDay) return;
+ TaleRecorder.RecordTale(VariousDefOf.TaleCameInside, new object[] { cummer, parent.pawn });
+ }
private Action PeriodSimulator(Stage targetstage)
{
@@ -1694,22 +1590,24 @@ namespace RJW_Menstruation
switch (targetstage)
{
case Stage.Follicular:
- action = FollicularAction;
+ action = delegate
+ {
+ FollicularAction(false);
+ };
break;
case Stage.Ovulatory:
action = OvulatoryAction;
break;
case Stage.Luteal:
- action = LutealAction;
- break;
- case Stage.Bleeding:
- action = BleedingAction;
- break;
- case Stage.Fertilized: //Obsoleted stage. merged in luteal stage
action = delegate
{
- ModLog.Message("Obsoleted stage. skipping...");
- GoNextStage(Stage.Luteal);
+ LutealAction(false);
+ };
+ break;
+ case Stage.Bleeding:
+ action = delegate
+ {
+ BleedingAction(false);
};
break;
case Stage.Pregnant:
@@ -1728,13 +1626,22 @@ namespace RJW_Menstruation
action = YoungAction;
break;
case Stage.ClimactericFollicular:
- action = ClimactericFollicularAction;
+ action = delegate
+ {
+ FollicularAction(true);
+ };
break;
case Stage.ClimactericLuteal:
- action = ClimactericLutealAction;
+ action = delegate
+ {
+ LutealAction(true);
+ };
break;
case Stage.ClimactericBleeding:
- action = ClimactericBleedingAction;
+ action = delegate
+ {
+ BleedingAction(true);
+ };
break;
case Stage.Anestrus:
action = AnestrusAction;
@@ -1742,7 +1649,7 @@ namespace RJW_Menstruation
default:
curStage = Stage.Follicular;
curStageHrs = 0;
- if (follicularIntervalhours < 0) follicularIntervalhours = PeriodRandomizer(Props.folicularIntervalDays * 24, Props.deviationFactor);
+ if (currentIntervalHours < 0) currentIntervalHours = PeriodRandomizer(curStage);
HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(Stage.Follicular), GetNextUpdate(), parent.pawn, false);
break;
}
@@ -1757,7 +1664,7 @@ namespace RJW_Menstruation
actionref = action;
return actionref;
-
+
}
@@ -1772,19 +1679,18 @@ namespace RJW_Menstruation
return ((nextOffset - currentOffset + tickInterval - 1) % tickInterval) + 1;
}
- protected void GoNextStage(Stage nextstage)
+ 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 void GoNextStageSetHour(Stage nextstage, int hour)
+ protected virtual void GoOvulatoryStage(bool climacteric)
{
- curStageHrs = hour;
- curStage = nextstage;
- HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), GetNextUpdate(), parent.pawn, false);
+ GoNextStage(Stage.Ovulatory);
}
//stage can be interrupted in other reasons
@@ -1801,15 +1707,14 @@ namespace RJW_Menstruation
protected void GoFollicularOrBleeding()
{
+ bool climacteric = Configurations.EnableMenopause && ovarypower < OvaryPowerThreshold;
if (Props.bleedingIntervalDays == 0)
{
- follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
- GoNextStage(Stage.Follicular);
+ GoNextStage(climacteric ? Stage.ClimactericFollicular : Stage.Follicular);
}
else
{
- bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor);
- GoNextStage(Stage.Bleeding);
+ GoNextStage(climacteric ? Stage.ClimactericBleeding : Stage.Bleeding);
}
}
@@ -1824,9 +1729,25 @@ namespace RJW_Menstruation
else if (curStage == Stage.ClimactericLuteal) curStage = Stage.Luteal;
}
- protected int PeriodRandomizer(int intervalhours, float deviation)
+ protected int PeriodRandomizer(Stage stage, float variabilityFactor = 1.0f)
{
- return intervalhours + (int)(intervalhours * Rand.Range(-deviation, deviation));
+ // Most cycle lengthening or shortening occurs in the follicular phase, so weight towards that
+ switch (stage)
+ {
+ case Stage.Follicular:
+ case Stage.ClimactericFollicular:
+ return (int)(Props.follicularIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 1.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 1.5f));
+ case Stage.Luteal:
+ case Stage.ClimactericLuteal:
+ return (int)(Props.lutealIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f));
+ case Stage.Bleeding:
+ case Stage.ClimactericBleeding:
+ 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));
+ default: // Often unused
+ return 1;
+ }
}
protected float InterspeciesImplantFactor(Pawn fertilizer)
@@ -1851,29 +1772,26 @@ namespace RJW_Menstruation
protected Stage RandomStage()
{
- int rand = Rand.Range(0, 2);
+ int rand = Rand.ElementByWeight(
+ 0, Props.follicularIntervalDays - Props.bleedingIntervalDays,
+ 1, Props.lutealIntervalDays,
+ 2, Props.bleedingIntervalDays);
switch (rand)
{
case 0:
- curStageHrs = Rand.Range(0, (Props.folicularIntervalDays - Props.bleedingIntervalDays) * 24);
+ curStageHrs = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * 24);
return Stage.Follicular;
case 1:
- curStageHrs = Rand.Range(0, Props.eggLifespanDays * 24);
+ curStageHrs = Rand.Range(0, Props.lutealIntervalDays * 24);
return Stage.Luteal;
case 2:
curStageHrs = Rand.Range(0, Props.bleedingIntervalDays * 24);
return Stage.Bleeding;
default: return Stage.Follicular;
}
-
-
}
-
-
-
-
public class Egg : IExposable
{
public bool fertilized;
@@ -1937,12 +1855,4 @@ namespace RJW_Menstruation
{
}
}
-
-
-
-
-
-
-
-
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs
index c988cfc..7f76ffa 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs
@@ -1,47 +1,65 @@
-using System;
+using RimWorld;
+using rjw;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RimWorld;
-using Verse;
-using rjw;
using UnityEngine;
+using Verse;
namespace RJW_Menstruation
{
public static class MenstruationUtility
{
-
-
+ [Obsolete("This method is obsolete. Use GetMenstruationComps or a related function instead", false)]
public static HediffComp_Menstruation GetMenstruationComp(this Pawn pawn)
{
- var hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll((Hediff h) => h.def.defName.ToLower().Contains("vagina"));
- HediffComp_Menstruation result;
- if (hedifflist.NullOrEmpty()) return null;
- else
+ return pawn.GetFirstMenstruationComp();
+ }
+
+ public static IEnumerable GetMenstruationComps(this Pawn pawn)
+ {
+ List hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll(h => VariousDefOf.AllVaginas.Contains(h.def));
+ if (hedifflist == null) yield break;
+ foreach (Hediff hediff in hedifflist)
{
- foreach (Hediff h in hedifflist)
- {
- result = h.TryGetComp();
- if (result != null) return result;
- }
+ HediffComp_Menstruation result = hediff.TryGetComp();
+ if (result != null) yield return result;
+ }
+ }
+
+ public static HediffComp_Menstruation GetFirstMenstruationComp(this Pawn pawn)
+ {
+ return pawn.GetMenstruationComps().FirstOrDefault();
+ }
+
+ public static HediffComp_Menstruation GetRandomMenstruationComp(this Pawn pawn)
+ {
+ return pawn.GetMenstruationComps().RandomElementWithFallback();
+ }
+
+ public static HediffComp_Menstruation GetFertileMenstruationComp(this Pawn pawn)
+ {
+ List comps = pawn.GetMenstruationComps().ToList();
+ return comps.Where(c => c.IsDangerDay).RandomElementWithFallback() ?? comps.RandomElementWithFallback();
+ }
+
+ public static HediffComp_Menstruation GetMenstruationComp(this Hediff vagina)
+ {
+ if (vagina is Hediff_PartBaseNatural || vagina is Hediff_PartBaseArtifical)
+ {
+ return vagina.TryGetComp();
}
return null;
}
- public static HediffComp_Menstruation GetMenstruationComp(this Hediff hediff)
+ public static HediffComp_Menstruation GetMenstruationComp(this Hediff_BasePregnancy pregnancy)
{
- if (hediff is Hediff_PartBaseNatural || hediff is Hediff_PartBaseArtifical)
- {
- return hediff.TryGetComp();
- }
- return null;
+ return pregnancy?.pawn.GetMenstruationComps().FirstOrDefault(comp => comp.Pregnancy == pregnancy);
}
public static HediffComp_Anus GetAnusComp(this Pawn pawn)
{
- var hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll((Hediff h) => h.def.defName.ToLower().Contains("anus"));
+ List hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll((Hediff h) => h.def.defName.ToLower().Contains("anus"));
HediffComp_Anus result;
if (!hedifflist.NullOrEmpty())
{
@@ -63,18 +81,11 @@ namespace RJW_Menstruation
return null;
}
-
public static float GetFertilityChance(this HediffComp_Menstruation comp)
{
- return comp.TotalFertCum * Configurations.FertilizeChance * comp.Props.basefertilizationChanceFactor;
+ return 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, comp.TotalFertCum * comp.Props.basefertilizationChanceFactor);
}
- public static HediffComp_Menstruation.Stage GetCurStage(this Pawn pawn)
- {
- return GetMenstruationComp(pawn)?.curStage ?? HediffComp_Menstruation.Stage.Bleeding;
- }
-
-
public static Texture2D GetPregnancyIcon(this HediffComp_Menstruation comp, Hediff hediff)
{
string icon = "";
@@ -157,19 +168,19 @@ namespace RJW_Menstruation
}
public static Texture2D GetEggIcon(this HediffComp_Menstruation comp, bool includeOvary)
{
- if (comp.parent.pawn.IsPregnant(Configurations.InfoDetail != Configurations.DetailLevel.All) && !(PregnancyHelper.GetPregnancy(comp.parent.pawn) is Hediff_MechanoidPregnancy))
- {
- if (comp.parent.pawn.GetPregnancyProgress() < 0.2f) return ContentFinder.Get("Eggs/Egg_Implanted00", true);
+ if (comp.Pregnancy != null && !(comp.Pregnancy is Hediff_MechanoidPregnancy))
+ {
+ if (comp.GetPregnancyProgress() < 0.2f) return ContentFinder.Get("Eggs/Egg_Implanted00", true);
else return ContentFinder.Get("Womb/Empty", true);
}
- switch(comp.curStage)
+ switch (comp.curStage)
{
case HediffComp_Menstruation.Stage.Follicular:
case HediffComp_Menstruation.Stage.ClimactericFollicular:
if (!includeOvary) break;
if (comp is HediffComp_InducedOvulator) break;
- if (comp.curStageHrs > comp.FollicularIntervalHours - 30) // Approximate time for ovulation to occur
+ if (comp.curStageHrs > comp.CurStageIntervalHours - 30) // Approximate time for ovulation to occur
return ContentFinder.Get("Ovaries/Ovary_01", true);
else break;
case HediffComp_Menstruation.Stage.Ovulatory:
@@ -209,7 +220,7 @@ namespace RJW_Menstruation
public static Texture2D GetGenitalIcon(this Pawn pawn, HediffComp_Menstruation comp, bool drawOrigin = false)
{
- var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.Find((Hediff h) => h.def.defName.ToLower().Contains("vagina"));
+ Hediff hediff = comp?.parent;
if (hediff == null) return ContentFinder.Get("Genitals/Vagina00", true);
//HediffComp_Menstruation comp = hediff.GetMenstruationComp();
string icon;
@@ -237,37 +248,32 @@ namespace RJW_Menstruation
public static Texture2D GetAnalIcon(this Pawn pawn, bool drawOrigin = false)
{
- var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("anus"));
- if (hediff != null)
- {
- 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
- else if (severity < 0.40f) icon += "01"; //tight
- else if (severity < 0.60f) icon += "02"; //average
- else if (severity < 0.80f) icon += "03"; //accomodating
- else if (severity < 1.01f) icon += "04"; //cavernous
- else icon += "05"; //abyssal
+ Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("anus"));
+ if (hediff == null) return ContentFinder.Get(("Genitals/Anal00"), true);
- return ContentFinder.Get((icon), true);
+ 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
{
- return ContentFinder.Get(("Genitals/Anal00"), true);
+ icon = "Genitals/Anal";
+ severity = hediff.Severity;
}
+ if (severity < 0.20f) icon += "00"; //micro
+ else if (severity < 0.40f) icon += "01"; //tight
+ else if (severity < 0.60f) icon += "02"; //average
+ else if (severity < 0.80f) icon += "03"; //accomodating
+ else if (severity < 1.01f) icon += "04"; //cavernous
+ else icon += "05"; //abyssal
+
+ return ContentFinder.Get((icon), true);
}
public static float GestationHours(this Hediff_BasePregnancy hediff)
@@ -280,6 +286,21 @@ namespace RJW_Menstruation
else return (hediff.p_end_tick - hediff.p_start_tick) / GenDate.TicksPerHour;
}
+ public static float RandomVariabilityPercent(int recursion = 0)
+ {
+ // Humans, in days
+ const float mean = 1.635f;
+ const float stddev = 0.9138f;
+ const float lambda = 0.234f;
+ if (recursion >= 10) return mean / (28 * 2);
+
+ float variability = Rand.Gaussian(mean, stddev) - Mathf.Log(Rand.Value) / lambda;
+ variability /= 28 * 2; // Convert to percentage
+
+ if (variability < 0 || variability > 0.35f) return RandomVariabilityPercent(recursion + 1); // ~2% chance, about the limit on how far variability can go before things start to break
+ else return variability;
+ }
+
public static bool IsInEstrus(this Pawn pawn, bool visible = true)
{
if (pawn.Dead) return false;
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 73521e2..56eff5c 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs
@@ -17,21 +17,26 @@ namespace RJW_Menstruation
protected void PregnancyThought()
{
- if (!is_discovered && xxx.is_human(pawn))
+ if (is_discovered ||
+ !xxx.is_human(pawn) ||
+ pawn.Has(Quirk.Breeder) ||
+ (pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Spouse) ||
+ x.def.Equals(PawnRelationDefOf.Fiance))) != null)
+ return;
+ if (pawn.Has(Quirk.ImpregnationFetish) || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null)
{
- if (!pawn.Has(Quirk.Breeder) && pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Spouse) || x.def.Equals(PawnRelationDefOf.Fiance)) == null)
- {
- if (pawn.Has(Quirk.ImpregnationFetish) || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null)
- {
- pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancyMild);
- }
- else
- {
- pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancy);
- }
- }
-
+ pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancyMild);
}
+ else
+ {
+ pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancy);
+ }
+ }
+
+ public override void Miscarry()
+ {
+ this.GetMenstruationComp().Pregnancy = null;
+ base.Miscarry();
}
public override void GiveBirth()
@@ -47,42 +52,43 @@ namespace RJW_Menstruation
Initialize(pawn, father);
}
- List siblings = new List();
foreach (Pawn baby in babies)
{
if (xxx.is_animal(baby))
{
- BestialBirth(baby, siblings);
+ BestialBirth(baby);
}
else
{
- HumanlikeBirth(baby, siblings);
+ HumanlikeBirth(baby);
}
baby.ageTracker.AgeChronologicalTicks = 0;
}
pawn.health.RemoveHediff(this);
+ HediffComp_Menstruation comp = this.GetMenstruationComp();
+ if(comp != null) comp.Pregnancy = null;
}
public string GetBabyInfo()
{
+ if (babies.NullOrEmpty())
+ return "Null";
+
string res = "";
- if (!babies.NullOrEmpty())
+
+ IEnumerable babiesdistinct = babies.Distinct(new RaceComparer());
+ int iteration = 0;
+ foreach (Pawn baby in babiesdistinct)
{
- var babiesdistinct = babies.Distinct(new RaceComparer());
- int iteration = 0;
- foreach (Pawn baby in babiesdistinct)
- {
- int num = babies.Where(x => x.def.Equals(baby.def)).Count();
- if (iteration > 0) res += ", ";
- res += num + " " + baby.def.label;
- iteration++;
- }
- res += " " + Translations.Dialog_WombInfo02;
- return res;
+ int num = babies.Where(x => x.def.Equals(baby.def)).Count();
+ if (iteration > 0) res += ", ";
+ res += num + " " + baby.def.label;
+ iteration++;
}
- return "Null";
+ res += " " + Translations.Dialog_WombInfo02;
+ return res;
}
public string GetFatherInfo()
@@ -95,7 +101,7 @@ namespace RJW_Menstruation
if (!is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All)
return res + Translations.Dialog_FatherUnknown;
- var babiesdistinct = babies.Distinct(new FatherComparer(pawn));
+ IEnumerable babiesdistinct = babies.Distinct(new FatherComparer(pawn));
int iteration = 0;
foreach (Pawn baby in babiesdistinct)
{
@@ -106,7 +112,7 @@ namespace RJW_Menstruation
return res;
}
- private void HumanlikeBirth(Pawn baby, List siblings)
+ private void HumanlikeBirth(Pawn baby)
{
Pawn mother = pawn; Pawn father = Utility.GetFather(baby, pawn);
//backup melanin, LastName for when baby reset by other mod on spawn/backstorychange
@@ -115,7 +121,7 @@ namespace RJW_Menstruation
PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother);
- var sex_need = mother.needs?.TryGetNeed();
+ Need_Sex sex_need = mother.needs?.TryGetNeed();
if (mother.Faction != null && !(mother.Faction?.IsPlayer ?? false) && sex_need != null)
{
sex_need.CurLevel = 1.0f;
@@ -144,17 +150,13 @@ namespace RJW_Menstruation
baby.guest.SetGuestStatus(Faction.OfPlayer, GuestStatus.Prisoner);
}
- foreach (Pawn sibling in siblings)
- {
- baby.relations.AddDirectRelation(PawnRelationDefOf.Sibling, sibling);
- }
- siblings.Add(baby);
-
+ if (xxx.is_human(mother)) TaleRecorder.RecordTale(TaleDefOf.GaveBirth, new object[] { mother, baby });
+
PostBirth(mother, father, baby);
}
- private void BestialBirth(Pawn baby, List siblings)
+ private void BestialBirth(Pawn baby)
{
Pawn mother = pawn; Pawn father = Utility.GetFather(baby, pawn);
//backup melanin, LastName for when baby reset by other mod on spawn/backstorychange
@@ -174,14 +176,6 @@ namespace RJW_Menstruation
baby.SetFaction(mother.Faction);
}
- if (!RJWSettings.Disable_bestiality_pregnancy_relations)
- {
- foreach (Pawn sibling in siblings)
- {
- baby.relations.AddDirectRelation(PawnRelationDefOf.Sibling, sibling);
- }
- siblings.Add(baby);
- }
Train(baby, mother);
PostBirth(mother, father, baby);
@@ -198,7 +192,6 @@ namespace RJW_Menstruation
List momtraits = new List();
List poptraits = new List();
List traits_to_inherit = new List();
- System.Random rd = new System.Random();
float max_num_momtraits_inherited = RJWPregnancySettings.max_num_momtraits_inherited;
float max_num_poptraits_inherited = RJWPregnancySettings.max_num_poptraits_inherited;
float max_num_traits_inherited = max_num_momtraits_inherited + max_num_poptraits_inherited;
@@ -226,7 +219,7 @@ namespace RJW_Menstruation
i = 1;
while (momtraits.Count > 0 && i <= max_num_momtraits_inherited)
{
- rand_trait_index = rd.Next(0, momtraits.Count);
+ rand_trait_index = Rand.Range(0, momtraits.Count);
traits_to_inherit.Add(momtraits[rand_trait_index]);
momtraits.RemoveAt(rand_trait_index);
}
@@ -236,7 +229,7 @@ namespace RJW_Menstruation
j = 1;
while (poptraits.Count > 0 && j <= max_num_poptraits_inherited)
{
- rand_trait_index = rd.Next(0, poptraits.Count);
+ rand_trait_index = Rand.Range(0, poptraits.Count);
traits_to_inherit.Add(poptraits[rand_trait_index]);
poptraits.RemoveAt(rand_trait_index);
}
@@ -257,7 +250,7 @@ namespace RJW_Menstruation
{
while (poptraits != null && momtraits.Count() > 0 && i <= max_num_momtraits_inherited)
{
- rand_trait_index = rd.Next(0, momtraits.Count);
+ rand_trait_index = Rand.Range(0, momtraits.Count);
if (!traits_to_inherit.Contains(momtraits[rand_trait_index]))
{
traits_to_inherit.Add(momtraits[rand_trait_index]);
@@ -269,7 +262,7 @@ namespace RJW_Menstruation
{
while (poptraits.Count > 0 && i < max_num_poptraits_inherited)
{
- rand_trait_index = rd.Next(0, poptraits.Count);
+ rand_trait_index = Rand.Range(0, poptraits.Count);
if (!traits_to_inherit.Contains(poptraits[rand_trait_index]))
{
traits_to_inherit.Add(poptraits[rand_trait_index]);
@@ -295,16 +288,15 @@ namespace RJW_Menstruation
protected void Train(Pawn baby, Pawn mother)
{
- if (!xxx.is_human(baby) && baby.Faction == Faction.OfPlayer)
+ if (xxx.is_human(baby) || baby.Faction != Faction.OfPlayer) return;
+
+ if (xxx.is_human(mother) && baby.Faction == Faction.OfPlayer && baby.training.CanAssignToTrain(TrainableDefOf.Obedience, out _).Accepted)
{
- if (xxx.is_human(mother) && baby.Faction == Faction.OfPlayer && baby.training.CanAssignToTrain(TrainableDefOf.Obedience, out _).Accepted)
- {
- baby.training.Train(TrainableDefOf.Obedience, mother);
- }
- if (xxx.is_human(mother) && baby.Faction == Faction.OfPlayer && baby.training.CanAssignToTrain(TrainableDefOf.Tameness, out _).Accepted)
- {
- baby.training.Train(TrainableDefOf.Tameness, mother);
- }
+ baby.training.Train(TrainableDefOf.Obedience, mother);
+ }
+ if (xxx.is_human(mother) && baby.Faction == Faction.OfPlayer && baby.training.CanAssignToTrain(TrainableDefOf.Tameness, out _).Accepted)
+ {
+ baby.training.Train(TrainableDefOf.Tameness, mother);
}
}
@@ -352,7 +344,7 @@ namespace RJW_Menstruation
kind: BabyPawnKindDecider(mother, father),
//fixedIdeo: mother.Ideo,
//forbidAnyTitle: true,
- forceNoBackstory:true
+ forceNoBackstory: true
);
int division = 1;
@@ -363,7 +355,7 @@ namespace RJW_Menstruation
string firstheadpath = null;
string firstHARcrown = null;
int traitSeed = Rand.Int;
- List parentTraits = GetInheritableTraits(mother, father);
+ List parentTraits = GetInheritableTraits(mother, father);
while (Rand.Chance(Configurations.EnzygoticTwinsChance) && division < Configurations.MaxEnzygoticTwins) division++;
for (int i = 0; i < division; i++)
{
@@ -421,30 +413,28 @@ namespace RJW_Menstruation
public Pawn GenerateBaby(PawnGenerationRequest request, Pawn mother, Pawn father, List parentTraits, int traitSeed)
{
Pawn baby = PawnGenerator.GeneratePawn(request);
- if (baby != null)
+ if (baby == null)
{
- if (xxx.is_human(baby) || (baby.relations != null && !RJWSettings.Disable_bestiality_pregnancy_relations))
+ Log.Error("Baby not generated. Request: " + request.ToString());
+ return null;
+ }
+ if (xxx.is_human(baby) || (baby.relations != null && !RJWSettings.Disable_bestiality_pregnancy_relations))
+ {
+ baby.SetMother(mother);
+ if (mother != father)
{
- baby.SetMother(mother);
- if (mother != father)
- {
- if (father.gender != Gender.Female) baby.SetFather(father);
- else
- {
- baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father);
- }
- }
- }
- if (xxx.is_human(baby))
- {
- // Ensure the same inherited traits are chosen each run
- // Has to happen right here so GeneratePawn up there still gets unique results
- Rand.PushState(traitSeed); // With a seed just to make sure that fraternal twins *don't* get trait-duped
- UpdateTraits(baby, parentTraits);
- Rand.PopState();
+ if (father.gender != Gender.Female) baby.SetFather(father);
+ else baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father);
}
}
- else Log.Error("Baby not generated. Request: " + request.ToString());
+ if (xxx.is_human(baby))
+ {
+ // Ensure the same inherited traits are chosen each run
+ // Has to happen right here so GeneratePawn up there still gets unique results
+ Rand.PushState(traitSeed); // With a seed just to make sure that fraternal twins *don't* get trait-duped
+ UpdateTraits(baby, parentTraits);
+ Rand.PopState();
+ }
return baby;
}
@@ -457,7 +447,10 @@ namespace RJW_Menstruation
///
public PawnKindDef BabyPawnKindDecider(Pawn mother, Pawn father)
{
- PawnKindDef spawn_kind_def = mother.kindDef;
+ PawnKindDef motherKindDef = Utility.GetRacesPawnKind(mother);
+ PawnKindDef fatherKindDef = Utility.GetRacesPawnKind(father);
+
+ PawnKindDef spawn_kind_def = motherKindDef;
int flag = 0;
if (xxx.is_human(mother)) flag += 2;
@@ -471,18 +464,18 @@ namespace RJW_Menstruation
switch (flag)
{
case 3:
- if (!Rand.Chance(RJWPregnancySettings.humanlike_DNA_from_mother)) spawn_kind_def = father.kindDef;
+ if (!Rand.Chance(RJWPregnancySettings.humanlike_DNA_from_mother)) spawn_kind_def = fatherKindDef;
break;
case 2:
- if (RJWPregnancySettings.bestiality_DNA_inheritance == 0f) spawn_kind_def = father.kindDef;
- else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = father.kindDef;
+ if (RJWPregnancySettings.bestiality_DNA_inheritance == 0f) spawn_kind_def = fatherKindDef;
+ else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
break;
case 1:
- if (RJWPregnancySettings.bestiality_DNA_inheritance == 1f) spawn_kind_def = father.kindDef;
- else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = father.kindDef;
+ if (RJWPregnancySettings.bestiality_DNA_inheritance == 1f) spawn_kind_def = fatherKindDef;
+ else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
break;
case 0:
- if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = father.kindDef;
+ if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
break;
}
@@ -490,19 +483,19 @@ namespace RJW_Menstruation
bool IsAndroidfather = AndroidsCompatibility.IsAndroid(father);
if (IsAndroidmother && !IsAndroidfather)
{
- spawn_kind_def = father.kindDef;
+ spawn_kind_def = fatherKindDef;
}
else if (!IsAndroidmother && IsAndroidfather)
{
- spawn_kind_def = mother.kindDef;
+ spawn_kind_def = motherKindDef;
}
string MotherRaceName = "";
string FatherRaceName = "";
- MotherRaceName = mother.kindDef?.race?.defName;
+ MotherRaceName = motherKindDef?.race?.defName;
PawnKindDef non_hybrid_kind_def = spawn_kind_def;
if (father != null)
- FatherRaceName = father.kindDef?.race?.defName;
+ FatherRaceName = fatherKindDef?.race?.defName;
if (FatherRaceName != "" && Configurations.UseHybridExtention)
@@ -516,24 +509,24 @@ namespace RJW_Menstruation
if (!Configurations.UseHybridExtention || spawn_kind_def == null)
{
spawn_kind_def = non_hybrid_kind_def;
- var groups = DefDatabase.AllDefs.Where(x => !(x.hybridRaceParents.NullOrEmpty() || x.hybridChildKindDef.NullOrEmpty()));
+ IEnumerable groups = DefDatabase.AllDefs.Where(x => !(x.hybridRaceParents.NullOrEmpty() || x.hybridChildKindDef.NullOrEmpty()));
//ModLog.Message(" found custom RaceGroupDefs " + groups.Count());
- foreach (var t in groups)
+ foreach (RaceGroupDef t in groups)
{
if ((t.hybridRaceParents.Contains(MotherRaceName) && t.hybridRaceParents.Contains(FatherRaceName))
|| (t.hybridRaceParents.Contains("Any") && (t.hybridRaceParents.Contains(MotherRaceName) || t.hybridRaceParents.Contains(FatherRaceName))))
{
//ModLog.Message(" has hybridRaceParents");
if (t.hybridChildKindDef.Contains("MotherKindDef"))
- spawn_kind_def = mother.kindDef;
+ spawn_kind_def = motherKindDef;
else if (t.hybridChildKindDef.Contains("FatherKindDef") && father != null)
- spawn_kind_def = father.kindDef;
+ spawn_kind_def = fatherKindDef;
else
{
//ModLog.Message(" trying hybridChildKindDef " + t.defName);
- var child_kind_def_list = new List();
+ List child_kind_def_list = new List();
child_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => t.hybridChildKindDef.Contains(x.defName)));
//ModLog.Message(" found custom hybridChildKindDefs " + t.hybridChildKindDef.Count);
@@ -547,20 +540,20 @@ namespace RJW_Menstruation
}
else if (!Configurations.UseHybridExtention || spawn_kind_def == null)
{
- spawn_kind_def = mother.RaceProps?.AnyPawnKind ?? mother.kindDef;
+ spawn_kind_def = mother.RaceProps?.AnyPawnKind ?? motherKindDef;
}
if (spawn_kind_def.defName.Contains("Nymph"))
{
//child is nymph, try to find other PawnKindDef
- var spawn_kind_def_list = new List();
+ List spawn_kind_def_list = new List();
spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == spawn_kind_def.race && !x.defName.Contains("Nymph")));
//no other PawnKindDef found try mother
if (spawn_kind_def_list.NullOrEmpty())
- spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == mother.kindDef.race && !x.defName.Contains("Nymph")));
+ spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == motherKindDef.race && !x.defName.Contains("Nymph")));
//no other PawnKindDef found try father
if (spawn_kind_def_list.NullOrEmpty() && father != null)
- spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == father.kindDef.race && !x.defName.Contains("Nymph")));
+ spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == fatherKindDef.race && !x.defName.Contains("Nymph")));
//no other PawnKindDef found fallback to generic colonist
if (spawn_kind_def_list.NullOrEmpty())
spawn_kind_def = PawnKindDefOf.Colonist;
@@ -568,9 +561,6 @@ namespace RJW_Menstruation
if (!spawn_kind_def_list.NullOrEmpty()) spawn_kind_def = spawn_kind_def_list.RandomElement();
}
-
-
-
return spawn_kind_def;
}
@@ -638,17 +628,17 @@ namespace RJW_Menstruation
parentTraitPool.RemoveAll(x => x.ScenForced);
int numberInherited;
if (parentTraitPool != null)
- numberInherited = System.Math.Min(parentTraitPool.Count(), Rand.RangeInclusive(0,2)); // Not 3; give a better chance for a natural trait to appear
+ numberInherited = System.Math.Min(parentTraitPool.Count(), Rand.RangeInclusive(0, 2)); // Not 3; give a better chance for a natural trait to appear
else
numberInherited = 0;
//Game suggested traits.
- var forcedTraits = personalTraitPool
+ IEnumerable forcedTraits = personalTraitPool
.Where(x => x.ScenForced)
.Distinct(new TraitComparer(ignoreDegree: true)); // result can be a mess, because game allows this mess to be created in scenario editor
List selectedTraits = new List();
- var comparer = new TraitComparer(); // trait comparision implementation, because without game compares traits *by reference*, makeing them all unique.
+ TraitComparer comparer = new TraitComparer(); // trait comparision implementation, because without game compares traits *by reference*, makeing them all unique.
selectedTraits.AddRange(forcedTraits); // enforcing scenario forced traits
for (int i = 0; i < numberInherited; i++) // add parent traits first
{
@@ -663,13 +653,13 @@ namespace RJW_Menstruation
while (selectedTraits.Count < traitLimit && personalTraitPool.Count > 0)
{
int index = Rand.Range(0, personalTraitPool.Count); // getting trait and removing from the pull
- var trait = personalTraitPool[index];
+ Trait trait = personalTraitPool[index];
personalTraitPool.RemoveAt(index);
if (!selectedTraits.Any(x => comparer.Equals(x, trait) || // skipping traits conflicting with already added
x.def.ConflictsWith(trait)))
selectedTraits.Add(new Trait(trait.def, trait.Degree, false));
-
+
}
pawn.story.traits.allTraits = selectedTraits;
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs
index 6ca0713..0ebf299 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs
@@ -1,24 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RimWorld;
+using RimWorld;
using Verse;
-using rjw;
namespace RJW_Menstruation
{
public class IngestionOutcomeDoer_GiveHediff_StackCount : IngestionOutcomeDoer_GiveHediff
- {
- protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
- {
- Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn);
- float effect = ((!(severity > 0f)) ? hediffDef.initialSeverity : severity) * ingested.stackCount;
- AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, toleranceChemical, ref effect);
- hediff.Severity = effect;
- pawn.health.AddHediff(hediff);
- }
+ {
+ protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
+ {
+ Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn);
+ float effect = ((!(severity > 0f)) ? hediffDef.initialSeverity : severity) * ingested.stackCount;
+ AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, toleranceChemical, ref effect);
+ hediff.Severity = effect;
+ pawn.health.AddHediff(hediff);
+ }
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs
index 0dcd459..99cae05 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs
@@ -1,5 +1,6 @@
-using System.Collections.Generic;
-using RimWorld;
+using RimWorld;
+using System.Collections.Generic;
+using System.Linq;
using Verse;
using Verse.AI;
@@ -16,11 +17,10 @@ namespace RJW_Menstruation
protected override IEnumerable MakeNewToils()
{
-
- HediffComp_Menstruation Comp = pawn.GetMenstruationComp();
+ List comps = pawn.GetMenstruationComps().ToList();
this.FailOn(delegate
{
- return !(Comp.TotalCumPercent > 0.001);
+ return comps.All(comp => comp.TotalCumPercent < 0.001);
});
Toil excreting = Toils_General.Wait(excretingTime, TargetIndex.None);//duration of
@@ -30,8 +30,9 @@ namespace RJW_Menstruation
{
initAction = delegate ()
{
- Comp.CumOut(null, 0.5f);
- if (Comp.TotalCumPercent > 0.001) JumpToToil(excreting);
+ foreach (HediffComp_Menstruation comp in comps)
+ comp.CumOut(null, 0.5f);
+ if (comps.Any(comp => comp.TotalCumPercent > 0.001)) JumpToToil(excreting);
}
};
//yield return excreting;
@@ -107,7 +108,7 @@ namespace RJW_Menstruation
protected virtual void Finish()
{
- if(pawn.CurJobDef == JobDefOf.Wait_MaintainPosture)
+ if (pawn.CurJobDef == JobDefOf.Wait_MaintainPosture)
{
pawn.jobs.EndCurrentJob(JobCondition.InterruptForced);
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs
index 82a2bf0..79e7be5 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs
@@ -1,9 +1,9 @@
-using System.Collections.Generic;
-using System.Linq;
-using HarmonyLib;
-using Verse;
+using HarmonyLib;
using RimWorld;
using RimWorld.Planet;
+using System.Collections.Generic;
+using System.Linq;
+using Verse;
namespace RJW_Menstruation.Patch
{
@@ -26,12 +26,11 @@ namespace RJW_Menstruation.Patch
public static void Prefix()
{
GetCriticalPawnReason_Patch.cummedPawns.Clear();
-// foreach(Pawn p in PawnsFinder.All_AliveOrDead)
- foreach(Pawn p in PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_OfPlayerFaction.Union(PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_PrisonersOfColony))
+ // foreach(Pawn p in PawnsFinder.All_AliveOrDead)
+ foreach (Pawn p in PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_OfPlayerFaction.Union(PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_PrisonersOfColony))
{
- HediffComp_Menstruation comp = p.GetMenstruationComp();
- if (comp is null) continue;
- GetCriticalPawnReason_Patch.cummedPawns.UnionWith(comp.GetCummersAndFertilizers());
+ foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
+ GetCriticalPawnReason_Patch.cummedPawns.UnionWith(comp.GetCummersAndFertilizers());
}
}
}
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 fe22153..22bf735 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs
@@ -28,11 +28,9 @@ namespace RJW_Menstruation
foreach (Gizmo gizmo in gizmos)
yield return gizmo;
- HediffComp_Menstruation comp = __instance.GetMenstruationComp();
- if (comp == null) yield break;
-
- foreach (Gizmo gizmo in GetMenstruationGizmos(__instance, comp))
- yield return gizmo;
+ foreach (HediffComp_Menstruation comp in __instance.GetMenstruationComps())
+ foreach (Gizmo gizmo in GetMenstruationGizmos(__instance, comp))
+ yield return gizmo;
}
public static List GetMenstruationGizmos(Pawn pawn, HediffComp_Menstruation comp)
@@ -49,8 +47,8 @@ namespace RJW_Menstruation
else description += comp.GetCurStageLabel + "\n";
if (pawn.IsPregnant())
{
- Hediff hediff = PregnancyHelper.GetPregnancy(pawn);
- if (Utility.ShowFetusImage((Hediff_BasePregnancy)hediff))
+ Hediff_BasePregnancy hediff = comp.Pregnancy;
+ if (Utility.ShowFetusImage(hediff))
{
icon = comp.GetPregnancyIcon(hediff);
if (hediff is Hediff_BasePregnancy h)
@@ -100,7 +98,7 @@ namespace RJW_Menstruation
Dialog_WombStatus.ToggleWindow(pawn, comp);
}
};
-
+
return gizmo;
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs
index be30dc8..d701d49 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs
@@ -14,14 +14,14 @@ namespace RJW_Menstruation
{
static First()
{
- var har = new Harmony("RJW_Menstruation");
+ Harmony har = new Harmony("RJW_Menstruation");
har.PatchAll(Assembly.GetExecutingAssembly());
InjectIntoRjwInteractionServices();
}
private static void InjectIntoRjwInteractionServices()
{
- var log = LogManager.GetLogger("StaticConstructorOnStartup");
+ ILog log = LogManager.GetLogger("StaticConstructorOnStartup");
List partKindUsageRules = Unprivater.GetProtectedValue>("_partKindUsageRules", typeof(PartPreferenceDetectorService));
partKindUsageRules.Add(new Interactions.EstrusPartKindUsageRule());
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 260937c..2265058 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
@@ -2,10 +2,8 @@
using HugsLib;
using RimWorld;
using System.Collections.Generic;
-using System.Linq;
using UnityEngine;
using Verse;
-using rjw;
namespace RJW_Menstruation
{
@@ -16,20 +14,18 @@ namespace RJW_Menstruation
public static void Postfix(Pawn __instance)
{
//Log.Message("Initialize on spawnsetup");
- HediffComp_Menstruation comp = __instance.GetMenstruationComp();
- if (comp != null)
+ 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();
}
-
-
}
}
@@ -38,7 +34,7 @@ namespace RJW_Menstruation
{
public static void Postfix(Vector3 clickPos, Pawn pawn, List opts)
{
- var selftargets = GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn));
+ IEnumerable selftargets = GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn));
foreach (LocalTargetInfo t in selftargets)
{
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs
index 887f6b8..f4445f9 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs
@@ -2,12 +2,12 @@
using rjw;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Objects;
-using Verse;
-using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
+using UnityEngine;
+using Verse;
namespace RJW_Menstruation
{
@@ -15,22 +15,28 @@ namespace RJW_Menstruation
[HarmonyPatch(typeof(PregnancyHelper), nameof(PregnancyHelper.impregnate))]
public static class Impregnate_Patch
{
- public static bool Prefix(SexProps props)
+ public static bool Prefix(SexProps props, out HediffComp_Menstruation __state)
{
xxx.rjwSextype sextype = props.sexType;
Pawn pawn = props.pawn;
Pawn partner = props.partner;
+ if (PregnancyHelper.GetPregnancy(partner) is Hediff_BasePregnancy oldestPregnancy) __state = oldestPregnancy.GetMenstruationComp();
+ else __state = null;
+
if (sextype != xxx.rjwSextype.Vaginal && sextype != xxx.rjwSextype.DoublePenetration) return true;
if (partner.IsAnimal() && !Configurations.EnableAnimalCycle) return true;
if (!InteractionCanCausePregnancy(props)) return false;
- var pawnparts = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn));
+ List pawnparts = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn));
- HediffComp_Menstruation comp = partner.GetMenstruationComp();
- if (comp is null) return true;
+ HediffComp_Menstruation comp;
+ if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus())
+ comp = partner.GetFertileMenstruationComp();
+ else comp = partner.GetRandomMenstruationComp();
+ if (comp == null) return true;
if (Genital_Helper.has_penis_fertile(pawn, pawnparts) && PregnancyHelper.CanImpregnate(pawn, partner, sextype))
{
@@ -44,8 +50,18 @@ namespace RJW_Menstruation
else comp.CumIn(pawn, pawn.GetCumVolume(pawnparts), 0);
return true;
+ }
+ public static void Postfix(SexProps props, HediffComp_Menstruation __state)
+ {
+ if (__state == null || __state.Pregnancy != null) return;
+ // It was pregnant, but not anymore. This probably means the pregnancy was destroyed by e.g. a mech implant
+ Pawn pawn = props.partner;
+ Hediff_BasePregnancy newestPregnancy = pawn.health.hediffSet.GetHediffs().MaxBy(hediff => hediff.loadID);
+ if (newestPregnancy == null) return;
+ if (pawn.GetMenstruationComps().Any(comp => comp.Pregnancy == newestPregnancy)) return; // One of the wombs did get it
+ else __state.Pregnancy = newestPregnancy;
}
///
@@ -85,31 +101,59 @@ namespace RJW_Menstruation
public static bool Prefix(Pawn pawn, Pawn partner) // partner has vagina
{
if (partner.IsAnimal() && !Configurations.EnableAnimalCycle) return true;
- HediffComp_Menstruation comp = partner.GetMenstruationComp();
- if (comp != null)
+ HediffComp_Menstruation comp;
+ if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus())
+ comp = partner.GetFertileMenstruationComp();
+ else comp = partner.GetRandomMenstruationComp();
+ if (comp == null)
{
- if (AndroidsCompatibility.IsAndroid(pawn) && !AndroidsCompatibility.AndroidPenisFertility(pawn))
- {
- comp.CumIn(pawn, pawn.GetCumVolume(), 0);
- return false;
- }
- else comp.CumIn(pawn, pawn.GetCumVolume(), pawn.health.capacities.GetLevel(xxx.reproduction));
+ if (Configurations.Debug) ModLog.Message("used original rjw method: Comp missing");
+ return true;
+ }
+ else if (AndroidsCompatibility.IsAndroid(pawn) && !AndroidsCompatibility.AndroidPenisFertility(pawn))
+ {
+ comp.CumIn(pawn, pawn.GetCumVolume(), 0);
return false;
}
- ModLog.Message("used original rjw method: Comp missing");
- return true;
+ else comp.CumIn(pawn, pawn.GetCumVolume(), pawn.health.capacities.GetLevel(xxx.reproduction));
+ return false;
+ }
+ }
+
+ [HarmonyPatch(typeof(PregnancyHelper), nameof(PregnancyHelper.CanImpregnate))]
+ public static class CanImpregnate_Patch
+ {
+ private static bool PregnancyBlocksImpregnation(this Pawn pawn, bool _)
+ {
+ if (!Configurations.EnableAnimalCycle && pawn.IsAnimal()) return pawn.IsPregnant();
+ else if (pawn.GetMenstruationComps().Any()) return false;
+ else return pawn.IsPregnant();
+ }
+ private static readonly MethodInfo IsPregnant = AccessTools.Method(typeof(PawnExtensions), nameof(PawnExtensions.IsPregnant), new System.Type[] {typeof(Pawn), typeof(bool)});
+ public static IEnumerable Transpiler(IEnumerable instructions)
+ {
+ if (IsPregnant == null) throw new System.InvalidOperationException("IsPregnant not found");
+ foreach(CodeInstruction instruction in instructions)
+ {
+ if (instruction.Calls(IsPregnant))
+ yield return CodeInstruction.Call(typeof(CanImpregnate_Patch), nameof(PregnancyBlocksImpregnation));
+ else yield return instruction;
+ }
}
}
[HarmonyPatch(typeof(Hediff_BasePregnancy), nameof(Hediff_BasePregnancy.PostBirth))]
public static class RJW_Patch_PostBirth
{
- public static void Postfix(Pawn mother, Pawn baby)
+ public static void Postfix(Hediff_BasePregnancy __instance, Pawn mother, Pawn baby)
{
if (Configurations.EnableBirthVaginaMorph)
{
- Hediff vagina = mother.health.hediffSet.hediffs.FirstOrFallback(x => x.def.defName.ToLower().Contains("vagina"));
- float morph = Mathf.Max(baby.BodySize - Mathf.Pow(vagina.Severity * mother.BodySize,2), 0f);
+ // The comp still has the pregnancy attached at this point in the process
+ Hediff vagina = __instance.GetMenstruationComp()?.parent;
+ if (vagina == null) vagina = mother.health.hediffSet.hediffs.FirstOrFallback(x => VariousDefOf.AllVaginas.Contains(x.def));
+ if (vagina == null) return;
+ float morph = Mathf.Max(baby.BodySize - Mathf.Pow(vagina.Severity * mother.BodySize, 2), 0f);
vagina.Severity += morph * Configurations.VaginaMorphPower;
}
}
@@ -123,9 +167,9 @@ namespace RJW_Menstruation
// This is stricter than can_impregnate, so quickly filter out scenarios that are negative anyways.
if (__result == false || __instance != Quirk.ImpregnationFetish) return;
__result =
- ((PregnancyHelper.CanImpregnate(pawn, partner) && (partner.GetMenstruationComp()?.IsDangerDay ?? true))
+ (PregnancyHelper.CanImpregnate(pawn, partner) && (partner.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true))
||
- (PregnancyHelper.CanImpregnate(partner, pawn) && (pawn.GetMenstruationComp()?.IsDangerDay ?? true)));
+ (PregnancyHelper.CanImpregnate(partner, pawn) && (pawn.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true));
}
}
@@ -144,9 +188,9 @@ namespace RJW_Menstruation
else __result--;
if (
- (PregnancyHelper.CanImpregnate(pawn, partner, props.sexType) && (partner.GetMenstruationComp()?.IsDangerDay ?? true))
+ (PregnancyHelper.CanImpregnate(pawn, partner, props.sexType) && (partner.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true))
||
- (PregnancyHelper.CanImpregnate(partner, pawn, props.sexType) && (pawn.GetMenstruationComp()?.IsDangerDay ?? true)))
+ (PregnancyHelper.CanImpregnate(partner, pawn, props.sexType) && (pawn.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true)))
__result++;
}
}
@@ -176,7 +220,7 @@ namespace RJW_Menstruation
{
__result *= (1f + GetNetFertility(fucker, fucked) / 40);
}
- else if(xxx.is_animal(fucker) && fucked.IsInEstrus(true) && PregnancyHelper.CanImpregnate(fucker, fucked))
+ else if (xxx.is_animal(fucker) && fucked.IsInEstrus(true) && PregnancyHelper.CanImpregnate(fucker, fucked))
{
__result *= 1.25f;
}
@@ -195,10 +239,11 @@ namespace RJW_Menstruation
private static readonly FieldInfo MinimumFuckabilityToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumFuckabilityToHookup));
public static IEnumerable Transpiler(IEnumerable instructions)
{
+ if (MinimumFuckabilityToHookup == null) throw new System.InvalidOperationException("MinimumFuckabilityToHookup not found");
bool first_fuckability = true;
- foreach(CodeInstruction instruction in instructions)
+ foreach (CodeInstruction instruction in instructions)
{
- if(instruction.LoadsField(MinimumFuckabilityToHookup))
+ if (instruction.LoadsField(MinimumFuckabilityToHookup))
{
// The first load will be for the estrus-haver considering a partner, the second for a pawn considering the estrus-haver
yield return new CodeInstruction(first_fuckability ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1);
@@ -230,14 +275,16 @@ namespace RJW_Menstruation
private static readonly FieldInfo MinimumRelationshipToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumRelationshipToHookup));
public static IEnumerable Transpiler(IEnumerable instructions)
{
+ if (MinimumAttractivenessToHookup == null) throw new System.InvalidOperationException("MinimumAttractivenessToHookup not found");
+ if (MinimumRelationshipToHookup == null) throw new System.InvalidOperationException("MinimumRelationshipToHookup not found");
LocalBuilder pawn_index = null;
// Like in the last one, we switch the arguments around for the second load
bool first_attractiveness = true;
bool first_relationship = true;
- foreach(CodeInstruction instruction in instructions)
+ foreach (CodeInstruction instruction in instructions)
{
// Get where the compiler decided to index the pawn at
- if (pawn_index is null && instruction.opcode == OpCodes.Stloc_S) // the first stloc.s in the IL is the pawn being loaded out of the list
+ if (pawn_index == null && instruction.opcode == OpCodes.Stloc_S) // the first stloc.s in the IL is the pawn being loaded out of the list
{ // a future RJW or compiler update might change this, or maybe another mod's patch
pawn_index = (LocalBuilder)instruction.operand;
yield return instruction;
@@ -252,7 +299,7 @@ namespace RJW_Menstruation
yield return CodeInstruction.Call(typeof(FindBestPartner_Patch), nameof(AttractivenessThreshold));
first_attractiveness = false;
- }
+ }
else if (instruction.LoadsField(MinimumRelationshipToHookup))
{
if (pawn_index?.LocalType != typeof(Pawn))
@@ -269,6 +316,21 @@ namespace RJW_Menstruation
}
}
+ [HarmonyPatch(typeof(JobDriver_Sex), nameof(JobDriver_Sex.PlayCumSound))]
+ public static class Orgasm_Patch
+ {
+ public static void Postfix(JobDriver_Sex __instance)
+ {
+#if false
+ Pawn pawn = __instance.pawn;
+ foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
+ {
+ comp.CumIn(pawn, (comp.parent.Severity / 10) * Rand.Range(0.75f, 1.25f), pawn.Label, -5.0f, VariousDefOf.GirlCumFilth);
+ }
+#endif
+ }
+ }
+
[HarmonyPatch(typeof(CompHediffBodyPart), nameof(CompHediffBodyPart.updatesize))]
public static class Updatesize_Patch
{
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 7efb672..198c10f 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj
@@ -101,6 +101,7 @@
..\..\..\..\..\rjw\1.3\Assemblies\RJW.dll
False
+
..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll
@@ -158,7 +159,7 @@
2.1.1
- runtime
+ runtime
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 89ed888..6a1f8b8 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs
@@ -1,11 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RimWorld;
-using Verse;
+using RimWorld;
using rjw;
+using System.Collections.Generic;
+using Verse;
namespace RJW_Menstruation
@@ -23,7 +19,7 @@ namespace RJW_Menstruation
BodyPartRecord part = Genital_Helper.get_breastsBPR(pawn);
if (part != null)
{
-
+
if (pawn.GetBreastComp() != null) yield return part;
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs
index 1289c0f..8df18e6 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs
@@ -22,14 +22,14 @@ namespace RJW_Menstruation
public static object GetPropertyValue(this Type type, string name)
{
BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
- PropertyInfo propertyInfo = type?.GetProperty(name,flags);
+ PropertyInfo propertyInfo = type?.GetProperty(name, flags);
return propertyInfo?.GetValue(null);
}
public static object GetPropertyValue(this object obj, string name)
{
BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
- PropertyInfo propertyInfo = obj?.GetType().GetProperty(name,flags);
+ PropertyInfo propertyInfo = obj?.GetType().GetProperty(name, flags);
return propertyInfo?.GetValue(obj);
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs
index 937fdb9..f383986 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs
@@ -1,11 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RimWorld;
+using UnityEngine;
using Verse;
-using UnityEngine;
namespace RJW_Menstruation
{
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Things.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Things.cs
index 324f428..e427e0f 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Things.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Things.cs
@@ -1,8 +1,7 @@
-using System;
-using System.Xml;
-using System.Collections.Generic;
-using RimWorld;
+using RimWorld;
using rjw;
+using System.Collections.Generic;
+using System.Xml;
using UnityEngine;
using Verse;
@@ -20,10 +19,7 @@ namespace RJW_Menstruation
public HybridExtension GetHybridExtension(string race)
{
if (hybridExtension.NullOrEmpty()) return null;
- else
- {
- return hybridExtension.Find(x => x.thingDef.defName.Equals(race));
- }
+ else return hybridExtension.Find(x => x.thingDef.defName.Equals(race));
}
public PawnKindDef GetHybridWith(string race)
@@ -67,21 +63,15 @@ namespace RJW_Menstruation
{
DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(this, "thingDef", xmlRoot.Name);
XmlNodeList childNodes = xmlRoot.ChildNodes;
-
+
if (childNodes.Count >= 1) foreach (XmlNode node in childNodes)
{
- #if DEBUG
- Log.Message(xmlRoot.Name + "HybridInfo: " + node.Name + " " + node.InnerText);
- #endif
+#if DEBUG
+ Log.Message(xmlRoot.Name + "HybridInfo: " + node.Name + " " + node.InnerText);
+#endif
hybridInfo.Add(node.Name, ParseHelper.FromString(node.InnerText));
}
-
-
-
}
-
-
-
}
public class HybridInformations : IExposable
@@ -145,9 +135,6 @@ namespace RJW_Menstruation
Scribe_Values.Look(ref thingDefName, "thingDefName");
Scribe_Collections.Look(ref hybridExtension, "hybridExtension", LookMode.Deep, new object[0]);
}
-
-
-
}
public class HybridExtensionExposable : HybridExtension, IExposable
@@ -197,10 +184,6 @@ namespace RJW_Menstruation
}
}
-
-
-
-
public class AbsorberModExtension : DefModExtension
{
public bool leakAfterDirty = false;
@@ -222,14 +205,12 @@ namespace RJW_Menstruation
public Color fluidColor = Color.white;
-
-
public virtual void DirtyEffect() { }
public virtual void WearEffect()
{
absorbedfluids += 0.1f;
- if(dirty) wearhours++;
+ if (dirty) wearhours++;
}
public override Color DrawColorTwo => fluidColor;
@@ -250,7 +231,7 @@ namespace RJW_Menstruation
public override void WearEffect()
{
- if(dirty) wearhours++;
+ if (dirty) wearhours++;
absorbedfluids += 0.5f;
}
@@ -299,13 +280,5 @@ namespace RJW_Menstruation
color = value;
}
}
-
-
-
}
-
-
-
-
-
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs
index 5260ed4..6189613 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Translations.cs
@@ -11,7 +11,6 @@ namespace RJW_Menstruation
public static readonly string Stage_Ovulatory = "Stage_Ovulatory".Translate();
public static readonly string Stage_Luteal = "Stage_Luteal".Translate();
public static readonly string Stage_Bleeding = "Stage_Bleeding".Translate();
- public static readonly string Stage_Fertilized = "Stage_Fertilized".Translate();
public static readonly string Stage_Pregnant = "Stage_Pregnant".Translate();
public static readonly string Stage_Recover = "Stage_Recover".Translate();
public static readonly string Stage_None = "Stage_None".Translate();
@@ -100,23 +99,23 @@ namespace RJW_Menstruation
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 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 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 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 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();
- public static readonly string Option29_Desc = "Option29_Desc".Translate();
+ public static readonly string Option29_Desc = "Option29_Desc".Translate();
public static readonly string Option30_Label = "Option30_Label".Translate();
- public static readonly string Option30_Desc = "Option30_Desc".Translate();
+ public static readonly string Option30_Desc = "Option30_Desc".Translate();
public static readonly string Option31_Label = "Option31_Label".Translate();
- public static readonly string Option31_Desc = "Option31_Desc".Translate();
+ 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 Option32_Desc = "Option32_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_HybridCustom.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_HybridCustom.cs
index a0fbb49..4df0978 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_HybridCustom.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_HybridCustom.cs
@@ -1,10 +1,7 @@
-using System;
+using RimWorld;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RimWorld;
-using rjw;
using UnityEngine;
using Verse;
using Verse.Sound;
@@ -26,17 +23,11 @@ namespace RJW_Menstruation
public void BuildRaceList()
{
raceList.Clear();
- if (!VariousDefOf.AllRaces.NullOrEmpty())
- foreach(ThingDef def in VariousDefOf.AllRaces)
+ if (!VariousDefOf.AllRaces.NullOrEmpty())
+ foreach (ThingDef def in VariousDefOf.AllRaces)
{
- if (def.race != null)
- {
- if (Configurations.IsOverrideExist(def)) continue;
- else
- {
- raceList.Add(new FloatMenuOption(def.label, delegate { AddHybridOverride(def);}, def.uiIcon, Color.white ));
- }
- }
+ if (def.race == null || Configurations.IsOverrideExist(def)) continue;
+ raceList.Add(new FloatMenuOption(def.label, delegate { AddHybridOverride(def); }, def.uiIcon, Color.white));
}
raceList.SortBy(x => x.Label);
}
@@ -44,17 +35,15 @@ namespace RJW_Menstruation
public void AddHybridOverride(ThingDef def)
{
FloatMenuOption option = raceList.FirstOrDefault(x => x.Label.Equals(def?.label));
- if (option != null)
+ if (option == null) return;
+ raceList.Remove(option);
+ if (Configurations.HybridOverride.NullOrEmpty())
{
- raceList.Remove(option);
- if (Configurations.HybridOverride.NullOrEmpty())
- {
- Configurations.HybridOverride = new List();
- }
- Configurations.HybridOverride.Add(new HybridInformations(def));
- Configurations.HybridOverride.SortBy(x => x.GetDef?.label ?? "Undefined");
+ Configurations.HybridOverride = new List();
}
-
+ Configurations.HybridOverride.Add(new HybridInformations(def));
+ Configurations.HybridOverride.SortBy(x => x.GetDef?.label ?? "Undefined");
+
}
public override Vector2 InitialSize
@@ -124,7 +113,7 @@ namespace RJW_Menstruation
buttonRect.x -= 100;
if (Widgets.ButtonText(buttonRect, "Undo"))
{
- var element = removeList.Last();
+ HybridInformations element = removeList.Last();
Configurations.HybridOverride.Add(element);
Configurations.HybridOverride.SortBy(x => x.GetDef?.label ?? "Undefined");
removeList.Remove(element);
@@ -138,17 +127,17 @@ namespace RJW_Menstruation
}
-
+
Rect outRect = new Rect(inRect.x, inRect.y + 30f, inRect.width, inRect.height - 30f);
- Rect mainRect = new Rect(inRect.x, inRect.y + 30f, inRect.width - 30f, Math.Max(24f*Configurations.HybridOverride?.Count() ?? 1,10f));
+ Rect mainRect = new Rect(inRect.x, inRect.y + 30f, inRect.width - 30f, Math.Max(24f * Configurations.HybridOverride?.Count() ?? 1, 10f));
Listing_Standard listmain = new Listing_Standard();
-
+
Widgets.BeginScrollView(outRect, ref scroll, mainRect);
listmain.Begin(mainRect);
- if (!Configurations.HybridOverride.NullOrEmpty())
- foreach(HybridInformations extension in Configurations.HybridOverride)
+ if (!Configurations.HybridOverride.NullOrEmpty())
+ foreach (HybridInformations extension in Configurations.HybridOverride)
{
- if (extension.GetDef != null) DoRow(listmain.GetRect(24f),extension);
+ if (extension.GetDef != null) DoRow(listmain.GetRect(24f), extension);
}
Widgets.EndScrollView();
listmain.End();
@@ -266,7 +255,7 @@ namespace RJW_Menstruation
SoundDefOf.TabClose.PlayOneShotOnCamera();
Find.WindowStack.Add(new Dialog_EditHybrid(info));
}
-
+
}
@@ -279,18 +268,19 @@ namespace RJW_Menstruation
protected void BuildRaceList()
{
raceList.Clear();
- if (!VariousDefOf.AllRaces.NullOrEmpty())
- foreach (ThingDef def in VariousDefOf.AllRaces)
+ if (VariousDefOf.AllRaces.NullOrEmpty()) return;
+
+ foreach (ThingDef def in VariousDefOf.AllRaces)
+ {
+ if (def.race != null)
{
- if (def.race != null)
+ if (info.hybridExtension.Exists(x => x.DefName == def.defName)) continue;
+ else
{
- if (info.hybridExtension.Exists(x => x.DefName == def.defName)) continue;
- else
- {
- raceList.Add(new FloatMenuOption(def.label, delegate { AddHybridInfo(def); }, Widgets.GetIconFor(def), Color.white));
- }
+ raceList.Add(new FloatMenuOption(def.label, delegate { AddHybridInfo(def); }, Widgets.GetIconFor(def), Color.white));
}
}
+ }
raceList.SortBy(x => x.Label);
}
@@ -320,11 +310,11 @@ namespace RJW_Menstruation
buttonRect.x -= 100;
if (Widgets.ButtonText(buttonRect, "Undo"))
{
- var element = removeList.Last();
+ HybridExtensionExposable element = removeList.Last();
info.hybridExtension.Add(element);
removeList.Remove(element);
}
-
+
foreach (HybridExtensionExposable element in removeList)
{
info.hybridExtension.Remove(element);
@@ -333,7 +323,7 @@ namespace RJW_Menstruation
float additionalHeight = 0f;
- if (!info.hybridExtension.NullOrEmpty()) foreach(HybridExtensionExposable e in info.hybridExtension)
+ if (!info.hybridExtension.NullOrEmpty()) foreach (HybridExtensionExposable e in info.hybridExtension)
{
additionalHeight += (e.hybridInfo?.Count() ?? 1) * rowH;
}
@@ -356,7 +346,7 @@ namespace RJW_Menstruation
}
-
+
Widgets.EndScrollView();
listmain.End();
}
@@ -376,7 +366,7 @@ namespace RJW_Menstruation
if (Widgets.ButtonText(buttonRect, "Add"))
{
List list = new List();
- if (!VariousDefOf.AllRaces.NullOrEmpty()) foreach(ThingDef def in VariousDefOf.AllRaces)
+ if (!VariousDefOf.AllRaces.NullOrEmpty()) foreach (ThingDef def in VariousDefOf.AllRaces)
{
if (def.race != null)
{
@@ -392,7 +382,7 @@ namespace RJW_Menstruation
list.SortBy(x => x.Label);
Find.WindowStack.Add(new FloatMenu(list));
}
-
+
}
buttonRect.x -= 80f;
@@ -403,18 +393,18 @@ namespace RJW_Menstruation
if (!extension.hybridInfo.EnumerableNullOrEmpty())
{
totalWeight = 0;
- foreach(KeyValuePair element in extension.hybridInfo)
+ foreach (KeyValuePair element in extension.hybridInfo)
{
totalWeight += element.Value;
}
-
+
List keys = new List(extension.hybridInfo.Keys);
foreach (string key in keys)
{
DoSubRow(sublist.GetRect(rowH), key, extension, removeelements);
}
}
- if(!removeelements.NullOrEmpty()) foreach(string key in removeelements)
+ if (!removeelements.NullOrEmpty()) foreach (string key in removeelements)
{
extension.hybridInfo.Remove(key);
}
@@ -425,7 +415,7 @@ namespace RJW_Menstruation
}
- protected void DoSubRow(Rect rect, string key, HybridExtensionExposable extension , List removeelements)
+ protected void DoSubRow(Rect rect, string key, HybridExtensionExposable extension, List removeelements)
{
bool isPawnKind = false;
int value = (int)extension.hybridInfo.TryGetValue(key);
@@ -471,15 +461,15 @@ namespace RJW_Menstruation
}
label += ": " + key;
Widgets.Label(rect, " - " + label);
- Widgets.TextFieldNumeric(buttonRect, ref value, ref valuestr,0,9999999);
+ Widgets.TextFieldNumeric(buttonRect, ref value, ref valuestr, 0, 9999999);
extension.hybridInfo.SetOrAdd(key, value);
buttonRect.x -= 80f;
Widgets.Label(buttonRect, String.Format("{0,0:P2}", value / totalWeight));
Widgets.DrawHighlightIfMouseover(rect);
- TooltipHandler.TipRegion(rect, Translations.CustomHybrid_Tooltip(info.GetDef?.label ?? "Undefined", extension.GetDef?.label ?? "Undefined", label, String.Format("{0,0:0.########%}", value/totalWeight)));
+ TooltipHandler.TipRegion(rect, Translations.CustomHybrid_Tooltip(info.GetDef?.label ?? "Undefined", extension.GetDef?.label ?? "Undefined", label, String.Format("{0,0:0.########%}", value / totalWeight)));
}
-
+
}
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 63d8537..7bbbfad 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
@@ -1,7 +1,7 @@
-using System;
-using System.Collections.Generic;
-using RimWorld;
+using RimWorld;
using rjw;
+using System;
+using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;
@@ -92,7 +92,7 @@ namespace RJW_Menstruation
int index = pawns.IndexOf(window.pawn);
SoundDefOf.TabOpen.PlayOneShotOnCamera();
Pawn newpawn = pawns[(index + 1) % pawns.Count];
- window.ChangePawn(newpawn, newpawn.GetMenstruationComp());
+ window.ChangePawn(newpawn, newpawn.GetFirstMenstruationComp());
}
else if (window.pawn != pawn)
{
@@ -151,16 +151,15 @@ namespace RJW_Menstruation
fontstyleleft.normal.textColor = Color.white;
float preginfoheight = 0f;
- bool pregnant = pawn.IsPregnant();
- Hediff hediff = PregnancyHelper.GetPregnancy(pawn);
- if (pregnant && Utility.ShowFetusImage((Hediff_BasePregnancy)hediff))
+ Hediff_BasePregnancy hediff = comp.Pregnancy;
+ if (hediff != null && Utility.ShowFetusImage(hediff))
{
womb = comp.GetPregnancyIcon(hediff);
if (hediff is Hediff_MultiplePregnancy m)
{
if (m.GestationProgress < 0.2f) cum = comp.GetCumIcon();
else cum = ContentFinder.Get(("Womb/Empty"), true);
- Pawn fetus = pawn.GetFetus();
+ Pawn fetus = comp.GetFetus();
if (fetus != null && Utility.ShowFetusInfo())
{
string feinfo = m.GetBabyInfo();
@@ -188,7 +187,7 @@ namespace RJW_Menstruation
{
if (b.GestationProgress < 0.2f) cum = comp.GetCumIcon();
else cum = ContentFinder.Get(("Womb/Empty"), true);
- Pawn fetus = pawn.GetFetus();
+ Pawn fetus = comp.GetFetus();
if (fetus != null && Utility.ShowFetusInfo())
{
preginfoheight = fontheight;
@@ -230,7 +229,7 @@ namespace RJW_Menstruation
if (pawn.story != null) GUI.Label(pawnLabel2Rect, pawn.ageTracker.AgeBiologicalYears + ", " + pawn.story.Title, fontstylecenter);
GUI.color = Color.white;
-
+
float wombrecth = 0;
if (Configurations.DrawWombStatus)
{
@@ -249,7 +248,7 @@ namespace RJW_Menstruation
}
Rect wombInfoRect = new Rect(0f, mainRect.yMax - wombrecth - fontheight - 2, wombRectWidth, fontheight - 4f);
- Rect progressRect = new Rect(wombInfoRect.x,wombInfoRect.yMax,wombRectWidth, 4f);
+ Rect progressRect = new Rect(wombInfoRect.x, wombInfoRect.yMax, wombRectWidth, 4f);
buttonstyle.normal.textColor = Color.white;
//boxstyle.normal.background = Texture2D.whiteTexture;
buttonstyle.alignment = TextAnchor.MiddleLeft;
@@ -286,7 +285,7 @@ namespace RJW_Menstruation
cumlistRect = new Rect(pawnRectWidth, fontheight, 150f, mainRect.yMax - wombRectHeight - fontheight);
}
- Rect infoRect = new Rect(0, pawnRectHeight + 2*fontheight, pawnRectWidth, pawnRect.yMax + 2*fontheight - wombInfoRect.y);
+ Rect infoRect = new Rect(0, pawnRectHeight + 2 * fontheight, pawnRectWidth, pawnRect.yMax + 2 * fontheight - wombInfoRect.y);
DrawInfos(infoRect);
@@ -369,7 +368,7 @@ namespace RJW_Menstruation
GUI.color = new Color(1.00f, 0.47f, 0.47f, 1);
GUI.Box(rect, "", boxstyle);
-
+
pawn.DrawBreastIcon(BreastIconRect, Mouse.IsOver(BreastIconRect) && Input.GetMouseButton(0));
@@ -388,11 +387,11 @@ namespace RJW_Menstruation
float statvalue;
const float height = 24f;
statvalue = pawn.GetStatValue(xxx.sex_drive_stat);
- FillableBarLabeled(lineRect, " " + xxx.sex_drive_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue/2 ,TextureCache.SlaaneshTexture,Texture2D.blackTexture, xxx.sex_drive_stat.description);
+ FillableBarLabeled(lineRect, " " + xxx.sex_drive_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue / 2, TextureCache.SlaaneshTexture, Texture2D.blackTexture, xxx.sex_drive_stat.description);
lineRect.y += height;
statvalue = pawn.GetStatValue(xxx.vulnerability_stat);
- FillableBarLabeled(lineRect, " " + xxx.vulnerability_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue/2, TextureCache.KhorneTexture,Texture2D.blackTexture, xxx.vulnerability_stat.description);
+ FillableBarLabeled(lineRect, " " + xxx.vulnerability_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue / 2, TextureCache.KhorneTexture, Texture2D.blackTexture, xxx.vulnerability_stat.description);
lineRect.y += height;
statvalue = pawn.GetStatValue(xxx.sex_stat);
@@ -409,27 +408,11 @@ namespace RJW_Menstruation
statvalue = pawn.records.GetValue(xxx.CountOfBirthEgg);
FillableBarLabeled(lineRect, " " + xxx.CountOfBirthEgg.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 100, TextureCache.NurgleTexture, Texture2D.blackTexture, xxx.CountOfBirthEgg.description);
- lineRect.y += height;
-
- statvalue = pawn.records.GetValue(xxx.CountOfWhore);
- if (statvalue > 0)
- {
- FillableBarLabeled(lineRect, " " + xxx.CountOfWhore.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 50, TextureCache.SlaaneshTexture, Texture2D.blackTexture, xxx.CountOfWhore.description);
- statvalue = pawn.records.GetValue(xxx.EarnedMoneyByWhore);
- lineRect.y += height;
- FillableBarLabeled(lineRect, " " + VariousDefOf.RJW_EarnedMoneyByWhore.label.CapitalizeFirst() + " " + statvalue, statvalue / 10000, TextureCache.GhalmarazTexture, Texture2D.blackTexture);
-
- lineRect.y += height;
- }
- else
- {
- lineRect.y += height;
- lineRect.y += height;
- }
+ lineRect.y += height * 3;
statvalue = Configurations.ImplantationChance * comp.ImplantFactor;
float fertchance = comp.GetFertilityChance();
- FillableBarLabeled(lineRect, " " + xxx.reproduction.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue, TextureCache.FertilityTexture, Texture2D.blackTexture, Translations.FertilityDesc(String.Format("{0:0.##}", fertchance*100)));
+ FillableBarLabeled(lineRect, " " + xxx.reproduction.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue, TextureCache.FertilityTexture, Texture2D.blackTexture, Translations.FertilityDesc(String.Format("{0:0.##}", fertchance * 100)));
Rect overayRect = new Rect(lineRect.x, lineRect.y, lineRect.width * Math.Min(1.0f, fertchance), lineRect.height);
GUI.DrawTexture(overayRect, TextureCache.FertChanceTex);
lineRect.y += height;
@@ -437,7 +420,7 @@ namespace RJW_Menstruation
private void FillableBarLabeled(Rect rect, string label, float fillPercent, Texture2D filltexture, Texture2D bgtexture, string tooltip = null)
{
- Widgets.FillableBar(rect, Math.Min(fillPercent,1.0f), filltexture, bgtexture, true);
+ Widgets.FillableBar(rect, Math.Min(fillPercent, 1.0f), filltexture, bgtexture, true);
GUI.Label(rect, label, fontstyleleft);
Widgets.DrawHighlightIfMouseover(rect);
if (tooltip != null) TooltipHandler.TipRegion(rect, tooltip);
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs
index 57f8dd1..7b60c02 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs
@@ -37,7 +37,7 @@ namespace RJW_Menstruation
Widgets.FillableBar(progressRect, comp.StageProgress, comp.GetStageTexture);
}
-
+
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs
index 095b740..38d40a3 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Utility.cs
@@ -1,13 +1,11 @@
using RimWorld;
using rjw;
using System;
-using System.Linq;
using System.Collections.Generic;
+using System.Linq;
using UnityEngine;
using Verse;
using Verse.Sound;
-using System.Threading;
-using System.Threading.Tasks;
namespace RJW_Menstruation
@@ -16,7 +14,7 @@ namespace RJW_Menstruation
{
public static Color blood = new Color(0.78f, 0, 0);
//public static Color nippleblack = new Color(0.215f, 0.078f, 0); // 81,20,0
- public static ColorInt white = new ColorInt(255,255,255,255);
+ public static ColorInt white = new ColorInt(255, 255, 255, 255);
@@ -49,10 +47,15 @@ namespace RJW_Menstruation
public static class Utility
{
- public static System.Random random = new System.Random(Environment.TickCount);
-
-
-
+ public static PawnKindDef GetRacesPawnKind(Pawn pawn)
+ {
+ if (pawn == null) return null;
+ if (pawn.kindDef?.race == pawn.def) return pawn.kindDef;
+ return VariousDefOf.AllKinds.Find(kind => kind.race == pawn.def && kind.defName.Contains("Colonist")) ??
+ VariousDefOf.AllKinds.Find(kind => kind.race == pawn.def) ??
+ pawn.def.race?.AnyPawnKind ??
+ pawn.kindDef;
+ }
public static float GetCumVolume(this Pawn pawn)
{
@@ -94,16 +97,13 @@ namespace RJW_Menstruation
public static HediffComp_Breast GetBreastComp(this Pawn pawn)
{
- var hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn))?.FindAll((Hediff h) => h is Hediff_PartBaseNatural || h is Hediff_PartBaseArtifical);
+ List hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn))?.FindAll((Hediff h) => h is Hediff_PartBaseNatural || h is Hediff_PartBaseArtifical);
HediffComp_Breast result;
if (hedifflist.NullOrEmpty()) return null;
- else
+ foreach (Hediff h in hedifflist)
{
- foreach(Hediff h in hedifflist)
- {
- result = h.TryGetComp();
- if (result != null) return result;
- }
+ result = h.TryGetComp();
+ if (result != null) return result;
}
return null;
}
@@ -125,66 +125,43 @@ namespace RJW_Menstruation
public static bool HasMenstruationComp(this Pawn pawn)
{
- var hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll((Hediff h) => h.def.defName.ToLower().Contains("vagina"));
- HediffComp_Menstruation result;
- if (hedifflist.NullOrEmpty()) return false;
- else
- {
- foreach (Hediff h in hedifflist)
- {
- result = h.TryGetComp();
- if (result != null) return true;
- }
- }
- return false;
+ return pawn.GetMenstruationComps().Any();
}
public static bool HasMenstruationComp(this Hediff hediff)
{
- if (hediff is Hediff_PartBaseNatural || hediff is Hediff_PartBaseArtifical)
+ if ((hediff is Hediff_PartBaseNatural || hediff is Hediff_PartBaseArtifical) && hediff.TryGetComp() != null)
+ return true;
+ else return false;
+ }
+
+
+ public static float GetFarthestPregnancyProgress(this Pawn pawn)
+ {
+ return pawn.health.hediffSet.GetHediffs().MaxBy(hediff => hediff.GestationProgress)?.GestationProgress ?? -1;
+ }
+
+ public static float GetPregnancyProgress(this HediffComp_Menstruation comp)
+ {
+ if (comp.Pregnancy == null) return -1;
+ else return comp.Pregnancy.GestationProgress;
+ }
+
+ public static Pawn GetFetus(this HediffComp_Menstruation comp)
+ {
+ if (comp.Pregnancy == null) return null;
+ if (!comp.Pregnancy.babies.NullOrEmpty()) return comp.Pregnancy.babies.First();
+ else
{
- if (hediff.TryGetComp() != null) return true;
+ Log.Error("Baby not exist: baby was not created or removed. Remove pregnancy.");
+ comp.Pregnancy.Miscarry();
+ return null;
}
- return false;
}
-
- public static float GetPregnancyProgress(this Pawn pawn)
+ public static void DrawBreastIcon(this Pawn pawn, Rect rect, bool drawOrigin = false)
{
- Hediff hediff = PregnancyHelper.GetPregnancy(pawn);
- if (hediff is Hediff_BasePregnancy h)
- {
- return h.GestationProgress;
- }
- return -1;
- }
-
- public static Pawn GetFetus(this Pawn pawn)
- {
- Hediff hediff = PregnancyHelper.GetPregnancy(pawn);
- if (hediff is Hediff_BasePregnancy h)
- {
- if (!h.babies.NullOrEmpty()) return h.babies.First();
- else
- {
- Log.Error("Baby not exist: baby was not created or removed. Remove pregnancy.");
- pawn.health.RemoveHediff(hediff);
- return null;
- }
- }
-
-
- return null;
- }
-
- public static Hediff_BasePregnancy GetRJWPregnancy(this Pawn pawn)
- {
- return (Hediff_BasePregnancy)pawn.health.hediffSet.hediffs.FirstOrDefault(x => x is Hediff_BasePregnancy);
- }
-
- public static void DrawBreastIcon(this Pawn pawn, Rect rect , bool drawOrigin = false)
- {
- var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("breast"));
+ 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;
if (hediff != null)
{
@@ -227,7 +204,7 @@ namespace RJW_Menstruation
nippleicon = icon + "_Nipple0" + GetNippleIndex(nipplesize);
areolaicon = icon + "_Areola0" + GetAreolaIndex(areolasize);
-
+
breast = ContentFinder.Get(icon, false);
areola = ContentFinder.Get(areolaicon, false);
@@ -299,78 +276,75 @@ namespace RJW_Menstruation
milkcomp = pawn.GetComp();
}
- if (milkcomp != null)
+ if (milkcomp == null) return;
+ if (milkcomp is CompMilkable milkable)
{
- if (milkcomp is CompMilkable milkable)
+ bool active = (bool)milkcomp.GetPropertyValue("Active");
+ if (active)
{
- bool active = (bool)milkcomp.GetPropertyValue("Active");
- if (active)
- {
- CompMilkable m = milkable;
- res = Math.Max(m.Fullness, res);
- Widgets.FillableBar(rect, Math.Min(res, 1.0f), TextureCache.MilkTexture, Texture2D.blackTexture, true);
- DrawMilkBottle(rect, pawn, VariousDefOf.Job_LactateSelf, m.Fullness);
- }
+ CompMilkable m = milkable;
+ res = Math.Max(m.Fullness, res);
+ Widgets.FillableBar(rect, Math.Min(res, 1.0f), TextureCache.MilkTexture, Texture2D.blackTexture, true);
+ DrawMilkBottle(rect, pawn, VariousDefOf.Job_LactateSelf, m.Fullness);
}
- else
+ }
+ else
+ {
+ bool active = (bool)milkcomp.GetPropertyValue("Active");
+ if (active)
{
- bool active = (bool)milkcomp.GetPropertyValue("Active");
- if (active)
- {
- float fullness = (float)milkcomp.GetMemberValue("fullness");
- res = Math.Max(fullness, res);
- Widgets.FillableBar(rect, Math.Min(res, 1.0f), TextureCache.MilkTexture, Texture2D.blackTexture, true);
- DrawMilkBottle(rect, pawn, VariousDefOf.Job_LactateSelf_MC, fullness);
- }
+ float fullness = (float)milkcomp.GetMemberValue("fullness");
+ res = Math.Max(fullness, res);
+ Widgets.FillableBar(rect, Math.Min(res, 1.0f), TextureCache.MilkTexture, Texture2D.blackTexture, true);
+ DrawMilkBottle(rect, pawn, VariousDefOf.Job_LactateSelf_MC, fullness);
}
}
}
- public static void DrawMilkBottle(Rect rect, Pawn pawn, JobDef milkjob,float fullness)
+ public static void DrawMilkBottle(Rect rect, Pawn pawn, JobDef milkjob, float fullness)
{
Texture2D texture;
Rect buttonrect = new Rect(rect.x, rect.y, rect.height, rect.height);
- if (fullness > 0.0f)
- {
- if (fullness < 0.3f) texture = ContentFinder.Get("Milk/Milkbottle_Small", false);
- else if (fullness < 0.7f) texture = ContentFinder.Get("Milk/Milkbottle_Medium", false);
- else texture = ContentFinder.Get("Milk/Milkbottle_Large", false);
- GUIContent icon = new GUIContent(texture);
- GUIStyle style = GUIStyle.none;
- style.normal.background = texture;
- string tooltip = Translations.Button_MilkTooltip;
+ if (fullness <= 0.0f) return;
- TooltipHandler.TipRegion(buttonrect, tooltip);
- if (GUI.Button(buttonrect, icon, style))
+ if (fullness < 0.3f) texture = ContentFinder.Get("Milk/Milkbottle_Small", false);
+ else if (fullness < 0.7f) texture = ContentFinder.Get("Milk/Milkbottle_Medium", false);
+ else texture = ContentFinder.Get("Milk/Milkbottle_Large", false);
+ GUIContent icon = new GUIContent(texture);
+ GUIStyle style = GUIStyle.none;
+ style.normal.background = texture;
+ string tooltip = Translations.Button_MilkTooltip;
+
+ TooltipHandler.TipRegion(buttonrect, tooltip);
+ if (GUI.Button(buttonrect, icon, style))
+ {
+ if (fullness < 0.1f
+ || !pawn.IsColonistPlayerControlled
+ || pawn.Downed) SoundDefOf.ClickReject.PlayOneShotOnCamera();
+ else
{
- if (fullness < 0.1f
- || !pawn.IsColonistPlayerControlled
- || pawn.Downed) SoundDefOf.ClickReject.PlayOneShotOnCamera();
- else
- {
- SoundDefOf.Click.PlayOneShotOnCamera();
- pawn.jobs.TryTakeOrderedJob(new Verse.AI.Job(milkjob, pawn));
- }
+ SoundDefOf.Click.PlayOneShotOnCamera();
+ pawn.jobs.TryTakeOrderedJob(new Verse.AI.Job(milkjob, pawn));
}
- Widgets.DrawHighlightIfMouseover(buttonrect);
}
+ Widgets.DrawHighlightIfMouseover(buttonrect);
}
public static string GetVaginaLabel(this Pawn pawn)
{
- var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)).Find((Hediff h) => h.def.defName.ToLower().Contains("vagina"));
+ Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)).Find(h => VariousDefOf.AllVaginas.Contains(h.def));
return hediff.LabelBase.CapitalizeFirst() + "\n(" + hediff.LabelInBrackets + ")" + "\n" + xxx.CountOfSex.LabelCap.CapitalizeFirst() + ": " + pawn.records.GetAsInt(xxx.CountOfSex);
}
public static string GetAnusLabel(this Pawn pawn)
{
- var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("anus"));
+ Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("anus"));
if (hediff != null) return hediff.LabelBase.CapitalizeFirst() + "\n(" + hediff.LabelInBrackets + ")";
else return "";
}
public static string GetBreastLabel(this Pawn pawn)
{
- var hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("breast"));
+ Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn)).FirstOrDefault((Hediff h) => h.def.defName.ToLower().Contains("breast"));
if (hediff != null) return hediff.LabelBase.CapitalizeFirst() + "\n(" + hediff.LabelInBrackets + ")";
else return "";
}
@@ -422,25 +396,20 @@ namespace RJW_Menstruation
{
Pawn res = pawn.GetFather();
if (res != null) return res;
- else
- {
-
- res = pawn.relations?.GetFirstDirectRelationPawn(PawnRelationDefOf.Parent, x => x != mother) ?? null;
- if (res == null) res = pawn.relations?.GetFirstDirectRelationPawn(VariousDefOf.Relation_birthgiver, x => x != mother) ?? null;
- return res;
- }
+ else res = pawn.relations?.GetFirstDirectRelationPawn(PawnRelationDefOf.Parent, x => x != mother) ?? null;
+ return res;
}
public static float RandGaussianLike(float min, float max, int iterations = 3)
{
- double res = 0;
+ float res = 0;
for (int i = 0; i < iterations; i++)
{
- res += random.NextDouble();
+ res += Rand.Value;
}
res /= iterations;
- return (float)res*(max-min) + min;
+ return res * (max - min) + min;
}
@@ -449,7 +418,7 @@ namespace RJW_Menstruation
float tmult = Mathf.Pow(1 - t, num);
return tmult * a + (1 - tmult) * b;
}
-
+
public static float VariationRange(this float num, float variant)
{
return num * Rand.Range(1.0f - variant, 1.0f + variant);
@@ -457,20 +426,7 @@ namespace RJW_Menstruation
public static bool ShouldShowWombGizmo(this Pawn pawn)
{
-
- if (Configurations.EnableWombIcon)
- {
- if (!pawn.IsAnimal())
- {
- return true;
- }
- else if (Configurations.EnableAnimalCycle)
- {
- return true;
- }
- }
- return false;
+ return Configurations.EnableWombIcon && (!pawn.IsAnimal() || Configurations.EnableAnimalCycle);
}
-
}
}
diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs
index 40ac6df..141d5c5 100644
--- a/1.3/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs
+++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs
@@ -1,8 +1,8 @@
using RimWorld;
using rjw;
-using System.Linq;
using System;
using System.Collections.Generic;
+using System.Linq;
using Verse;
namespace RJW_Menstruation
@@ -11,6 +11,7 @@ namespace RJW_Menstruation
{
public static readonly ThingDef CumFilth = DefDatabase.GetNamed("FilthCum");
+ public static readonly ThingDef GirlCumFilth = DefDatabase.GetNamed("FilthGirlCum");
public static readonly ThingDef Tampon = DefDatabase.GetNamed("Absorber_Tampon");
public static readonly ThingDef Tampon_Dirty = DefDatabase.GetNamed("Absorber_Tampon_Dirty");
public static readonly ThingDef FilthMixture = DefDatabase.GetNamed("FilthMixture");
@@ -22,9 +23,6 @@ namespace RJW_Menstruation
public static readonly HediffDef Hediff_Estrus_Concealed = DefDatabase.GetNamed("Hediff_Estrus_Concealed");
public static readonly HediffDef Hediff_ASA = DefDatabase.GetNamed("Hediff_ASA");
public static readonly StatDef MaxAbsorbable = DefDatabase.GetNamed("MaxAbsorbable");
- // Obsolete, kept for compatibility for now
- public static readonly PawnRelationDef Relation_birthgiver = DefDatabase.AllDefs.FirstOrDefault(d => d.defName == "RJW_Sire");
- public static readonly PawnRelationDef Relation_spawn = DefDatabase.AllDefs.FirstOrDefault(d => d.defName == "RJW_Pup");
public static readonly NeedDef SexNeed = DefDatabase.GetNamed("Sex");
public static readonly JobDef VaginaWashing = DefDatabase.GetNamed("VaginaWashing");
public static readonly JobDef Job_LactateSelf = DefDatabase.GetNamed("LactateSelf");
@@ -42,28 +40,26 @@ namespace RJW_Menstruation
public static readonly ThoughtDef UnwantedPregnancyMild = DefDatabase.GetNamed("UnwantedPregnancyMild");
public static readonly ThoughtDef TookContraceptivePill = DefDatabase.GetNamed("TookContraceptivePill");
public static readonly ThoughtDef HateTookContraceptivePill = DefDatabase.GetNamed("HateTookContraceptivePill");
- public static readonly HediffDef_PartBase Vagina = DefDatabase.GetNamed("Vagina");
- public static readonly CompProperties_Menstruation VaginaCompProperties = (CompProperties_Menstruation)Vagina.comps.FirstOrDefault(x => x is CompProperties_Menstruation);
+ public static readonly CompProperties_Menstruation HumanVaginaCompProperties = (CompProperties_Menstruation)Genital_Helper.average_vagina.comps.FirstOrDefault(x => x is CompProperties_Menstruation);
public static readonly KeyBindingDef OpenStatusWindowKey = DefDatabase.GetNamed("OpenStatusWindow");
- public static readonly PawnColumnDef RJW_EarnedMoneyByWhore = DefDatabase.GetNamed("RJW_EarnedMoneyByWhore");
public static readonly RecordDef AmountofCreampied = DefDatabase.GetNamed("AmountofCreampied");
public static readonly RecordDef AmountofFertilizedEggs = DefDatabase.GetNamed("AmountofFertilizedEggs");
+ public static readonly TaleDef TaleCameInside = DefDatabase.GetNamed("CameInside");
private static List allraces = null;
private static List allkinds = null;
+ private static HashSet allvaginas = null;
public static List AllRaces
{
get
{
- if (allraces == null)
- {
-
- List allThings = DefDatabase.AllDefsListForReading;
- allraces = allThings.FindAll(x => x.race != null && x.race.IsFlesh);
- }
+ if (allraces != null) return allraces;
+
+ List allThings = DefDatabase.AllDefsListForReading;
+ allraces = allThings.FindAll(x => x.race != null && x.race.IsFlesh);
return allraces;
}
}
@@ -71,16 +67,37 @@ namespace RJW_Menstruation
{
get
{
- if (allkinds == null)
- {
- List allKinds = DefDatabase.AllDefsListForReading;
- allkinds = allKinds.FindAll(x => x.race != null);
- }
+ if (allkinds != null) return allkinds;
+
+ List allKinds = DefDatabase.AllDefsListForReading;
+ allkinds = allKinds.FindAll(x => x.race != null);
return allkinds;
}
}
+ public static HashSet AllVaginas
+ {
+ get
+ {
+ if (allvaginas != null) return allvaginas;
+ allvaginas = new HashSet();
-
+ List allHediffs = DefDatabase.AllDefsListForReading;
+ foreach(HediffDef hediffDef in allHediffs)
+ {
+ if (hediffDef.comps.NullOrEmpty()) continue;
+ foreach (HediffCompProperties comp in hediffDef.comps)
+ {
+ if (comp.compClass == typeof(HediffComp_Menstruation) || comp.compClass.IsSubclassOf(typeof(HediffComp_Menstruation)))
+ {
+ allvaginas.Add(hediffDef);
+ break;
+ }
+ }
+ }
+
+ return allvaginas;
+ }
+ }
// Defs from Milkable Colonists
public static readonly HediffDef Hediff_Lactating_Drug = DefDatabase.GetNamedSilentFail("Lactating_Drug");
@@ -88,12 +105,5 @@ namespace RJW_Menstruation
public static readonly HediffDef Hediff_Lactating_Permanent = DefDatabase.GetNamedSilentFail("Lactating_Permanent");
public static readonly HediffDef Hediff_Heavy_Lactating_Permanent = DefDatabase.GetNamedSilentFail("Heavy_Lactating_Permanent");
public static readonly JobDef Job_LactateSelf_MC = DefDatabase.GetNamedSilentFail("LactateSelf_MC");
-
-
-
-
-
-
-
}
}
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/GatheredCumMixture.cs b/1.3/source/RJW_Menstruation/SexperienceModule/GatheredCumMixture.cs
index 1600282..b40ef61 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/GatheredCumMixture.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/GatheredCumMixture.cs
@@ -1,13 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Verse;
-using RimWorld;
-using RJWSexperience;
-using RJW_Menstruation;
+using System.Collections.Generic;
using UnityEngine;
+using Verse;
namespace RJW_Menstruation.Sexperience
{
@@ -34,8 +27,8 @@ namespace RJW_Menstruation.Sexperience
if (res && other is GatheredCumMixture mixture)
{
GatheredCumMixture othercum = mixture;
- cumColor = Colors.CMYKLerp(cumColor,othercum.cumColor,count/(amount+count));
- if (!othercum.ingredients.NullOrEmpty()) for (int i=0; i MakeNewToils()
{
-
- HediffComp_Menstruation Comp = pawn.GetMenstruationComp();
//this.FailOn(delegate
//{
// return !(Comp.TotalCumPercent > 0.001);
@@ -38,23 +31,26 @@ namespace RJW_Menstruation.Sexperience
{
initAction = delegate ()
{
- if (Comp.TotalCumPercent > 0.001)
- {
- CumMixture mixture = Comp.MixtureOut(RJWSexperience.VariousDefOf.GatheredCum, 0.5f);
- float amount = mixture.Volume;
- if (mixture.ispurecum)
+ bool anyExcreted = false;
+ foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
+ if (comp.TotalCumPercent > 0.001)
{
- Bucket.AddCum(amount);
+ CumMixture mixture = comp.MixtureOut(RJWSexperience.VariousDefOf.GatheredCum, 0.5f);
+ float amount = mixture.Volume;
+ if (mixture.ispurecum)
+ {
+ Bucket.AddCum(amount);
+ }
+ else
+ {
+ GatheredCumMixture cummixture = (GatheredCumMixture)ThingMaker.MakeThing(VariousDefOf.GatheredCumMixture);
+ cummixture.InitwithCum(mixture);
+ Bucket.AddCum(amount, cummixture);
+ }
+ anyExcreted = true;
}
- else
- {
- GatheredCumMixture cummixture = (GatheredCumMixture)ThingMaker.MakeThing(VariousDefOf.GatheredCumMixture);
- cummixture.InitwithCum(mixture);
- Bucket.AddCum(amount, cummixture);
- }
- }
- else ReadyForNextToil();
- if (Comp.TotalCumPercent > 0.001) JumpToToil(excreting);
+ if (!anyExcreted) ReadyForNextToil();
+ if (pawn.GetMenstruationComps().Any(c => c.TotalCumPercent > 0.001)) JumpToToil(excreting);
}
};
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/GetGizmos.cs b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/GetGizmos.cs
index e96e9d1..392b18d 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/GetGizmos.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/GetGizmos.cs
@@ -1,14 +1,7 @@
-using System;
+using HarmonyLib;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Verse;
-using RimWorld;
using UnityEngine;
-using RJWSexperience;
-using rjw;
-using HarmonyLib;
+using Verse;
namespace RJW_Menstruation.Sexperience
@@ -32,7 +25,7 @@ namespace RJW_Menstruation.Sexperience
defaultLabel = label,
defaultDesc = description,
icon = icon,
- isActive = delegate() { return comp.DoCleanWomb; },
+ isActive = delegate () { return comp.DoCleanWomb; },
toggleAction = delegate
{
comp.DoCleanWomb = !comp.DoCleanWomb;
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Harmony.cs b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Harmony.cs
index db23583..5fd4777 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Harmony.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Harmony.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using HarmonyLib;
+using HarmonyLib;
using System.Reflection;
using Verse;
@@ -14,7 +9,7 @@ namespace RJW_Menstruation.Sexperience
{
static First()
{
- var har = new Harmony("RJW_Menstruation.Sexperience");
+ Harmony har = new Harmony("RJW_Menstruation.Sexperience");
har.PatchAll(Assembly.GetExecutingAssembly());
}
}
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Menstruation_Patch.cs b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Menstruation_Patch.cs
index b3df374..3a65a43 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Menstruation_Patch.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Menstruation_Patch.cs
@@ -1,16 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RJW_Menstruation;
-using HarmonyLib;
-using rjw;
+using HarmonyLib;
using RimWorld;
+using UnityEngine;
using Verse;
using Verse.Sound;
-using UnityEngine;
-using RJWSexperience;
namespace RJW_Menstruation.Sexperience
{
@@ -24,7 +16,7 @@ namespace RJW_Menstruation.Sexperience
Rect buttonRect = new Rect(rect.x, rect.yMax - ICONSIZE, ICONSIZE, ICONSIZE).ContractedBy(2f);
if (__instance.Comp.DoCleanWomb)
{
- Widgets.DrawTextureFitted(buttonRect,TextureCache.GatherCum_Bucket,1.0f);
+ Widgets.DrawTextureFitted(buttonRect, TextureCache.GatherCum_Bucket, 1.0f);
TooltipHandler.TipRegion(buttonRect, Translations.Dialog_DoCleanWomb_Tooltip);
}
else
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Pawn_Patch.cs b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Pawn_Patch.cs
index 68648c4..e979368 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Pawn_Patch.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/Pawn_Patch.cs
@@ -1,14 +1,10 @@
-using System;
+using HarmonyLib;
+using RimWorld;
+using RJWSexperience;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Verse;
-using Verse.AI;
-using RimWorld;
-using HarmonyLib;
using UnityEngine;
-using RJWSexperience;
+using Verse;
namespace RJW_Menstruation.Sexperience
{
@@ -17,25 +13,20 @@ namespace RJW_Menstruation.Sexperience
{
public static void Postfix(Vector3 clickPos, Pawn pawn, List opts)
{
- var targets = GenUI.TargetsAt(clickPos, TargetingParameters.ForBuilding());
- HediffComp_Menstruation comp = pawn.GetMenstruationComp();
+ IEnumerable targets = GenUI.TargetsAt(clickPos, TargetingParameters.ForBuilding());
- if (comp != null && comp.TotalCumPercent > 0.001f)
- foreach (LocalTargetInfo t in targets)
- {
- if (t.Thing is Building building)
+ if (pawn.GetMenstruationComps().Any(comp => comp.TotalCumPercent > 0.001f))
+ foreach (LocalTargetInfo t in targets)
{
- if (building is Building_CumBucket)
+ if (t.Thing is Building building)
{
- opts.AddDistinct(MakeMenu(pawn, building));
- break;
+ if (building is Building_CumBucket)
+ {
+ opts.AddDistinct(MakeMenu(pawn, building));
+ break;
+ }
}
}
- }
-
-
-
-
}
public static FloatMenuOption MakeMenu(Pawn pawn, LocalTargetInfo target)
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/RJW_Patch.cs b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/RJW_Patch.cs
index 9a344a4..b8d536e 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/Patch/RJW_Patch.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/Patch/RJW_Patch.cs
@@ -1,15 +1,9 @@
-using System;
-using System.Collections.Generic;
+using HarmonyLib;
+using rjw;
+using RJWSexperience;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using RimWorld;
using Verse;
using Verse.AI;
-using rjw;
-using RJW_Menstruation;
-using HarmonyLib;
-using RJWSexperience;
namespace RJW_Menstruation.Sexperience
{
@@ -20,8 +14,7 @@ namespace RJW_Menstruation.Sexperience
[HarmonyPatch("HasJobOnThing")]
public static bool HasJobOnThing(Pawn pawn, ref bool __result)
{
- HediffComp_Menstruation comp = pawn.GetMenstruationComp();
- if (comp != null && comp.DoCleanWomb && comp.TotalCumPercent > 0.001f && pawn.Map.listerBuildings.ColonistsHaveBuilding(VariousDefOf.CumBucket))
+ if (pawn.GetMenstruationComps().Any(comp => comp.DoCleanWomb && comp.TotalCumPercent > 0.001f) && pawn.Map.listerBuildings.ColonistsHaveBuilding(VariousDefOf.CumBucket))
{
__result = true;
return false;
@@ -33,8 +26,7 @@ namespace RJW_Menstruation.Sexperience
[HarmonyPatch("JobOnThing")]
public static void JobOnThing(Pawn pawn, ref Job __result)
{
- HediffComp_Menstruation comp = pawn.GetMenstruationComp();
- if (comp != null && comp.DoCleanWomb && comp.TotalCumPercent > 0.001f)
+ if (pawn.GetMenstruationComps().Any(comp => comp.DoCleanWomb && comp.TotalCumPercent > 0.001f))
{
Building_CumBucket bucket = pawn.FindClosestBucket();
@@ -43,10 +35,6 @@ namespace RJW_Menstruation.Sexperience
__result = JobMaker.MakeJob(VariousDefOf.VaginaWashingwithBucket, null, bucket, bucket.Position);
}
}
-
}
-
-
-
}
}
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/Properties/AssemblyInfo.cs b/1.3/source/RJW_Menstruation/SexperienceModule/Properties/AssemblyInfo.cs
index fa02342..a2226aa 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/Properties/AssemblyInfo.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
diff --git a/1.3/source/RJW_Menstruation/SexperienceModule/VariousDefOf.cs b/1.3/source/RJW_Menstruation/SexperienceModule/VariousDefOf.cs
index fef502c..617eb47 100644
--- a/1.3/source/RJW_Menstruation/SexperienceModule/VariousDefOf.cs
+++ b/1.3/source/RJW_Menstruation/SexperienceModule/VariousDefOf.cs
@@ -1,9 +1,4 @@
-using RimWorld;
-using rjw;
-using System.Linq;
-using System;
-using System.Collections.Generic;
-using Verse;
+using Verse;
namespace RJW_Menstruation.Sexperience
{
diff --git a/About/Manifest.xml b/About/Manifest.xml
index 21cc793..d56ea34 100644
--- a/About/Manifest.xml
+++ b/About/Manifest.xml
@@ -1,7 +1,7 @@
RJW Menstruation
- 1.0.6.6
+ 1.0.7.0
diff --git a/changelogs.txt b/changelogs.txt
index 9134a88..f2d3030 100644
--- a/changelogs.txt
+++ b/changelogs.txt
@@ -1,3 +1,25 @@
+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.
+
+ - Support for multiple vaginas, including each having a separate pregnancy.
+ - More reliably generate a baby's race correctly when using pawnkind diversification mods.
+ - Overhauled many things under the hood.
+ - Cycle randomization completely redone. Everyone now has a (hidden) cycle speed and cycle variability.
+ - Ovary initialization redone. All pawns now get a total number of eggs based on their age and racial properties.
+ - Coming inside someone with an IUD will give the same total amount of fluid as without, just at a lower fertility.
+ - The chance to fertilize has been changed to an exponential curve instead of a linear one. This will increase the chances of pregnancy at low amounts of semen and slightly reduce it at high amounts.
+ - Semen now has a fertility percentage instead of "fertile volume".
+ - The exact time between fertilization and implantation has been adjusted.
+ - Removing a vagina will end any pregnancy it has in progress. Please wait until the baby is born first.
+ - Your colonists can create artwork of someone being born.
+ - They can also create artwork of someone coming inside someone else.
+
+ - Default values changed to account for the new math. The new defaults will have the same odds of pregnancy with a 10ml ejaculation at ovulation (in a human) as before:
+ - Fertilization chance from 10%/mL to 15%
+ - Cum decay from 30%/hour to 15%
+ - Fertility decay from 20%/hour to 5%
+
Version 1.0.6.6
- Ovipostors add on average 1.5x as much cum to a womb than before.
- The womb tick timing is now more consistent across a save and load, and also spread out across pawns.