diff --git a/1.4/Assemblies/RJW_Menstruation.dll b/1.4/Assemblies/RJW_Menstruation.dll index 2ac459a..97337d7 100644 Binary files a/1.4/Assemblies/RJW_Menstruation.dll and b/1.4/Assemblies/RJW_Menstruation.dll differ diff --git a/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml b/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml index 9e5a55e..c436751 100644 --- a/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml +++ b/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml @@ -37,8 +37,7 @@ 月經加速 加快月經週期 除錯 - 顯示除錯資訊 -啟用時會令「胎兒信息級別」選項調至「全部細節」。 + 顯示除錯資訊 啟用時會令「胎兒信息級別」選項調至「全部細節」。 子宮狀態 在狀態窗口中繪製子宮圖標 陰道狀態 @@ -148,10 +147,4 @@ 沒有卵細胞 必須擁有子宮 {PAWN_labelShort}完成了{PAWN_possessive}卵母細胞再生術(cycle) - - 排卵機率:{0} - 排卵期內每個卵子的獨立排卵機率。 - (測試中!) 允許在「生機」(Biotech)追加的懷孕機制中出現多胞胎。 - 啟用這個選項將允許同卵或異卵雙胞胎出現在「生機」(Biotech)追加的懷孕機制中。 -一併將啟用雜交系統;然而兩個類人(humanlikes)生物絕不可能生出動物。 diff --git a/1.4/Languages/English/Keyed/RJW_Menstruation.xml b/1.4/Languages/English/Keyed/RJW_Menstruation.xml index 18611bd..a1c65b3 100644 --- a/1.4/Languages/English/Keyed/RJW_Menstruation.xml +++ b/1.4/Languages/English/Keyed/RJW_Menstruation.xml @@ -56,12 +56,6 @@ Cum will lose fertility by this amount every hour This value affects fertilization chance indirectly. Cycle acceleration Accelerate menstruation cycle This can cause early menopause and infertility. Setting this lower than x12 is recommended. Rimworld's timescale: x6(default) - Colonist update interval - How often the womb of each of your colonists, prisoners, and slaves update. Lowering this will improve accuracy, increasing this can improve performance. - Non-colonist update interval - How often the womb of humans you don't control update. Lowering this will improve accuracy, increasing this can improve performance. - Animal update interval - How often the womb of animals update. Lowering this will improve accuracy, increasing this can improve performance. Debug Show debug information. Womb status diff --git a/1.4/MilkModule/Assemblies/MilkModule.dll b/1.4/MilkModule/Assemblies/MilkModule.dll index d34b673..1881466 100644 Binary files a/1.4/MilkModule/Assemblies/MilkModule.dll and b/1.4/MilkModule/Assemblies/MilkModule.dll differ diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs index 07fd58f..d450c4d 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs @@ -1,5 +1,4 @@ -using RimWorld; -using rjw; +using rjw; using System; using System.Collections.Generic; using UnityEngine; @@ -18,10 +17,6 @@ namespace RJW_Menstruation public const float CumFertilityDecayRatioDefault = 0.05f; public const int CumFertilityDecayRatioAdjustDefault = 50; public const int CycleAccelerationDefault = 6; - public const int ColonistTickIntervalDefault = 2500; // 1 hour - public const int NonColonistTickIntervalDefault = 2500; - public const int AnimalTickIntervalDefault = 2500; - public const int TickIntervalMinimum = 20; public const float EnzygoticTwinsChanceDefault = 0.002f; public const int EnzygoticTwinsChanceAdjustDefault = 2; public const int MaxEnzygoticTwinsDefault = 9; @@ -46,9 +41,6 @@ namespace RJW_Menstruation public static float CumFertilityDecayRatio = CumFertilityDecayRatioDefault; public static int CumFertilityDecayRatioAdjust = CumFertilityDecayRatioAdjustDefault; public static int CycleAcceleration = CycleAccelerationDefault; - public static int ColonistTickInterval = ColonistTickIntervalDefault; - public static int NonColonistTickInterval = NonColonistTickIntervalDefault; - public static int AnimalTickInterval = AnimalTickIntervalDefault; public static bool EnableWombIcon = true; public static bool EnableDraftedIcon = true; public static bool EnableAnimalCycle = false; @@ -93,9 +85,6 @@ namespace RJW_Menstruation EnableGatherCumGizmo = true; EnableAnimalCycle = false; CycleAcceleration = CycleAccelerationDefault; - ColonistTickInterval = ColonistTickIntervalDefault; - NonColonistTickInterval = NonColonistTickIntervalDefault; - AnimalTickInterval = AnimalTickIntervalDefault; EstrusOverridesHookupSettings = false; EstrusFuckabilityToHookup = RJWHookupSettings.MinimumFuckabilityToHookup; EstrusAttractivenessToHookup = RJWHookupSettings.MinimumAttractivenessToHookup; @@ -190,51 +179,48 @@ namespace RJW_Menstruation public override void ExposeData() { - Scribe_Values.Look(ref ImplantationChanceAdjust, "ImplantationChanceAdjust", ImplantationChanceAdjustDefault); - Scribe_Values.Look(ref ImplantationChance, "ImplantationChance", ImplantationChanceDefault); - Scribe_Values.Look(ref FertilizeChanceAdjust, "FertilizeChanceAdjust", FertilizeChanceAdjustDefault); - Scribe_Values.Look(ref FertilizeChance, "FertilizeChance", FertilizeChanceDefault); - Scribe_Values.Look(ref CumDecayRatioAdjust, "CumDecayRatioAdjust", CumDecayRatioAdjustDefault); - Scribe_Values.Look(ref CumDecayRatio, "CumDecayRatio", CumDecayRatioDefault); - Scribe_Values.Look(ref CumFertilityDecayRatioAdjust, "CumFertilityDecayRatioAdjust", CumFertilityDecayRatioAdjustDefault); - Scribe_Values.Look(ref CumFertilityDecayRatio, "CumFertilityDecayRatio", CumFertilityDecayRatioDefault); - Scribe_Values.Look(ref CycleAcceleration, "CycleAcceleration", CycleAccelerationDefault); - Scribe_Values.Look(ref ColonistTickInterval, "ColonistTickInterval", ColonistTickIntervalDefault); - Scribe_Values.Look(ref NonColonistTickInterval, "NonColonistTickInterval", NonColonistTickIntervalDefault); - Scribe_Values.Look(ref AnimalTickInterval, "AnimalTickInterval", AnimalTickIntervalDefault); - Scribe_Values.Look(ref EnableWombIcon, "EnableWombIcon", true); - Scribe_Values.Look(ref EnableDraftedIcon, "EnableDraftedIcon", true); - Scribe_Values.Look(ref EnableAnimalCycle, "EnableAnimalCycle", false); - Scribe_Values.Look(ref DrawWombStatus, "DrawWombStatus", true); - Scribe_Values.Look(ref DrawVaginaStatus, "DrawVaginaStatus", true); - Scribe_Values.Look(ref DrawEggOverlay, "DrawEggOvray", true); - Scribe_Values.Look(ref Debug, "Debug", false); - Scribe_Values.Look(ref infoDetail, "InfoDetail", DetailLevel.All); - Scribe_Values.Look(ref EnableMenopause, "EnableMenopause", true); - Scribe_Values.Look(ref EstrusOverridesHookupSettings, "EstrusOverridesHookupSettings", false); + Scribe_Values.Look(ref ImplantationChanceAdjust, "ImplantationChanceAdjust", ImplantationChanceAdjust, true); + Scribe_Values.Look(ref ImplantationChance, "ImplantationChance", ImplantationChance, true); + Scribe_Values.Look(ref FertilizeChanceAdjust, "FertilizeChanceAdjust", FertilizeChanceAdjust, true); + Scribe_Values.Look(ref FertilizeChance, "FertilizeChance", FertilizeChance, true); + Scribe_Values.Look(ref CumDecayRatioAdjust, "CumDecayRatioAdjust", CumDecayRatioAdjust, true); + Scribe_Values.Look(ref CumDecayRatio, "CumDecayRatio", CumDecayRatio, true); + Scribe_Values.Look(ref CumFertilityDecayRatioAdjust, "CumFertilityDecayRatioAdjust", CumFertilityDecayRatioAdjust, true); + Scribe_Values.Look(ref CumFertilityDecayRatio, "CumFertilityDecayRatio", CumFertilityDecayRatio, true); + Scribe_Values.Look(ref CycleAcceleration, "CycleAcceleration", CycleAcceleration, true); + Scribe_Values.Look(ref EnableWombIcon, "EnableWombIcon", EnableWombIcon, true); + Scribe_Values.Look(ref EnableDraftedIcon, "EnableDraftedIcon", EnableDraftedIcon, true); + Scribe_Values.Look(ref EnableAnimalCycle, "EnableAnimalCycle", EnableAnimalCycle, true); + Scribe_Values.Look(ref DrawWombStatus, "DrawWombStatus", DrawWombStatus, true); + Scribe_Values.Look(ref DrawVaginaStatus, "DrawVaginaStatus", DrawVaginaStatus, true); + Scribe_Values.Look(ref DrawEggOverlay, "DrawEggOvray", DrawEggOverlay, true); + Scribe_Values.Look(ref Debug, "Debug", Debug, true); + Scribe_Values.Look(ref infoDetail, "InfoDetail", infoDetail, true); + Scribe_Values.Look(ref EnableMenopause, "EnableMenopause", EnableMenopause, true); + Scribe_Values.Look(ref EstrusOverridesHookupSettings, "EstrusOverridesHookupSettings", EstrusOverridesHookupSettings, true); Scribe_Values.Look(ref EstrusFuckabilityToHookup, "EstrusFuckabilityToHookup", EstrusFuckabilityToHookup, true); Scribe_Values.Look(ref EstrusAttractivenessToHookup, "EstrusAttractivenessToHookup", EstrusAttractivenessToHookup, true); Scribe_Values.Look(ref EstrusRelationshipToHookup, "EstrusRelationshipToHookup", EstrusRelationshipToHookup, true); - Scribe_Values.Look(ref PregnancySource, "PregnancySource", PregnancyType.MultiplePregnancy); - Scribe_Values.Look(ref EnableBiotechTwins, "EnableBiotechTwins", false); - Scribe_Values.Look(ref EnableHeteroOvularTwins, "EnableHeteroOvularTwins", true); - Scribe_Values.Look(ref EnableEnzygoticTwins, "EnableEnzygoticTwins", true); - Scribe_Values.Look(ref EnzygoticTwinsChance, "EnzygoticTwinsChance", EnzygoticTwinsChanceDefault); - Scribe_Values.Look(ref EnzygoticTwinsChanceAdjust, "EnzygoticTwinsChanceAdjust", EnzygoticTwinsChanceAdjustDefault); - Scribe_Values.Look(ref MaxEnzygoticTwins, "MaxEnzygoticTwins", MaxEnzygoticTwinsDefault); - Scribe_Values.Look(ref BleedingAmount, "BleedingAmount", BleedingAmountDefault); - Scribe_Values.Look(ref EnableButtonInHT, "EnableButtonInHT", false); - Scribe_Values.Look(ref EnableGatherCumGizmo, "EnableGatherCumGizmo", true); - Scribe_Values.Look(ref ShowFlag, "ShowFlag", PawnFlags.Colonist | PawnFlags.Prisoner); - Scribe_Values.Look(ref UseHybridExtention, "UseHybridExtention", true); - Scribe_Values.Look(ref MotherFirst, "MotherFirst", false); - Scribe_Values.Look(ref MaxBreastIncrementFactor, "MaxBreastIncrementFactor", MaxBreastIncrementFactorDefault); - Scribe_Values.Look(ref MaxNippleIncrementFactor, "MaxNippleIncrementFactor", MaxNippleIncrementFactorDefault); - Scribe_Values.Look(ref PermanentNippleChange, "PermanentNippleChange", PermanentNippleChangeDefault); - Scribe_Values.Look(ref AllowShrinkIcon, "AllowShrinkIcon", false); - Scribe_Values.Look(ref EggLifespanMultiplier, "EggLifespanMultiplier", EggLifespanMultiplierDefault); - Scribe_Values.Look(ref EnableBirthVaginaMorph, "EnableBirthVaginaMorph", false); - Scribe_Values.Look(ref VaginaMorphPower, "VaginaMorphPower", VaginaMorphPowerDefault); + Scribe_Values.Look(ref PregnancySource, "PregnancySource", PregnancySource, true); + Scribe_Values.Look(ref EnableBiotechTwins, "EnableBiotechTwins", EnableBiotechTwins, true); + Scribe_Values.Look(ref EnableHeteroOvularTwins, "EnableHeteroOvularTwins", EnableHeteroOvularTwins, true); + Scribe_Values.Look(ref EnableEnzygoticTwins, "EnableEnzygoticTwins", EnableEnzygoticTwins, true); + Scribe_Values.Look(ref EnzygoticTwinsChance, "EnzygoticTwinsChance", EnzygoticTwinsChance, true); + Scribe_Values.Look(ref EnzygoticTwinsChanceAdjust, "EnzygoticTwinsChanceAdjust", EnzygoticTwinsChanceAdjust, true); + Scribe_Values.Look(ref MaxEnzygoticTwins, "MaxEnzygoticTwins", MaxEnzygoticTwins, true); + Scribe_Values.Look(ref BleedingAmount, "BleedingAmount", BleedingAmount, true); + Scribe_Values.Look(ref EnableButtonInHT, "EnableButtonInHT", EnableButtonInHT, true); + Scribe_Values.Look(ref EnableGatherCumGizmo, "EnableGatherCumGizmo", true, true); + Scribe_Values.Look(ref ShowFlag, "ShowFlag", ShowFlag, true); + Scribe_Values.Look(ref UseHybridExtention, "UseHybridExtention", UseHybridExtention, true); + Scribe_Values.Look(ref MotherFirst, "MotherFirst", MotherFirst, true); + Scribe_Values.Look(ref MaxBreastIncrementFactor, "MaxBreastIncrementFactor", MaxBreastIncrementFactor, true); + Scribe_Values.Look(ref MaxNippleIncrementFactor, "MaxNippleIncrementFactor", MaxNippleIncrementFactor, true); + Scribe_Values.Look(ref PermanentNippleChange, "PermanentNippleChange", PermanentNippleChange, true); + Scribe_Values.Look(ref AllowShrinkIcon, "AllowShrinkIcon", AllowShrinkIcon, true); + Scribe_Values.Look(ref EggLifespanMultiplier, "EggLifespanMultiplier", EggLifespanMultiplier, true); + Scribe_Values.Look(ref EnableBirthVaginaMorph, "EnableBirthVaginaMorph", EnableBirthVaginaMorph, true); + Scribe_Values.Look(ref VaginaMorphPower, "VaginaMorphPower", VaginaMorphPower, true); Scribe_Collections.Look(ref HybridOverride, saveDestroyedThings: true, label: "HybridOverride", lookMode: LookMode.Deep, ctorArgs: new object[0]); base.ExposeData(); } @@ -288,9 +274,8 @@ namespace RJW_Menstruation public override void DoSettingsWindowContents(Rect inRect) { Rect outRect = new Rect(0f, 30f, inRect.width, inRect.height - 30f); - float mainRectHeight = 126f + + float mainRectHeight = 30f + (Configurations.EnableWombIcon || Configurations.EnableButtonInHT ? 400f : 0f) + - (Configurations.EnableAnimalCycle ? 48f : 0f) + (Configurations.EstrusOverridesHookupSettings ? 144f : 0f) + (Configurations.PregnancySource == Configurations.PregnancyType.MultiplePregnancy ? (Configurations.EnableEnzygoticTwins ? 175f : 75f) : 0f) + (Configurations.PregnancySource == Configurations.PregnancyType.Biotech ? 75f : 0f) + @@ -418,11 +403,11 @@ namespace RJW_Menstruation string estimatedlifespan; if (semenlifespan < 0) { - estimatedlifespan = string.Format(": Infinite", semenlifespan); + estimatedlifespan = String.Format(": Infinite", semenlifespan); } else { - estimatedlifespan = string.Format(": {0:0}h", semenlifespan); + estimatedlifespan = String.Format(": {0:0}h", semenlifespan); } listmain.LabelDouble(Translations.Option6_Label + " " + Configurations.CumFertilityDecayRatio * 100 + "%", Translations.EstimatedCumLifespan + estimatedlifespan, Translations.Option6_Desc); Configurations.CumFertilityDecayRatioAdjust = (int)listmain.Slider(Configurations.CumFertilityDecayRatioAdjust, 0, 1000); @@ -431,17 +416,6 @@ namespace RJW_Menstruation listmain.Label(Translations.Option7_Label + " x" + Configurations.CycleAcceleration, -1, Translations.Option7_Desc); Configurations.CycleAcceleration = (int)listmain.Slider(Configurations.CycleAcceleration, 1, 50); - listmain.LabelDouble(Translations.Option_ColonistUpdateInterval_Label, GenDate.ToStringTicksToPeriod(Configurations.ColonistTickInterval), Translations.Option_ColonistUpdateInterval_Desc); - Configurations.ColonistTickInterval = (int)Mathf.Exp(listmain.Slider(Mathf.Log(Configurations.ColonistTickInterval), Mathf.Log(Configurations.TickIntervalMinimum), Mathf.Log(4 * GenDate.TicksPerHour))); - - listmain.LabelDouble(Translations.Option_NonColonistUpdateInterval_Label, GenDate.ToStringTicksToPeriod(Configurations.NonColonistTickInterval), Translations.Option_NonColonistUpdateInterval_Desc); - Configurations.NonColonistTickInterval = (int)Mathf.Exp(listmain.Slider(Mathf.Log(Configurations.NonColonistTickInterval), Mathf.Log(Configurations.TickIntervalMinimum), Mathf.Log(4 * GenDate.TicksPerHour))); - - if(Configurations.EnableAnimalCycle) - { - listmain.LabelDouble(Translations.Option_AnimalUpdateInterval_Label, GenDate.ToStringTicksToPeriod(Configurations.AnimalTickInterval), Translations.Option_AnimalUpdateInterval_Desc); - Configurations.AnimalTickInterval = (int)Mathf.Exp(listmain.Slider(Mathf.Log(Configurations.AnimalTickInterval), Mathf.Log(Configurations.TickIntervalMinimum), Mathf.Log(4 * GenDate.TicksPerHour))); - } float var2 = EstimatedBleedingAmountPerHour; float var1 = Math.Max(EstimatedBleedingAmount, var2); diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs index 3f112d3..c1f9931 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs @@ -165,15 +165,16 @@ namespace RJW_Menstruation Scribe_References.Look(ref pawn, "pawn", true); Scribe_Values.Look(ref volume, "volume", volume, true); Scribe_Values.Look(ref fertility, "fertility", fertility, true); - Scribe_Values.Look(ref notcumthickness, "notcumthickness", 0); - Scribe_Values.Look(ref notcum, "notcum", false); - Scribe_Values.Look(ref notcumLabel, "notcumLabel", ""); - Scribe_Values.Look(ref useCustomColor, "useCustomColor", false); - Scribe_Values.Look(ref customColor, "customColor", default); + Scribe_Values.Look(ref notcumthickness, "notcumthickness", notcumthickness, 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); + Scribe_Values.Look(ref customColor, "customColor", customColor, true); Scribe_Defs.Look(ref filthDef, "filthDef"); + } - public void MakeThinner(float speed) + public void MakeThinner(int speed) { cumthickness = cumthickness.LerpMultiple(DecayResist, 0.3f, speed); } @@ -204,11 +205,8 @@ namespace RJW_Menstruation { // comp is used for Hydrogen's RJW Muscle Injury float totalleak = volume; - float decayPerInterval = 1 - Mathf.Pow(1 - Configurations.CumDecayRatio, comp.SimulationsPerHour); - float fertilityDecayPerInterval = 1 - Mathf.Pow(1 - Configurations.CumFertilityDecayRatio, comp.SimulationsPerHour); - antisperm *= comp.SimulationsPerHour; - volume *= Math.Max(0, 1 - decayPerInterval * (1 - DecayResist) * leakfactor); - fertility *= Math.Max(0, 1 - (fertilityDecayPerInterval * (1 - DecayResist) + antisperm)); + volume *= Math.Max(0, (1 - (Configurations.CumDecayRatio * (1 - DecayResist)) * leakfactor)); + fertility *= Math.Max(0, 1 - (Configurations.CumFertilityDecayRatio * (1 - DecayResist) + antisperm)); CutMinor(); totalleak -= volume; return totalleak; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs index 55f34db..fe98f5a 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs @@ -10,10 +10,7 @@ namespace RJW_Menstruation private static void SetFollicular(Pawn p) { foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - { comp.GoNextStage(HediffComp_Menstruation.Stage.Follicular); - comp.RemoveAllEggs(); - } Messages.Message($"{p} is now follicular", p, MessageTypeDefOf.NeutralEvent, false); } @@ -37,10 +34,7 @@ namespace RJW_Menstruation private static void SetBleeding(Pawn p) { foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - { comp.GoNextStage(HediffComp_Menstruation.Stage.Bleeding); - comp.RemoveAllEggs(); - } Messages.Message($"{p} is now bleeding", p, MessageTypeDefOf.NeutralEvent, false); } /* @@ -63,13 +57,6 @@ namespace RJW_Menstruation comp.RemoveAllCums(); Messages.Message($"All cum removed from {p}'s womb", p, MessageTypeDefOf.NeutralEvent, false); } - [DebugAction("RJW Menstruation", "Remove all eggs from pawn's womb", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] - private static void RemoveEggs(Pawn p) - { - foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) - comp.RemoveAllEggs(); - Messages.Message($"All eggs removed from {p}'s womb", p, MessageTypeDefOf.NeutralEvent, false); - } [DebugAction("RJW Menstruation", "Add egg to pawn's next ovulation", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] private static void AddEgg(Pawn p) { diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs index b618abe..2b51556 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs @@ -89,7 +89,7 @@ namespace RJW_Menstruation else m.moodPowerFactor = 0.3f; } - if (pawn.IsProPregnancy()) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill); + if (pawn.HasQuirk(QuirkUtility.Quirks.Breeder)) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill); else pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.TookContraceptivePill); } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs index 558031d..71e930c 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs @@ -69,12 +69,15 @@ namespace RJW_Menstruation get { if (babyHalfAge > 0f) return babyHalfAge; - List ages = Pawn.RaceProps.lifeStageAges; + List ages = Pawn.def.race.lifeStageAges; if (ages?.Count > 1) babyHalfAge = ages[1].minAge / 2; if (babyHalfAge <= 0) babyHalfAge = 1.2f / 2; // Default to human + if (RJWPregnancySettings.phantasy_pregnancy) + babyHalfAge /= GenDate.DaysPerYear; + return babyHalfAge; } } @@ -137,10 +140,10 @@ namespace RJW_Menstruation { base.CompExposeData(); - Scribe_Values.Look(ref ageOfLastBirth, "ageOfLastBirth", -1); + Scribe_Values.Look(ref ageOfLastBirth, "ageOfLastBirth", ageOfLastBirth, true); Scribe_Values.Look(ref maxBreastIncrement, "maxBreastIncrement", maxBreastIncrement, true); - Scribe_Values.Look(ref breastSizeIncreased, "breastSizeIncreased", 0.0f); - Scribe_Values.Look(ref nippleProgress, "nippleProgress", 0.0f); + Scribe_Values.Look(ref breastSizeIncreased, "breastSizeIncreased", breastSizeIncreased, true); + Scribe_Values.Look(ref nippleProgress, "nippleProgress", nippleProgress, true); Scribe_Values.Look(ref baseAlpha, "baseAlpha", baseAlpha, true); Scribe_Values.Look(ref baseAreola, "baseAreola", baseAreola, true); Scribe_Values.Look(ref baseNipple, "baseNipple", baseNipple, true); @@ -149,7 +152,7 @@ namespace RJW_Menstruation public bool ShouldSimulate() { if (!Configurations.EnableAnimalCycle && Pawn.IsAnimal()) return false; - if (Pawn.SpawnedOrAnyParentSpawned || Pawn.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(Pawn)) return true; + if (Pawn.Spawned || Pawn.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(Pawn)) return true; return false; } @@ -196,19 +199,19 @@ namespace RJW_Menstruation protected long CalculateLastBirth() { - long youngestAge = -1; + long youngestAge = (long)(BabyHalfAge * GenDate.TicksPerYear) * -2; // So a newborn isn't considered a new mother, either if ((Pawn.relations == null)) return youngestAge; - List rjwPregnancies = new List(); - Pawn.health.hediffSet.GetHediffs(ref rjwPregnancies); + List pregnancies = new List(); + Pawn.health.hediffSet.GetHediffs(ref pregnancies); bool hasChild = Pawn.relations.Children. - Where(child => !rjwPregnancies.Any(preg => preg.babies.Contains(child))). // no fetuses + Where(child => !pregnancies.Any(preg => preg.babies.Contains(child))). // no fetuses Where(child => child.GetMother() == Pawn). // not Dad TryMinBy(child => child.ageTracker.AgeBiologicalTicks, out Pawn youngest); - if (hasChild) youngestAge = Math.Max(Pawn.ageTracker.AgeBiologicalTicks - youngest.ageTracker.AgeBiologicalTicks, -1); + if (hasChild) youngestAge = Pawn.ageTracker.AgeBiologicalTicks - youngest.ageTracker.AgeBiologicalTicks; return youngestAge; } @@ -221,7 +224,7 @@ namespace RJW_Menstruation { maxBreastIncrement = Utility.RandGaussianLike(0.088f, 0.202f); } - if (ageOfLastBirth == 0 || ageOfLastBirth < -1) + if (ageOfLastBirth == 0) { ageOfLastBirth = CalculateLastBirth(); } @@ -250,7 +253,7 @@ namespace RJW_Menstruation debugGrowthStatus = "Base size (ageless)"; } // The youngest child is less than halfway into babyhood: Full size - else if (ageOfLastBirth > 0 && ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > Pawn.ageTracker.AgeBiologicalTicks) + else if (ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > Pawn.ageTracker.AgeBiologicalTicks) { debugGrowthStatus = "Full size due to young child"; if (breastSizeIncreased < MaxBreastIncrement) @@ -296,7 +299,7 @@ namespace RJW_Menstruation float newNippleProgress; if (Pawn.ageTracker.BiologicalTicksPerTick <= 0f) newNippleProgress = 0f; - else if (ageOfLastBirth > 0 && ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > Pawn.ageTracker.AgeBiologicalTicks) + else if (ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > Pawn.ageTracker.AgeBiologicalTicks) newNippleProgress = 1f; else if (Pawn.IsRJWPregnant() || Pawn.IsBiotechPregnant()) newNippleProgress = nippleTransitions.Evaluate(Pawn.GetFarthestPregnancyProgress()); diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs index a32969c..d069069 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs @@ -15,14 +15,6 @@ namespace RJW_Menstruation public class HediffComp_InducedOvulator : HediffComp_Menstruation { - protected bool hadOvulatoryStage = false; // Regardless of whether an egg was actually produced - - protected override void InitializeExtraValues() - { - base.InitializeExtraValues(); - hadOvulatoryStage |= IsEggExist; - } - public override string GetCurStageDesc { get @@ -43,7 +35,7 @@ namespace RJW_Menstruation protected override float RaceCyclesPerYear() { // Don't bother with breeding season, since so much time is planned to be spent pregnant. - float pregnanciesPerYear = GenDate.DaysPerYear / Mathf.Max(1, Pawn.RaceProps.gestationPeriodDays); + float pregnanciesPerYear = GenDate.DaysPerYear / Mathf.Max(1, Pawn.def.race.gestationPeriodDays); return 2 * pregnanciesPerYear / Configurations.ImplantationChanceDefault; } @@ -54,35 +46,21 @@ namespace RJW_Menstruation return Mathf.CeilToInt((Pawn.relations?.ChildrenCount ?? 0) / Configurations.ImplantationChanceDefault); } - public override void CompExposeData() - { - base.CompExposeData(); - Scribe_Values.Look(ref hadOvulatoryStage, "hadOvulatoryStage", false); - } - protected override void GoOvulatoryStage() { estrusflag = false; - hadOvulatoryStage = false; GoNextStage(Stage.Luteal); } - protected override void OvulatoryAction() - { - base.OvulatoryAction(); - hadOvulatoryStage = true; - } - - protected override void LutealAction() - { - base.LutealAction(); - if (curStage != Stage.Luteal) hadOvulatoryStage = false; - } - protected override void AfterCumIn(Pawn cummer) { base.AfterCumIn(cummer); - if (curStage == Stage.Follicular) GoNextStage(Stage.Ovulatory); + switch (curStage) + { + case Stage.Follicular: + GoNextStage(Stage.Ovulatory); + break; + } } public override bool IsDangerDay @@ -97,7 +75,7 @@ namespace RJW_Menstruation case Stage.Ovulatory: return true; case Stage.Luteal: - return hadOvulatoryStage && curStageTicks < EggLifespanTicks; + return IsEggExist && curStageHrs < EggLifespanHours; default: return false; } @@ -111,11 +89,11 @@ namespace RJW_Menstruation switch (curStage) { case Stage.Follicular: - return curStageTicks > currentIntervalTicks - Props.estrusDaysBeforeOvulation * GenDate.TicksPerDay; + return curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24; case Stage.Ovulatory: return true; case Stage.Luteal: - return hadOvulatoryStage && curStageTicks < EggLifespanTicks; + return IsEggExist && curStageHrs < EggLifespanHours; default: return false; } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs index c32ee83..d015752 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs @@ -29,7 +29,6 @@ namespace RJW_Menstruation public float baseImplantationChanceFactor; public float basefertilizationChanceFactor; public int follicularIntervalDays = 14; //before ovulation including beginning of bleeding - public int ovulationIntervalHours = 12; //between the end of follicular and the egg emerging 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 @@ -64,17 +63,17 @@ namespace RJW_Menstruation public class HediffComp_Menstruation : HediffComp { const float minmakefilthvalue = 1.0f; - const int maxImplantDelayHours = 30 * GenDate.HoursPerDay; - const int minImplantAgeHours = 3 * GenDate.HoursPerDay; - const float fluidLeakThreshold = 3.5f; + //const int ovarypowerthreshold = 72; + + const int tickInterval = GenDate.TicksPerHour; + const int maxImplantDelayHours = 30 * 24; + const int minImplantAgeHours = 3 * 24; const float pulloutSuccessRate = 0.8f; const float fetishPulloutSuccessModifier = 0.25f; public CompProperties_Menstruation Props; public Stage curStage = Stage.Follicular; - public int curStageTicks = 0; // Actual number of ticks equals this / cycleAcceleration - private int tickInterval = -1; - const int recalculateTickInterval = GenTicks.TickLongInterval; + public int curStageHrs = 0; public bool loaded = false; public bool initError = false; public int ovarypower = -100000; @@ -104,7 +103,6 @@ namespace RJW_Menstruation public static readonly Dictionary StageTexture = new Dictionary() { { Stage.Follicular, TextureCache.FollicularTexture }, - { Stage.Ovulatory, TextureCache.OvulatoryTexture }, { Stage.Luteal, TextureCache.LutealTexture }, { Stage.Bleeding, TextureCache.BleedingTexture }, { Stage.Pregnant, TextureCache.PregnantTexture }, @@ -116,22 +114,19 @@ namespace RJW_Menstruation protected List eggs; protected float cycleSpeed = -1; protected float cycleVariability = -1; - protected int currentIntervalTicks = -1; // Actual number of ticks equals this / cycleAcceleration + protected int currentIntervalHours = -1; protected float crampPain = -1; - protected float fluidToLeak = 0; protected Need sexNeed = null; protected string customwombtex = null; protected string customvagtex = null; protected bool estrusflag = false; - protected float ovulationChanceCache = -1.0f; // Dirtied every simulation - protected float implantationChanceCache = -1.0f; protected int opcache = -1; protected float antisperm = 0.0f; protected float? originvagsize = null; // RJW pregnancy, or Biotech pregnancy/labor/laborpushing protected Hediff pregnancy = null; - protected int eggLifeSpanTicks = 2 * GenDate.TicksPerDay; + protected int eggLifeSpanHours = 48; protected EstrusLevel estrusLevel = EstrusLevel.Visible; protected float ovulationFactor = 1f; protected bool noBleeding = false; @@ -160,24 +155,6 @@ namespace RJW_Menstruation new CurvePoint(1.0f,0.5f) }; - protected int TickInterval - { - get - { - if (tickInterval <= 0) - { - if (Pawn.IsAnimal()) tickInterval = Configurations.AnimalTickInterval; - else if (Pawn.IsColonist || Pawn.IsPrisonerOfColony || Pawn.IsSlaveOfColony) tickInterval = Configurations.ColonistTickInterval; - else tickInterval = Configurations.NonColonistTickInterval; - if (tickInterval <= Configurations.TickIntervalMinimum) tickInterval = Configurations.TickIntervalMinimum; - } - return tickInterval; - } - set => tickInterval = value; - } - - public float SimulationsPerHour => (float)TickInterval / GenDate.TicksPerHour; - public Hediff Pregnancy { get { @@ -200,7 +177,7 @@ namespace RJW_Menstruation float avglittersize; try { - avglittersize = Mathf.Max(Rand.ByCurveAverage(Pawn.RaceProps.litterSizeCurve), 1.0f); + avglittersize = Mathf.Max(Rand.ByCurveAverage(Pawn.def.race.litterSizeCurve), 1.0f); } catch { @@ -212,7 +189,7 @@ namespace RJW_Menstruation opcache = (int)(RaceCyclesPerYear() * avglittersize * yearsBeforeMenopause * - (Pawn.RaceProps.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy)); + (Pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy)); if (opcache == 0) opcache = 1; return opcache; } @@ -265,15 +242,24 @@ namespace RJW_Menstruation public float TotalCum { - get => cums?.Sum(cum => cum.Volume) ?? 0; + get + { + return cums?.Sum(cum => cum.Volume) ?? 0; + } } public float TotalFertCum { - get => cums?.Sum(cum => cum.FertVolume) ?? 0; + get + { + return cums?.Sum(cum => cum.FertVolume) ?? 0; + } } public float TotalCumPercent { - get => cums?.Sum(cum => cum.Volume) / Props.maxCumCapacity ?? 0; + get + { + return cums?.Sum(cum => cum.Volume) / Props.maxCumCapacity ?? 0; + } } public float CumCapacity { @@ -289,7 +275,7 @@ namespace RJW_Menstruation { get { - if (QuirkUtility.HasQuirk(Pawn, QuirkUtility.Quirks.Breeder)) return 0.5f; + if (xxx.has_quirk(Pawn, "Breeder")) return 0.5f; return 1.0f; } @@ -298,70 +284,58 @@ namespace RJW_Menstruation // I hate doing this, but it's the least bad option public bool calculatingOvulationChance = false; - protected float CalcuatedOvulationChance() - { - float ovulationChance = 1.0f; - if (EggHealth <= 0.0f) return 0.0f; - if (EggHealth < 1.0f / 3.0f) ovulationChance = 0.8f; - if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) - { - if (Pawn.SterileGenes()) return 0.0f; - // Replicate how rjw.PawnCapacityWorker_Fertility.CalculateCapacityLevel does it, but without the age factor - if (!Pawn.RaceHasFertility()) return 0.0f; - if (AndroidsCompatibility.IsAndroid(Pawn) && parent.def != Genital_Helper.archotech_vagina) return 0.0f; - foreach (var part in StatDefOf.Fertility.parts) - { - if(part is StatPart_FertilityByGenderAge fertilityByAge) - { - float factor = 1.0f; - fertilityByAge.TransformValue(StatRequest.For(Pawn), ref factor); - if (factor <= 0.0f) return 0.0f; // Too young or too old - } - else part.TransformValue(StatRequest.For(Pawn), ref ovulationChance); - } - if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder)) ovulationChance *= 10.0f; - try - { - calculatingOvulationChance = true; - ovulationChance *= PawnCapacityUtility.CalculateCapacityLevel(Pawn.health.hediffSet, xxx.reproduction); - } - finally { calculatingOvulationChance = false; } - } - return ovulationChance; - } - - protected float CalcuatedImplantChance() - { - float factor = 1.0f; - if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) - { - // Implant factor will be based solely on pawn age, plus any rollover from ovulation chance - StatPart_FertilityByGenderAge fertilityStatPart = StatDefOf.Fertility.GetStatPart(); - fertilityStatPart?.TransformValue(StatRequest.For(Pawn), ref factor); - if (OvulationChance > 1.0f) factor *= OvulationChance; - return Props.baseImplantationChanceFactor * FertilityModifier * factor; - } - else - { - return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * factor; - } - } - public float OvulationChance { get { - if (ovulationChanceCache < 0.0f) ovulationChanceCache = CalcuatedOvulationChance(); - return ovulationChanceCache; + float ovulationChance = 1.0f; + if (EggHealth <= 0.0f) return 0.0f; + if (EggHealth < 1.0f / 3.0f) ovulationChance = 0.8f; + if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) + { + if (Pawn.SterileGenes()) return 0.0f; + // Replicate how rjw.PawnCapacityWorker_Fertility.CalculateCapacityLevel does it, but without the age factor + if (!Pawn.RaceHasFertility()) return 0.0f; + if (AndroidsCompatibility.IsAndroid(Pawn) && parent.def != Genital_Helper.archotech_vagina) return 0.0f; + foreach (var part in StatDefOf.Fertility.parts) + { + if(part is StatPart_FertilityByGenderAge fertilityByAge) + { + float factor = 1.0f; + fertilityByAge.TransformValue(StatRequest.For(Pawn), ref factor); + if (factor <= 0.0f) return 0.0f; // Too young or too old + } + else part.TransformValue(StatRequest.For(Pawn), ref ovulationChance); + } + if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder)) ovulationChance *= 10.0f; + try + { + calculatingOvulationChance = true; + ovulationChance *= PawnCapacityUtility.CalculateCapacityLevel(Pawn.health.hediffSet, xxx.reproduction); + } + finally { calculatingOvulationChance = false; } + } + return ovulationChance; } } - public float ImplantChance { get { - if (implantationChanceCache < 0.0f) implantationChanceCache = CalcuatedImplantChance(); - return implantationChanceCache; + float factor = 1.0f; + if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) + { + // Implant factor will be based solely on pawn age, plus any rollover from ovulation chance + StatPart_FertilityByGenderAge fertilityStatPart = StatDefOf.Fertility.GetStatPart(); + fertilityStatPart?.TransformValue(StatRequest.For(Pawn), ref factor); + float ovulationOverflow = OvulationChance; + if (ovulationOverflow > 1.0f) factor *= ovulationOverflow; + return Props.baseImplantationChanceFactor * FertilityModifier * factor; + } + else + { + return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * factor; + } } } @@ -475,13 +449,25 @@ namespace RJW_Menstruation public string WombTex { - get => customwombtex ?? Props.wombTex; - set => customwombtex = value; + get + { + return customwombtex ?? Props.wombTex; + } + set + { + customwombtex = value; + } } public string VagTex { - get => customvagtex ?? Props.vagTex; - set => customvagtex = value; + get + { + return customvagtex ?? Props.vagTex; + } + set + { + customvagtex = value; + } } public string GetFertilizingInfo { @@ -515,12 +501,12 @@ namespace RJW_Menstruation /// /// returns fertstage. if not fertilized returns -1 /// - public int EggFertilizedTime + public int IsFertilized { get { if (eggs?.All(egg => !egg.fertilized) ?? true) return -1; - return eggs.Max(egg => egg.ticksSinceFertilization); + return eggs.Max(egg => egg.fertstage); } } public IEnumerable GetCummersAndFertilizers() @@ -534,12 +520,18 @@ namespace RJW_Menstruation } public bool IsEggExist { - get => !eggs.NullOrEmpty(); + get + { + return !eggs.NullOrEmpty(); + } } - public int EggLifespanTicks + public int EggLifespanHours { - get => eggLifeSpanTicks; + get + { + return eggLifeSpanHours; + } } public virtual bool IsDangerDay @@ -551,11 +543,11 @@ namespace RJW_Menstruation switch (curStage) { case Stage.Follicular: - return curStageTicks > 0.7f * currentIntervalTicks; + return curStageHrs > 0.7f * currentIntervalHours; case Stage.Ovulatory: return true; case Stage.Luteal: - return curStageTicks < EggLifespanTicks; + return curStageHrs < EggLifespanHours; default: return false; } @@ -563,7 +555,10 @@ namespace RJW_Menstruation } public int GetNumOfEggs { - get => eggs?.Count ?? 0; + get + { + return eggs?.Count ?? 0; + } } public Color BloodColor { @@ -571,13 +566,14 @@ namespace RJW_Menstruation { try { - Color c = Pawn.RaceProps.BloodDef.graphicData.color; + Color c = Pawn.def.race.BloodDef.graphicData.color; return c; } catch { return Colors.blood; } + } } @@ -591,19 +587,25 @@ namespace RJW_Menstruation } return originvagsize ?? 0.1f; } - set => originvagsize = value; + set + { + originvagsize = value; + } } - public int CurStageIntervalTicks + public float CurStageIntervalHours { - get => currentIntervalTicks; + get + { + return currentIntervalHours; + } } public float StageProgress { get { - if (pregnancy == null) return Mathf.Clamp01((float)curStageTicks / currentIntervalTicks); + if (pregnancy == null) return Mathf.Clamp01(curStageHrs / CurStageIntervalHours); bool is_discovered = false; switch (pregnancy) { @@ -625,21 +627,12 @@ namespace RJW_Menstruation if (Pawn.story?.bodyType == BodyTypeDefOf.Thin) discoveryTime = 0.25f; else if (Pawn.story?.bodyType == BodyTypeDefOf.Female) discoveryTime = 0.35f; // Estimated; there's no way to get the exact value after the fact without writing it into the save - float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * GenDate.HoursPerDay)); + float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * 24)); return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity); } } - public float StageProgessNextUpdate - { - get - { - if (pregnancy != null) return StageProgress; - return Mathf.Clamp01((float)(curStageTicks + TickInterval * Configurations.CycleAcceleration) / currentIntervalTicks); - } - } - public Texture2D GetStageTexture { get @@ -652,30 +645,19 @@ namespace RJW_Menstruation public override void CompExposeData() { base.CompExposeData(); - if (Scribe.mode == LoadSaveMode.LoadingVars) - { - int curStageHrs = -1; - int currentIntervalHours = -1; - Scribe_Values.Look(ref curStageHrs, "curStageHrs", curStageHrs, true); - Scribe_Values.Look(ref currentIntervalHours, "currentIntervalHours", currentIntervalHours, true); - if (curStageHrs >= 0) curStageTicks = curStageHrs * GenDate.TicksPerHour; - if (currentIntervalHours >= 0) currentIntervalTicks = currentIntervalHours * GenDate.TicksPerHour; - } - Scribe_Collections.Look(ref cums, saveDestroyedThings: true, label: "cums", lookMode: LookMode.Deep, ctorArgs: new object[0]); 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 curStageTicks, "curStageTicks", curStageTicks, true); + Scribe_Values.Look(ref curStageHrs, "curStageHrs", curStageHrs, true); Scribe_Values.Look(ref cycleSpeed, "cycleSpeed", cycleSpeed, true); Scribe_Values.Look(ref cycleVariability, "cycleVariability", cycleVariability, true); - Scribe_Values.Look(ref currentIntervalTicks, "currentIntervalTicks", currentIntervalTicks, true); + Scribe_Values.Look(ref currentIntervalHours, "currentIntervalHours", currentIntervalHours, true); Scribe_Values.Look(ref crampPain, "crampPain", crampPain, true); - Scribe_Values.Look(ref fluidToLeak, "fluidToLeak", 0); Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true); - Scribe_Values.Look(ref eggstack, "eggstack", 0); - Scribe_Values.Look(ref estrusflag, "estrusflag", false); + 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", false); + Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", DoCleanWomb, true); Scribe_References.Look(ref pregnancy, "pregnancy"); } @@ -690,16 +672,16 @@ namespace RJW_Menstruation public void Notify_UpdatedGenes() { - eggLifeSpanTicks = Props.eggLifespanDays * GenDate.TicksPerDay; + eggLifeSpanHours = Props.eggLifespanDays * 24; estrusLevel = Props.concealedEstrus ? EstrusLevel.Concealed : EstrusLevel.Visible; ovulationFactor = 1f; noBleeding = false; if (Pawn.genes == null || !ModsConfig.BiotechActive) return; - if (Pawn.genes.HasGene(VariousDefOf.ShortEggLifetime)) eggLifeSpanTicks = eggLifeSpanTicks * 3 / 4; - else if (Pawn.genes.HasGene(VariousDefOf.DoubleEggLifetime)) eggLifeSpanTicks *= 2; - else if (Pawn.genes.HasGene(VariousDefOf.QuadEggLifetime)) eggLifeSpanTicks *= 4; + if (Pawn.genes.HasGene(VariousDefOf.ShortEggLifetime)) eggLifeSpanHours = eggLifeSpanHours * 3 / 4; + else if (Pawn.genes.HasGene(VariousDefOf.DoubleEggLifetime)) eggLifeSpanHours *= 2; + else if (Pawn.genes.HasGene(VariousDefOf.QuadEggLifetime)) eggLifeSpanHours *= 4; if (Pawn.genes.HasGene(VariousDefOf.NeverEstrus)) estrusLevel = EstrusLevel.None; else if (Pawn.genes.HasGene(VariousDefOf.FullEstrus)) estrusLevel = EstrusLevel.Visible; @@ -713,7 +695,7 @@ namespace RJW_Menstruation public bool ShouldSimulate() { if (!Configurations.EnableAnimalCycle && Pawn.IsAnimal()) return false; - if (Pawn.SpawnedOrAnyParentSpawned || Pawn.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(Pawn)) return true; + if (Pawn.Spawned || Pawn.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(Pawn)) return true; return false; } @@ -743,8 +725,7 @@ namespace RJW_Menstruation Initialize(); } - if (Pawn.IsHashIntervalTick(recalculateTickInterval)) TickInterval = -1; // Every so often, force TickInterval to be recalculated in case the pawn's status changed. - if (!Pawn.IsHashIntervalTick(TickInterval)) return; + if (!Pawn.IsHashIntervalTick(tickInterval)) return; if (initError) Log.Warning($"Attempting to process {Pawn}'s womb uninitialized"); @@ -826,7 +807,6 @@ namespace RJW_Menstruation { get { - if (Pawn.Dead) return null; StringBuilder tip = new StringBuilder(); tip.Append(Translations.Dialog_WombInfo01); tip.Append(": "); @@ -841,17 +821,17 @@ namespace RJW_Menstruation } } - protected virtual int TicksToNextStage() + protected virtual int HoursToNextStage() { - return Math.Max(0,(currentIntervalTicks - curStageTicks) / Configurations.CycleAcceleration); + return Math.Max(0,(currentIntervalHours - curStageHrs) / Configurations.CycleAcceleration); } public override string CompDebugString() { - if (Pawn.Dead || curStage == Stage.None || curStage == Stage.Infertile || curStage == Stage.Pregnant) return null; + if (curStage == Stage.None || curStage == Stage.Infertile || curStage == Stage.Pregnant) return base.CompDebugString(); StringBuilder debugString = new StringBuilder(); debugString.Append($"Time to next state: "); - debugString.Append(GenDate.ToStringTicksToPeriod(TicksToNextStage())); + debugString.Append(GenDate.ToStringTicksToPeriod(HoursToNextStage() * GenDate.TicksPerHour)); return debugString.ToString(); } @@ -862,7 +842,11 @@ namespace RJW_Menstruation /// public Cum GetNotCum(string notcumlabel) { - return cums?.Find(cum => cum.notcum && cum.notcumLabel.Equals(notcumlabel)); + if (!cums.NullOrEmpty()) foreach (Cum cum in cums) + { + if (cum.notcum && cum.notcumLabel.Equals(notcumlabel)) return cum; + } + return null; } /// @@ -878,17 +862,17 @@ namespace RJW_Menstruation /// /// Inject pawn's cum into womb /// - /// + /// /// /// /// - public void CumIn(Pawn cummer, float volume, float fertility = 1.0f, bool precum = false) + public void CumIn(Pawn pawn, float volume, float fertility = 1.0f, bool precum = false) { if (volume <= 0) return; - if (!precum && fertility > 0 && IsDangerDay && cummer.relations.GetPregnancyApproachForPartner(Pawn) == PregnancyApproach.AvoidPregnancy) + if (!precum && fertility > 0 && IsDangerDay && pawn.relations.GetPregnancyApproachForPartner(Pawn) == PregnancyApproach.AvoidPregnancy) { float successChance = pulloutSuccessRate; - if (cummer.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; + if (pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; if (Pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) successChance *= fetishPulloutSuccessModifier; if (Rand.Chance(successChance)) return; } @@ -901,14 +885,14 @@ namespace RJW_Menstruation bool merged = false; if (!cums.NullOrEmpty()) foreach (Cum cum in cums) { - if (cum.pawn.Equals(cummer)) + if (cum.pawn.Equals(pawn)) { cum.MergeWithCum(volume, fertility); merged = true; } cum.DismishForce(cumoutrate); } - if (!merged) cums.Add(new Cum(cummer, volume * (1 - cumoutrate), fertility)); + if (!merged) cums.Add(new Cum(pawn, volume * (1 - cumoutrate), fertility)); } else { @@ -916,20 +900,20 @@ namespace RJW_Menstruation bool merged = false; if (!cums.NullOrEmpty()) foreach (Cum cum in cums) { - if (cum.pawn.Equals(cummer)) + if (cum.pawn.Equals(pawn)) { cum.MergeWithCum(volume, fertility); merged = true; } } - if (!merged) cums.Add(new Cum(cummer, volume, fertility)); + if (!merged) cums.Add(new Cum(pawn, volume, fertility)); } cumd = TotalCumPercent - cumd; if (!precum) { Pawn.records.AddTo(VariousDefOf.AmountofCreampied, volume); - AfterCumIn(cummer); + AfterCumIn(pawn); AfterFluidIn(cumd); } } @@ -937,12 +921,12 @@ namespace RJW_Menstruation /// /// Inject pawn's fluid into womb /// - /// + /// /// /// /// /// - public void CumIn(Pawn cummer, float volume, string notcumlabel, float decayresist = 0, ThingDef filthdef = null) + public void CumIn(Pawn pawn, float volume, string notcumlabel, float decayresist = 0, ThingDef filthdef = null) { if (volume <= 0) return; float tmp = TotalCum + volume; @@ -953,14 +937,14 @@ namespace RJW_Menstruation bool merged = false; if (!cums.NullOrEmpty()) foreach (Cum cum in cums) { - if (cum.notcum && cum.pawn.Equals(cummer) && cum.notcumLabel.Equals(notcumlabel)) + if (cum.notcum && cum.pawn.Equals(pawn) && cum.notcumLabel.Equals(notcumlabel)) { cum.MergeWithFluid(volume, decayresist, filthdef); merged = true; } cum.DismishForce(cumoutrate); } - if (!merged) cums.Add(new Cum(cummer, volume * (1 - cumoutrate), notcumlabel, decayresist, filthdef)); + if (!merged) cums.Add(new Cum(pawn, volume * (1 - cumoutrate), notcumlabel, decayresist, filthdef)); } else { @@ -968,13 +952,13 @@ namespace RJW_Menstruation bool merged = false; if (!cums.NullOrEmpty()) foreach (Cum cum in cums) { - if (cum.notcum && cum.pawn.Equals(cummer) && cum.notcumLabel.Equals(notcumlabel)) + if (cum.notcum && cum.pawn.Equals(pawn) && cum.notcumLabel.Equals(notcumlabel)) { cum.MergeWithFluid(volume, decayresist, filthdef); merged = true; } } - if (!merged) cums.Add(new Cum(cummer, volume, notcumlabel, decayresist, filthdef)); + if (!merged) cums.Add(new Cum(pawn, volume, notcumlabel, decayresist, filthdef)); } cumd = TotalCumPercent - cumd; AfterNotCumIn(); @@ -1014,23 +998,17 @@ namespace RJW_Menstruation absorber = (Absorber)Pawn.apparel?.WornApparel?.Find(x => x is Absorber); if (absorber != null) { - absorber.WearEffect(TickInterval); - if (absorber.dirty && absorber.EffectAfterDirty) absorber.DirtyEffect(TickInterval); + absorber.WearEffect(); + if (absorber.dirty && absorber.EffectAfterDirty) absorber.DirtyEffect(); } } /// /// For natural leaking /// - protected virtual void AfterCumOut(float amount, List filthlabels) + protected virtual void AfterCumOut() { - fluidToLeak += amount; - if (fluidToLeak > fluidLeakThreshold) Pawn.needs?.mood?.thoughts?.memories?.TryGainMemory(VariousDefOf.LeakingFluids); - for (; fluidToLeak > fluidLeakThreshold; fluidToLeak -= fluidLeakThreshold) - { - if (cums.Count > 1) MakeCumFilthMixture(fluidLeakThreshold, filthlabels); - else if (cums.Count == 1) MakeCumFilth(cums.First(), fluidLeakThreshold); - } + Pawn.needs?.mood?.thoughts?.memories?.TryGainMemory(VariousDefOf.LeakingFluids); } /// @@ -1059,20 +1037,24 @@ namespace RJW_Menstruation if (TotalCum > Props.maxCumCapacity * Pawn.BodySize) leakfactor = Math.Min(1 + (TotalCum - Props.maxCumCapacity * Pawn.BodySize) / 10, 2f); if (absorber != null && absorber.dirty && !absorber.LeakAfterDirty) leakfactor = 0f; if (Pawn.CurJobDef == xxx.knotted) leakfactor = 0f; + HashSet removecums = new HashSet(); foreach (Cum cum in cums) { - if (Rand.Chance(SimulationsPerHour)) cum.CumEffects(Pawn); + cum.CumEffects(Pawn); float vd = cum.DismishNatural(leakfactor, this, antisperm); - cum.MakeThinner((float)Configurations.CycleAcceleration * SimulationsPerHour); + cum.MakeThinner(Configurations.CycleAcceleration); totalleak += AbsorbCum(vd, absorber); string tmp = "FilthLabelWithSource".Translate(cum.FilthDef.label, cum.pawn?.LabelShort ?? "Unknown", 1.ToString()); filthlabels.Add(tmp.Replace(" x1", "")); + if (cum.ShouldRemove()) removecums.Add(cum); } - AfterCumOut(totalleak, filthlabels); - cums.RemoveAll(cum => cum.ShouldRemove()); - if (cums.NullOrEmpty()) fluidToLeak = 0; + if (cums.Count > 1) MakeCumFilthMixture(totalleak, filthlabels); + else if (cums.Count == 1) MakeCumFilth(cums.First(), totalleak); + cums.RemoveAll(cum => removecums.Contains(cum)); cumd = TotalCumPercent - cumd; + if (totalleak >= 1.0f) AfterCumOut(); AfterFluidOut(cumd); + } /// @@ -1102,7 +1084,6 @@ namespace RJW_Menstruation if (cums.Count > 1) MakeCumFilthMixture(totalleak, filthlabels); else if (cums.Count == 1) MakeCumFilth(cums.First(), totalleak); cums.RemoveAll(cum => removecums.Contains(cum)); - if (cums.NullOrEmpty()) fluidToLeak = 0; cumd = TotalCumPercent - cumd; AfterFluidOut(cumd); return outcum; @@ -1132,7 +1113,6 @@ namespace RJW_Menstruation if (cum.notcum) pure = false; } cums.RemoveAll(cum => removecums.Contains(cum)); - if (cums.NullOrEmpty()) fluidToLeak = 0; return new CumMixture(Pawn, totalleak, cumlabels, color, mixtureDef, pure); } @@ -1145,11 +1125,6 @@ namespace RJW_Menstruation cums.Clear(); } - public void RemoveAllEggs() - { - eggs.Clear(); - } - /// /// Fertilize eggs and return the result @@ -1173,13 +1148,11 @@ namespace RJW_Menstruation initError = true; Props = (CompProperties_Menstruation)props; - if (cums == null) cums = new List(); - if (eggs == null) eggs = new List(); - - PreInitialize(); + Notify_UpdatedGenes(); if (Props.infertile) { + if (cums == null) cums = new List(); curStage = Stage.None; loaded = true; initError = false; @@ -1191,20 +1164,22 @@ namespace RJW_Menstruation InitOvary(); - if (currentIntervalTicks < 0) + if (currentIntervalHours < 0) { if (ShouldBeInfertile()) curStage = Stage.Infertile; else if (!IsBreedingSeason()) curStage = Stage.Anestrus; else curStage = RandomStage(); if (curStage == Stage.Follicular) - currentIntervalTicks = PeriodRandomizer(Stage.Follicular) - PeriodRandomizer(Stage.Bleeding); + currentIntervalHours = PeriodRandomizer(Stage.Follicular) - PeriodRandomizer(Stage.Bleeding); else - currentIntervalTicks = PeriodRandomizer(curStage); - if (currentIntervalTicks < 0) currentIntervalTicks = 0; - else if (currentIntervalTicks < curStageTicks) curStageTicks = currentIntervalTicks; + currentIntervalHours = PeriodRandomizer(curStage); + if (currentIntervalHours <= 0) currentIntervalHours = 1; + else if (currentIntervalHours < curStageHrs) curStageHrs = currentIntervalHours; } if (crampPain < 0) crampPain = PainRandomizer(); InitializeExtraValues(); + if (cums == null) cums = new List(); + if (eggs == null) eggs = new List(); TakeLoosePregnancy(); @@ -1213,11 +1188,6 @@ namespace RJW_Menstruation initError = false; } - protected virtual void PreInitialize() - { - Notify_UpdatedGenes(); - } - protected virtual void InitializeExtraValues() { } @@ -1247,7 +1217,7 @@ namespace RJW_Menstruation float avglittersize; try { - avglittersize = Mathf.Max(Rand.ByCurveAverage(Pawn.RaceProps.litterSizeCurve), 1.0f); + avglittersize = Mathf.Max(Rand.ByCurveAverage(Pawn.def.race.litterSizeCurve), 1.0f); } catch (NullReferenceException) { @@ -1290,8 +1260,6 @@ namespace RJW_Menstruation protected virtual void BeforeSimulator() { - ovulationChanceCache = -1.0f; - implantationChanceCache = -1.0f; CumOut(); } @@ -1311,11 +1279,11 @@ namespace RJW_Menstruation switch (curStage) { case Stage.Follicular: - return curStageTicks > currentIntervalTicks - Props.estrusDaysBeforeOvulation * GenDate.TicksPerDay; + return curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24; case Stage.Ovulatory: return true; case Stage.Luteal: - return curStageTicks < EggLifespanTicks; + return curStageHrs < EggLifespanHours; default: return false; } @@ -1365,12 +1333,9 @@ namespace RJW_Menstruation if (eligibleCum.Count == 0) return null; float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume); - - //float fertFailChancePerHour = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor); - //float fertFailChancePerInterval = Mathf.Pow(fertFailChancePerHour, (float)TickInterval / GenDate.TicksPerHour); - float fertFailChancePerInterval = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor * SimulationsPerHour); - if (Rand.Chance(fertFailChancePerInterval)) return null; + if (Rand.Chance(Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor))) + return null; Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1); float selection = Rand.Range(0.0f, totalFertPower); @@ -1395,8 +1360,8 @@ namespace RJW_Menstruation foreach (Egg egg in eggs) { if (!egg.fertilized || - egg.ticksSinceFertilization < minImplantAgeHours * GenDate.TicksPerHour || - egg.ageTicks < Math.Min(Props.lutealIntervalDays * GenDate.TicksPerDay / 2, maxImplantDelayHours * GenDate.TicksPerHour)) + egg.fertstage < minImplantAgeHours || + egg.position < Math.Min(Props.lutealIntervalDays * 24 / 2, maxImplantDelayHours)) continue; else if (egg.fertilizer == null) { @@ -1480,18 +1445,14 @@ namespace RJW_Menstruation if (pregnancy is Hediff_BasePregnancy rjw_preg) { // TODO: advance biotech pregnancy - rjw_preg.p_start_tick -= egg.ticksSinceFertilization / Configurations.CycleAcceleration; - rjw_preg.p_end_tick -= egg.ticksSinceFertilization / Configurations.CycleAcceleration; + rjw_preg.p_start_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour; + rjw_preg.p_end_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour; } } } else - { - if (Configurations.Debug) - { - float implantChance = Configurations.ImplantationChance * ImplantChance * InterspeciesImplantFactor(egg.fertilizer); - Log.Message($"Fertilized egg of {Pawn} failed to implant (chance {implantChance.ToStringPercent()}, father {egg.fertilizer})"); - } + { + if (Configurations.Debug) Log.Message($"Fertilized egg of {Pawn} failed to implant (father {egg.fertilizer})"); deadeggs.Add(egg); } } @@ -1510,9 +1471,7 @@ namespace RJW_Menstruation protected void BleedOut() { - // ~1.5 per hour times acceleration - float bledAmount = 0.03f * Configurations.BleedingAmount * Configurations.CycleAcceleration * Rand.Range(0.5f, 1.5f) * SimulationsPerHour; - CumIn(Pawn, bledAmount, Translations.Menstrual_Blood, -5.0f, Pawn.RaceProps?.BloodDef ?? ThingDefOf.Filth_Blood); + CumIn(Pawn, Rand.Range(0.02f * Configurations.BleedingAmount, 0.04f * Configurations.BleedingAmount), Translations.Menstrual_Blood, -5.0f, Pawn.def.race?.BloodDef ?? ThingDefOf.Filth_Blood); Cum blood = GetNotCum(Translations.Menstrual_Blood); if (blood != null) blood.Color = BloodColor; } @@ -1579,12 +1538,12 @@ namespace RJW_Menstruation HashSet deadeggs = new HashSet(); foreach (Egg egg in eggs) { - egg.ageTicks += TickInterval * Configurations.CycleAcceleration; - if (egg.fertilized) egg.ticksSinceFertilization += TickInterval * Configurations.CycleAcceleration; + egg.position += Configurations.CycleAcceleration; + if (egg.fertilized) egg.fertstage += Configurations.CycleAcceleration; else { - egg.lifeSpanTicks -= TickInterval * Configurations.CycleAcceleration; - if (egg.lifeSpanTicks < 0) deadeggs.Add(egg); + egg.lifespanhrs -= Configurations.CycleAcceleration; + if (egg.lifespanhrs < 0) deadeggs.Add(egg); } } eggs.RemoveAll(egg => deadeggs.Contains(egg)); @@ -1595,7 +1554,7 @@ namespace RJW_Menstruation Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_MenstrualCramp, Pawn); hediff.Severity = crampPain * Rand.Range(0.9f, 1.1f); HediffCompProperties_SeverityPerDay Prop = (HediffCompProperties_SeverityPerDay)hediff.TryGetComp().props; - Prop.severityPerDay = -hediff.Severity / (currentIntervalTicks / GenDate.TicksPerDay) * Configurations.CycleAcceleration; + Prop.severityPerDay = -hediff.Severity / (currentIntervalHours / 24) * Configurations.CycleAcceleration; Pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(Pawn)); } @@ -1607,14 +1566,14 @@ namespace RJW_Menstruation GoNextStage(Stage.Anestrus); return; } - else if (curStageTicks >= currentIntervalTicks) + else if (curStageHrs >= currentIntervalHours) { GoOvulatoryStage(); } else { - curStageTicks += TickInterval * Configurations.CycleAcceleration; - if (!estrusflag && curStageTicks > currentIntervalTicks - Props.estrusDaysBeforeOvulation * GenDate.TicksPerDay) + curStageHrs += Configurations.CycleAcceleration; + if (!estrusflag && curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24) { estrusflag = true; SetEstrus(); @@ -1625,16 +1584,11 @@ namespace RJW_Menstruation protected virtual void OvulatoryAction() { - if (curStageTicks < currentIntervalTicks) - { - curStageTicks += TickInterval * Configurations.CycleAcceleration; - return; - } estrusflag = false; float eggnum; try { - eggnum = Math.Max(Rand.ByCurve(Pawn.RaceProps.litterSizeCurve), 1f); + eggnum = Math.Max(Rand.ByCurve(Pawn.def.race.litterSizeCurve), 1f); } catch (NullReferenceException) { @@ -1648,24 +1602,27 @@ namespace RJW_Menstruation eggnum *= ovulationFactor; int toOvulate = (int)eggnum + eggstack; + float ovulationChance = OvulationChance; int ovulated = 0; for (int i = 0; i < toOvulate; i++) - if (i < eggstack || Rand.Chance(OvulationChance)) // eggstack comes from drugs and are guaranteed ovulated + if (i < eggstack || Rand.Chance(ovulationChance)) // eggstack comes from drugs and are guaranteed ovulated { - eggs.Add(new Egg((int)(EggLifespanTicks / CycleFactor))); + eggs.Add(new Egg((int)(EggLifespanHours / CycleFactor))); ++ovulated; } + if(ovulated > ovarypower) ovulated = Math.Min(ovarypower, eggstack); + ovarypower -= ovulated; eggstack = 0; if (Configurations.Debug && ovulated != toOvulate) - Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({OvulationChance.ToStringPercent()} chance)"); + Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({ovulationChance.ToStringPercent()} chance)"); GoNextStage(Stage.Luteal); } protected virtual void LutealAction() { - if (curStageTicks >= currentIntervalTicks) + if (curStageHrs >= currentIntervalHours) { eggs.Clear(); if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Chance(0.3f))) //skips bleeding @@ -1687,13 +1644,13 @@ namespace RJW_Menstruation } else { - curStageTicks += TickInterval * Configurations.CycleAcceleration; + curStageHrs += Configurations.CycleAcceleration; StayCurrentStage(); } } else { - curStageTicks += TickInterval * Configurations.CycleAcceleration; + curStageHrs += Configurations.CycleAcceleration; StayCurrentStage(); } @@ -1701,23 +1658,23 @@ namespace RJW_Menstruation protected virtual void BleedingAction() { - if (curStageTicks >= currentIntervalTicks) + if (curStageHrs >= currentIntervalHours) { Hediff hediff = Pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp); if (hediff != null && !Pawn.GetMenstruationComps().Any(comp => comp != this && comp.curStage == Stage.Bleeding)) Pawn.health.RemoveHediff(hediff); - int totalFollicularTicks = PeriodRandomizer(Stage.Follicular); // The total amount of time for both bleeding and follicular - if (totalFollicularTicks <= currentIntervalTicks) // We've bled for so long that we completely missed the follicular phase + int totalFollicularHours = PeriodRandomizer(Stage.Follicular); // 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(); else { - currentIntervalTicks = totalFollicularTicks - currentIntervalTicks; // I.e., the remaining follicular time equals the total minus the bleeding time elapsed + currentIntervalHours = totalFollicularHours - currentIntervalHours; // I.e., the remaining follicular hours equals the total minus the bleeding hours elapsed GoNextStage(Stage.Follicular, false); } } else { - if (curStageTicks < currentIntervalTicks / 4) BleedOut(); - curStageTicks += TickInterval * Configurations.CycleAcceleration; + if (curStageHrs < currentIntervalHours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut(); + curStageHrs += Configurations.CycleAcceleration; StayCurrentStage(); } } @@ -1733,7 +1690,7 @@ namespace RJW_Menstruation if (pregnancy != null && Pawn.health.hediffSet.hediffs.Contains(pregnancy)) { - curStageTicks += TickInterval; + curStageHrs += 1; StayCurrentStageConst(Stage.Pregnant); } else @@ -1745,7 +1702,7 @@ namespace RJW_Menstruation protected virtual void RecoverAction() { - if (curStageTicks >= currentIntervalTicks) + if (curStageHrs >= currentIntervalHours) { if (ShouldBeInfertile()) { @@ -1762,7 +1719,7 @@ namespace RJW_Menstruation } else { - curStageTicks += TickInterval * Configurations.CycleAcceleration; + curStageHrs += Configurations.CycleAcceleration; StayCurrentStage(); } } @@ -1797,7 +1754,8 @@ namespace RJW_Menstruation if (!xxx.is_human(Pawn) || !xxx.is_human(cummer)) return; if ((cummer.HasQuirk(QuirkUtility.Quirks.Teratophile) != (Pawn.GetStatValue(StatDefOf.PawnBeauty) >= 0)) || - cummer.IsProPregnancy()) + cummer.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || + cummer.HasQuirk(QuirkUtility.Quirks.Breeder)) { if (cummer.relations.OpinionOf(Pawn) <= -25) { @@ -1811,7 +1769,7 @@ namespace RJW_Menstruation if (IsDangerDay) { - if (Pawn.IsProPregnancy()) + if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || Pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) { Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer); } @@ -1834,7 +1792,7 @@ namespace RJW_Menstruation } else { - if (Pawn.IsProPregnancy()) + if (Pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || Pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) { Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetishSafe, cummer); } @@ -1857,8 +1815,8 @@ namespace RJW_Menstruation public void GoNextStage(Stage nextstage, bool calculateHours = true) { - curStageTicks = 0; - if (calculateHours) currentIntervalTicks = PeriodRandomizer(nextstage); + curStageHrs = 0; + if (calculateHours) currentIntervalHours = PeriodRandomizer(nextstage); curStage = nextstage; } @@ -1900,17 +1858,15 @@ namespace RJW_Menstruation switch (stage) { case Stage.Follicular: - return (int)(Props.follicularIntervalDays * GenDate.TicksPerDay * (1 + Rand.Range(-cycleVariability, cycleVariability) * 1.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 1.5f)); - case Stage.Ovulatory: - return Props.ovulationIntervalHours * GenDate.TicksPerHour; // No variability for now + return (int)(Props.follicularIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 1.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 1.5f)); case Stage.Luteal: - return (int)(Props.lutealIntervalDays * GenDate.TicksPerDay * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); + return (int)(Props.lutealIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); case Stage.Bleeding: - return (int)(Props.bleedingIntervalDays * GenDate.TicksPerDay * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); + 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 * GenDate.TicksPerDay * Rand.Range(0.95f, 1.05f)); + return (int)(Props.recoveryIntervalDays * 24 * Rand.Range(0.95f, 1.05f)); case Stage.Pregnant: - return (int)(MenstruationUtility.GestationHours(pregnancy) * GenDate.TicksPerHour); + return (int)MenstruationUtility.GestationHours(pregnancy); default: return 1; } @@ -1946,13 +1902,13 @@ namespace RJW_Menstruation switch (stage) { case Stage.Follicular: - curStageTicks = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * GenDate.TicksPerDay); + curStageHrs = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * 24); break; case Stage.Luteal: - curStageTicks = Rand.Range(0, Props.lutealIntervalDays * GenDate.TicksPerDay); + curStageHrs = Rand.Range(0, Props.lutealIntervalDays * 24); break; case Stage.Bleeding: - curStageTicks = Rand.Range(0, Props.bleedingIntervalDays * GenDate.TicksPerDay); + curStageHrs = Rand.Range(0, Props.bleedingIntervalDays * 24); break; } return stage; @@ -1998,52 +1954,38 @@ namespace RJW_Menstruation public class Egg : IExposable { public bool fertilized; - public int lifeSpanTicks; // Actual ticks scaled by cycleAcceleration + public int lifespanhrs; public Pawn fertilizer; - public int ageTicks; - public int ticksSinceFertilization = 0; + public int position; + public int fertstage = 0; public Egg() { fertilized = false; - lifeSpanTicks = (int)(96 * GenDate.TicksPerHour * Configurations.EggLifespanMultiplier); + lifespanhrs = (int)(96 * Configurations.EggLifespanMultiplier); fertilizer = null; - ageTicks = 0; + position = 0; } - public Egg(int lifespanticks) + public Egg(int lifespanhrs) { fertilized = false; - lifeSpanTicks = (int)(lifespanticks * Configurations.EggLifespanMultiplier); + this.lifespanhrs = (int)(lifespanhrs * Configurations.EggLifespanMultiplier); fertilizer = null; - ageTicks = 0; + position = 0; } public void ExposeData() { - if (Scribe.mode == LoadSaveMode.LoadingVars) - { - int lifespanhrs = -1; - int position = -1; - Scribe_Values.Look(ref lifespanhrs, "lifespanhrs", lifespanhrs, true); - Scribe_Values.Look(ref position, "position", position, true); - if (lifespanhrs >= 0) lifeSpanTicks = lifespanhrs * GenDate.TicksPerHour; - if (position >= 0) ageTicks = position * GenDate.TicksPerHour; - } Scribe_References.Look(ref fertilizer, "fertilizer", true); - Scribe_Values.Look(ref fertilized, "fertilized", false); - Scribe_Values.Look(ref lifeSpanTicks, "lifeSpanTicks", lifeSpanTicks, true); - Scribe_Values.Look(ref ageTicks, "ageTicks", ageTicks, true); - Scribe_Values.Look(ref ticksSinceFertilization, "ticksSinceFertilization", 0); - if (ticksSinceFertilization == 0 && Scribe.mode == LoadSaveMode.LoadingVars) - { - // A bit awkward to do this twice, but it prevents ticksSinceFertilization from getting overwritten on a fertstage load - int fertstage = -1; - Scribe_Values.Look(ref fertstage, "fertstage", fertstage, true); - if (fertstage >= 0) ticksSinceFertilization = fertstage * GenDate.TicksPerHour; - } + Scribe_Values.Look(ref fertilized, "fertilized", fertilized, true); + Scribe_Values.Look(ref lifespanhrs, "lifespanhrs", lifespanhrs, true); + Scribe_Values.Look(ref position, "position", position, true); + Scribe_Values.Look(ref fertstage, "fertstage", fertstage, true); } } + + } public class HediffComp_Anus : HediffComp diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs index 017a6ed..6611547 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PeriodicOvulator.cs @@ -16,28 +16,23 @@ namespace RJW_Menstruation public class HediffComp_PeriodicOvulator : HediffComp_Menstruation { - public int ticksToNextCycle = -100000; - public int averageCycleIntervalTicks = -1; + public int hoursToNextCycle = -100000; + public int averageCycleIntervalHours = -1; public new CompProperties_PeriodicOvulator Props; - protected override void PreInitialize() - { - base.PreInitialize(); - Props = (CompProperties_PeriodicOvulator)props; - } - protected override void InitializeExtraValues() { - base.InitializeExtraValues(); - if (averageCycleIntervalTicks < 0) + base.InitializeExtraValues(); + Props = (CompProperties_PeriodicOvulator)props; + if (averageCycleIntervalHours < 0) { - averageCycleIntervalTicks = (int)(Props.cycleIntervalDays.RandomInRange * GenDate.TicksPerDay / cycleSpeed); - if (ticksToNextCycle < -50000) - ticksToNextCycle = Rand.Range(0, averageCycleIntervalTicks); + averageCycleIntervalHours = (int)(24f * Props.cycleIntervalDays.RandomInRange / cycleSpeed); + if (hoursToNextCycle < -50000) + hoursToNextCycle = Rand.Range(0, averageCycleIntervalHours); // Make the cutoff halfway into cycle, just to be sure there isn't a double-cycle the first time if ((curStage == Stage.Follicular || curStage == Stage.Luteal || curStage == Stage.Bleeding) - && (averageCycleIntervalTicks - ticksToNextCycle) / 2 >= GenDate.TicksPerDay * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed) + && (averageCycleIntervalHours - hoursToNextCycle) / 2 >= 24 * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed) GoNextStage(Stage.Anestrus); } } @@ -45,46 +40,40 @@ namespace RJW_Menstruation protected override float RaceCyclesPerYear() { // Don't bother trying to work seasonal breeding into the math - // Base it off of the shortest cycle interval of the vagina - return GenDate.DaysPerYear / (Props.cycleIntervalDays.TrueMin / Configurations.CycleAccelerationDefault); + // Due to the enormous variation in possible cycle gaps, cheat and base it off the individual + return averageCycleIntervalHours * cycleSpeed / (24 * 360); // cancel out their cycleSpeed from initialization to get their "normal" speed } protected override void BeforeSimulator() { base.BeforeSimulator(); - if (ticksToNextCycle > 0) ticksToNextCycle -= TickInterval * Configurations.CycleAcceleration; + if (hoursToNextCycle > 0) hoursToNextCycle -= Configurations.CycleAcceleration; } public override void CompExposeData() { base.CompExposeData(); - if (Scribe.mode == LoadSaveMode.LoadingVars) - { - int hoursToNextCycle = -1; - int averageCycleIntervalHours = -1; - Scribe_Values.Look(ref hoursToNextCycle, "hoursToNextCycle", hoursToNextCycle, true); - Scribe_Values.Look(ref averageCycleIntervalHours, "averageCycleIntervalHours", averageCycleIntervalHours, true); - if (hoursToNextCycle >= 0) ticksToNextCycle = hoursToNextCycle * GenDate.TicksPerHour; - if (averageCycleIntervalHours >= 0) averageCycleIntervalTicks = averageCycleIntervalHours * GenDate.TicksPerHour; - } - Scribe_Values.Look(ref ticksToNextCycle, "ticksToNextCycle", ticksToNextCycle, true); - Scribe_Values.Look(ref averageCycleIntervalTicks, "averageCycleIntervalTicks", averageCycleIntervalTicks, true); + Scribe_Values.Look(ref hoursToNextCycle, "hoursToNextCycle", hoursToNextCycle, true); + Scribe_Values.Look(ref averageCycleIntervalHours, "averageCycleIntervalHours", averageCycleIntervalHours, true); } - protected override int TicksToNextStage() + protected override int HoursToNextStage() { - if (curStage == Stage.Anestrus && ticksToNextCycle > 0) return ticksToNextCycle / Configurations.CycleAcceleration; - else return base.TicksToNextStage(); + if (curStage == Stage.Anestrus && hoursToNextCycle > 0) return hoursToNextCycle / Configurations.CycleAcceleration; + else return base.HoursToNextStage(); } protected override void BleedingAction() { - base.BleedingAction(); - if (curStage != Stage.Bleeding) + if (curStageHrs >= currentIntervalHours) { + Hediff hediff = Pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp); + if (hediff != null && !Pawn.GetMenstruationComps().Any(comp => comp != this && comp.curStage == Stage.Bleeding)) Pawn.health.RemoveHediff(hediff); estrusflag = false; GoNextStage(Stage.Anestrus); + return; } + else base.BleedingAction(); } protected override void PregnantAction() @@ -92,14 +81,14 @@ namespace RJW_Menstruation base.PregnantAction(); if (curStage != Stage.Pregnant) // Go halfway into the cycle - ticksToNextCycle = (int)(averageCycleIntervalTicks * (1 + Rand.Range(-cycleVariability, cycleVariability))) / 2; + hoursToNextCycle = (int)(averageCycleIntervalHours * (1 + Rand.Range(-cycleVariability, cycleVariability))) / 2; } protected override void AnestrusAction() { - if (ticksToNextCycle <= 0) + if (hoursToNextCycle <= 0) { - ticksToNextCycle = (int)(averageCycleIntervalTicks * (1 + Rand.Range(-cycleVariability, cycleVariability))); + hoursToNextCycle = (int)(averageCycleIntervalHours * (1 + Rand.Range(-cycleVariability, cycleVariability))); if (IsBreedingSeason()) GoNextStage(Stage.Follicular); return; } @@ -110,7 +99,7 @@ namespace RJW_Menstruation { base.CopyCycleProperties(original); if (original is HediffComp_PeriodicOvulator comp) - averageCycleIntervalTicks = comp.averageCycleIntervalTicks; + averageCycleIntervalHours = comp.averageCycleIntervalHours; } } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs index ce0efe9..8d7ab50 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabies.cs @@ -213,7 +213,7 @@ namespace RJW_Menstruation PregnancyUtility.ApplyBirthOutcome(thisOutcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments); // No more babies if mom dies halfway through. Unrealistic maybe, but saves a lot of headache in ApplyBirthOutcome - if (mother.Dead) break; + if (mother.health.Dead) break; if (xxx.is_human(baby)) mother.records.Increment(xxx.CountOfBirthHuman); else if (xxx.is_animal(baby)) @@ -266,7 +266,7 @@ namespace RJW_Menstruation baby.relations.ClearAllRelations(); PregnancyUtility.ApplyBirthOutcome(outcome, quality, ritual, genes, geneticMother, birtherThing, thisFather, doctor, lordJobRitual, assignments); - if (mother.Dead) break; + if (mother.health.Dead) break; if (xxx.is_human(baby)) mother.records.Increment(xxx.CountOfBirthHuman); else if (xxx.is_animal(baby)) diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs index c3cd7e4..d67fbb4 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs @@ -3,7 +3,6 @@ using RimWorld.Planet; using rjw; using System; using System.Collections.Generic; -using System.Diagnostics.Eventing.Reader; using System.Linq; using UnityEngine; using Verse; @@ -218,50 +217,44 @@ namespace RJW_Menstruation return wombtex; } - public static Texture2D GetOvaryIcon(this HediffComp_Menstruation comp) - { - const float ovaryChanceToShow_01 = 0.2f; - const float ovaryChanceToShow_02 = 0.8f; - float ovulatoryProgress; - bool isInduced = comp is HediffComp_InducedOvulator; - if (comp.curStage == HediffComp_Menstruation.Stage.Follicular && - isInduced && - comp.Pawn.jobs.curDriver is JobDriver_Sex job && - job.Sexprops != null && - !job.Sexprops.usedCondom && - (job.Sexprops.sexType == xxx.rjwSextype.Vaginal || job.Sexprops.sexType == xxx.rjwSextype.DoublePenetration)) - ovulatoryProgress = 0.0f; - else if (comp.curStage == HediffComp_Menstruation.Stage.Ovulatory) ovulatoryProgress = isInduced ? Mathf.Max(ovaryChanceToShow_01, comp.StageProgessNextUpdate) : comp.StageProgessNextUpdate; -// else if (comp.curStage == HediffComp_Menstruation.Stage.Luteal && comp.IsEggExist) return ContentFinder.Get("Ovaries/Ovary_02", true); - else return ContentFinder.Get("Womb/Empty", true); - - float combinedAppearance = ovulatoryProgress * comp.OvulationChance; - if (combinedAppearance >= ovaryChanceToShow_02 && comp.OvulationChance >= 1.0f) return ContentFinder.Get("Ovaries/Ovary_02", true); - else if (combinedAppearance >= ovaryChanceToShow_01) return ContentFinder.Get("Ovaries/Ovary_01", true); - else return ContentFinder.Get("Ovaries/Ovary_00", true); - } public static Texture2D GetEggIcon(this HediffComp_Menstruation comp, bool includeOvary) { + const float ovaryChanceToShow_01 = 0.4f; + const float ovaryChanceToShow_02 = 1.0f; switch (comp.CurrentVisibleStage) { case HediffComp_Menstruation.Stage.Follicular: + if (!includeOvary) break; + if (comp is HediffComp_InducedOvulator) + { + if (comp.Pawn.jobs.curDriver is JobDriver_Sex job && + job.Sexprops != null && + !job.Sexprops.usedCondom && + (job.Sexprops.sexType == xxx.rjwSextype.Vaginal || job.Sexprops.sexType == xxx.rjwSextype.DoublePenetration)) + return ContentFinder.Get((comp.OvulationChance >= ovaryChanceToShow_01) ? "Ovaries/Ovary_01" : "Ovaries_Ovary_00", true); + else break; + } + if (comp.curStageHrs > comp.CurStageIntervalHours - 30) // Approximate time for ovulation to occur + return ContentFinder.Get((comp.OvulationChance >= ovaryChanceToShow_01) ? "Ovaries/Ovary_01" : "Ovaries_Ovary_00", true); + else break; case HediffComp_Menstruation.Stage.Ovulatory: if (!includeOvary) break; - else return GetOvaryIcon(comp); + if (comp.OvulationChance >= ovaryChanceToShow_02) + return ContentFinder.Get("Ovaries/Ovary_02", true); + else if (comp.OvulationChance >= ovaryChanceToShow_01) + return ContentFinder.Get("Ovaries/Ovary_01", true); + else + return ContentFinder.Get("Ovaries/Ovary_00", true); case HediffComp_Menstruation.Stage.Luteal: if (!comp.IsEggExist) break; - int fertTime = comp.EggFertilizedTime; - if (fertTime >= 0) + int fertstage = comp.IsFertilized; + if (fertstage >= 0) { - if (fertTime <= GenDate.TicksPerHour * Configurations.CycleAcceleration) return ContentFinder.Get("Eggs/Egg_Fertilizing02", true); - else if (fertTime <= 18 * GenDate.TicksPerHour) return ContentFinder.Get("Eggs/Egg_Fertilized00", true); - else if (fertTime <= 54 * GenDate.TicksPerHour) return ContentFinder.Get("Eggs/Egg_Fertilized01", true); + if (fertstage <= Configurations.CycleAcceleration) return ContentFinder.Get("Eggs/Egg_Fertilizing02", true); + else if (fertstage <= 18) return ContentFinder.Get("Eggs/Egg_Fertilized00", true); + else if (fertstage <= 54) return ContentFinder.Get("Eggs/Egg_Fertilized01", true); else return ContentFinder.Get("Eggs/Egg_Fertilized02", true); } - else if (includeOvary && comp.curStageTicks <= comp.Props.ovulationIntervalHours * 0.4f * GenDate.TicksPerHour) // Total about as long as it spent in Ovary_01 - { - return ContentFinder.Get("Ovaries/Ovary_02", true); - } else if (comp.IsEggFertilizing) { if (comp.GetFertilityChance() < 0.5f) @@ -355,7 +348,7 @@ namespace RJW_Menstruation else if (hediff is Hediff_BasePregnancy rjw_preg) return (rjw_preg.p_end_tick - rjw_preg.p_start_tick) / GenDate.TicksPerHour; // TODO: Biotech pregnancy - else return hediff.pawn.RaceProps.gestationPeriodDays * GenDate.HoursPerDay; + else return hediff.pawn.def.race.gestationPeriodDays * GenDate.HoursPerDay; } public static float RandomVariabilityPercent(int recursion = 0) @@ -407,22 +400,6 @@ namespace RJW_Menstruation return false; } - public static bool IsProPregnancy(this Pawn pawn) - { - if (pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || - pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish)) - return true; - - Ideo ideo = pawn.Ideo; - if (ideo == null || VariousDefOf.Pregnancy_Elevated == null) return false; - if (ideo.HasPrecept(VariousDefOf.Pregnancy_Elevated) || - ideo.HasPrecept(VariousDefOf.Pregnancy_Holy) || - ideo.HasPrecept(VariousDefOf.Pregnancy_Required)) - return true; - - return false; - } - public static float DamagePants(this Pawn pawn, float fluidAmount) { if (pawn.apparel == null) return 0; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs index 0b5d0c5..b47d614 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs @@ -23,11 +23,11 @@ namespace RJW_Menstruation { if (is_discovered || !xxx.is_human(pawn) || - pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || (pawn.Ideo?.HasPrecept(VariousDefOf.Pregnancy_Required) ?? false) || + pawn.HasQuirk(QuirkUtility.Quirks.Breeder) || (pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Spouse) || x.def.Equals(PawnRelationDefOf.Fiance))) != null) return; - if (pawn.IsProPregnancy() || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null) + if (pawn.HasQuirk(QuirkUtility.Quirks.ImpregnationFetish) || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null) { pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancyMild); } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs index 4bd3cef..df6584b 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Biotech_Patch.cs @@ -117,7 +117,7 @@ namespace RJW_Menstruation { public static void Postfix(Thing birtherThing) { - if (birtherThing is Pawn pawn && !pawn.Dead) + if (birtherThing is Pawn pawn && !pawn.health.Dead) pawn.GetBreastComp()?.GaveBirth(); } } @@ -192,20 +192,17 @@ namespace RJW_Menstruation } } - [HarmonyPatch(typeof(Pawn_GeneTracker), "AddGene", new Type[] { typeof(Gene), typeof(bool) })] + [HarmonyPatch(typeof(Pawn_GeneTracker), "AddGene", new Type[] {typeof(Gene), typeof(bool)})] public class AddGene_Patch { public static bool Prefix(ref Gene __result, Gene gene, Pawn ___pawn) { - if (!VariousDefOf.WombGenes.Contains(gene.def)) return true; - bool keepGene; - if (PawnGenerator.IsBeingGenerated(___pawn)) - // During pawn generation, the vagina hediff doesn't exist yet, so use gender to decide instead - // Not the most accurate, but close enough - keepGene = ___pawn.gender == Gender.Female; - else keepGene = ___pawn.GetMenstruationComps().Any(); - if (!keepGene) __result = null; - return keepGene; + if(VariousDefOf.WombGenes.Contains(gene.def) && !___pawn.GetMenstruationComps().Any()) + { + __result = null; + return false; + } + else return true; } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs index 37eda3e..79e7be5 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs @@ -16,7 +16,7 @@ namespace RJW_Menstruation.Patch { if (!__result.NullOrEmpty()) return; if (cummedPawns.Contains(pawn)) - __result = "EggFertOrCumInWomb"; + __result = "Has cum or fertilized egg in a womb"; } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Gizmo_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Gizmo_Patch.cs index 86ef4d9..7185ccf 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Gizmo_Patch.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Gizmo_Patch.cs @@ -1,5 +1,4 @@ using HarmonyLib; -using RimWorld; using rjw; using System.Collections.Generic; using System.Linq; @@ -43,12 +42,12 @@ namespace RJW_Menstruation private static Gizmo CreateGizmo_WombStatus(Pawn pawn, HediffComp_Menstruation comp) { - Texture2D icon, icon_overlay; + Texture2D icon, icon_overay; StringBuilder description = new StringBuilder(); if (Configurations.Debug) { description - .AppendFormat("{0}: {1}\n", comp.curStage, comp.curStageTicks / GenDate.TicksPerHour); + .AppendFormat("{0}: {1}\n", comp.curStage, comp.curStageHrs); if (comp.Pregnancy is Hediff_BasePregnancy rjwpreg) description .AppendFormat("due: {0}\n", rjwpreg.DueDate()); else if (comp.Pregnancy is Hediff_Pregnant biopreg) description @@ -69,15 +68,15 @@ namespace RJW_Menstruation float gestationProgress = comp.StageProgress; if (hediff is Hediff_BasePregnancy || hediff is HediffWithParents) { - if (gestationProgress < 0.2f) icon_overlay = comp.GetCumIcon(); - else icon_overlay = ContentFinder.Get(("Womb/Empty"), true); + if (gestationProgress < 0.2f) icon_overay = comp.GetCumIcon(); + else icon_overay = ContentFinder.Get(("Womb/Empty"), true); } - else icon_overlay = ContentFinder.Get(("Womb/Empty"), true); + else icon_overay = ContentFinder.Get(("Womb/Empty"), true); } else { icon = comp.GetWombIcon(); - icon_overlay = comp.GetCumIcon(); + icon_overay = comp.GetCumIcon(); } } else @@ -91,7 +90,7 @@ namespace RJW_Menstruation { icon = comp.GetWombIcon(); } - icon_overlay = comp.GetCumIcon(); + icon_overay = comp.GetCumIcon(); } foreach (string s in comp.GetCumsInfo) description.AppendFormat("{0}\n", s); @@ -103,7 +102,7 @@ namespace RJW_Menstruation defaultLabel = pawn.LabelShort, defaultDesc = description.ToString(), icon = icon, - icon_overlay = icon_overlay, + icon_overay = icon_overay, shrinkable = Configurations.AllowShrinkIcon, cumcolor = c, comp = comp, diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs index 4c9c591..b1c3853 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs @@ -15,13 +15,13 @@ namespace RJW_Menstruation return milktexturecache; } } - // Ovulation, sex drive - public static Texture2D OvulatoryTexture + // Sex drive + public static Texture2D SexDriveTexture { get { - if (ovulatorytexturecache == null) ovulatorytexturecache = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f); - return ovulatorytexturecache; + if (sexdrivetexturecache == null) sexdrivetexturecache = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f); + return sexdrivetexturecache; } } // Bleeding, vulnerability @@ -93,7 +93,7 @@ namespace RJW_Menstruation public static readonly Texture2D GatherCum_Pussy = ContentFinder.Get("UI/Icon/ToPussy"); private static Texture2D milktexturecache = SolidColorMaterials.NewSolidColorTexture(0.992f, 1.0f, 0.960f, 1.0f); - private static Texture2D ovulatorytexturecache = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f); + private static Texture2D sexdrivetexturecache = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f); private static Texture2D bleedingtexturecache = SolidColorMaterials.NewSolidColorTexture(0.415f, 0.0f, 0.003f, 1.0f); private static Texture2D pregnanttexturecache = SolidColorMaterials.NewSolidColorTexture(0.082f, 0.453f, 0.6f, 1.0f); private static Texture2D recovertexturecache = SolidColorMaterials.NewSolidColorTexture(0.6f, 0.83f, 0.35f, 1.0f); @@ -101,5 +101,10 @@ namespace RJW_Menstruation private static Texture2D animaltexturecache = SolidColorMaterials.NewSolidColorTexture(0.411f, 0.521f, 0.878f, 1.0f); private static Texture2D lutealtexturecache = SolidColorMaterials.NewSolidColorTexture(0.843f, 0.474f, 0.6f, 1.0f); private static Texture2D whoredtexturecache = SolidColorMaterials.NewSolidColorTexture(0.7f, 0.7f, 0.0f, 1.0f); + + + + + } } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs index 5e4dd91..e427e0f 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs @@ -197,8 +197,7 @@ namespace RJW_Menstruation public float absorbedfluids = 0; public bool dirty = false; - public int wearTicks = 0; - protected virtual float PassiveAbsorptionPerHour => 0.1f; + public int wearhours = 0; public virtual bool LeakAfterDirty => def.GetModExtension().leakAfterDirty; public virtual bool EffectAfterDirty => def.GetModExtension().effectsAfterDirty; public virtual ThingDef DirtyDef => def.GetModExtension().dirtyDef; @@ -206,12 +205,12 @@ namespace RJW_Menstruation public Color fluidColor = Color.white; - public virtual void DirtyEffect(int tickInterval) { } + public virtual void DirtyEffect() { } - public virtual void WearEffect(int tickInterval) + public virtual void WearEffect() { - absorbedfluids += PassiveAbsorptionPerHour * tickInterval / GenDate.TicksPerHour; - if (dirty) wearTicks += tickInterval; + absorbedfluids += 0.1f; + if (dirty) wearhours++; } public override Color DrawColorTwo => fluidColor; @@ -219,27 +218,26 @@ namespace RJW_Menstruation public override void ExposeData() { base.ExposeData(); - if(Scribe.mode == LoadSaveMode.LoadingVars) - { - int wearhours = -1; - Scribe_Values.Look(ref wearhours, "wearhours", wearhours, true); - if (wearhours >= 0) wearTicks = wearhours * GenDate.TicksPerHour; - } - Scribe_Values.Look(ref absorbedfluids, "absorbedfluids", 0); - Scribe_Values.Look(ref dirty, "dirty", false); - Scribe_Values.Look(ref wearTicks, "wearTicks", 0); - Scribe_Values.Look(ref fluidColor, "fluidColor", Color.white); + Scribe_Values.Look(ref absorbedfluids, "absorbedfluids", absorbedfluids, true); + Scribe_Values.Look(ref dirty, "dirty", dirty, true); + Scribe_Values.Look(ref wearhours, "wearhours", wearhours, true); + Scribe_Values.Look(ref fluidColor, "fluidColor", fluidColor, true); } } public class Absorber_Tampon : Absorber { - protected override float PassiveAbsorptionPerHour => 0.5f; - public override void DirtyEffect(int tickInterval) - { - if (wearTicks > MinHrstoDirtyEffect * GenDate.TicksPerHour && Rand.MTBEventOccurs(100.0f, GenDate.TicksPerHour, tickInterval) && !Wearer.apparel.IsLocked(this)) + public override void WearEffect() + { + if (dirty) wearhours++; + absorbedfluids += 0.5f; + } + + public override void DirtyEffect() + { + if (wearhours > MinHrstoDirtyEffect && Rand.Chance(0.01f) && !Wearer.apparel.IsLocked(this)) { Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer)); } @@ -256,7 +254,7 @@ namespace RJW_Menstruation public override void ExposeData() { base.ExposeData(); - Scribe_Values.Look(ref color, "color", Color.white); + Scribe_Values.Look(ref color, "color", color, true); } public override Color DrawColor diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs index dd2982f..1a67ebf 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs @@ -60,12 +60,6 @@ namespace RJW_Menstruation public static readonly string Option6_Desc = "Option6_Desc".Translate(); public static readonly string Option7_Label = "Option7_Label".Translate(); public static readonly string Option7_Desc = "Option7_Desc".Translate(); - public static readonly string Option_ColonistUpdateInterval_Label = "Option_ColonistUpdateInterval_Label".Translate(); - public static readonly string Option_ColonistUpdateInterval_Desc = "Option_ColonistUpdateInterval_Desc".Translate(); - public static readonly string Option_NonColonistUpdateInterval_Label = "Option_NonColonistUpdateInterval_Label".Translate(); - public static readonly string Option_NonColonistUpdateInterval_Desc = "Option_NonColonistUpdateInterval_Desc".Translate(); - public static readonly string Option_AnimalUpdateInterval_Label = "Option_AnimalUpdateInterval_Label".Translate(); - public static readonly string Option_AnimalUpdateInterval_Desc = "Option_AnimalUpdateInterval_Desc".Translate(); public static readonly string Option8_Label = "Option8_Label".Translate(); public static readonly string Option8_Desc = "Option8_Desc".Translate(); public static readonly string Option9_Label = "Option9_Label".Translate(); diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs index 0448aac..9b726b2 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs @@ -433,7 +433,7 @@ 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.OvulatoryTexture, Texture2D.blackTexture, xxx.sex_drive_stat.description); + FillableBarLabeled(lineRect, " " + xxx.sex_drive_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue / 2, TextureCache.SexDriveTexture, Texture2D.blackTexture, xxx.sex_drive_stat.description); lineRect.y += height; statvalue = pawn.GetStatValue(xxx.vulnerability_stat); @@ -462,8 +462,8 @@ namespace RJW_Menstruation statvalue = Configurations.ImplantationChance * comp.ImplantChance; float fertchance = comp.GetFertilityChance(); FillableBarLabeled(lineRect, " " + xxx.reproduction.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue, TextureCache.LutealTexture, Texture2D.blackTexture, Translations.FertilityDesc(string.Format("{0:0.##}", fertchance * 100))); - Rect overlayRect = new Rect(lineRect.x, lineRect.y, lineRect.width * Math.Min(1.0f, fertchance), lineRect.height); - GUI.DrawTexture(overlayRect, TextureCache.FertChanceTex); + Rect overayRect = new Rect(lineRect.x, lineRect.y, lineRect.width * Math.Min(1.0f, fertchance), lineRect.height); + GUI.DrawTexture(overayRect, TextureCache.FertChanceTex); lineRect.y += height; } diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs index aaaa96f..c303d4e 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs @@ -5,7 +5,7 @@ namespace RJW_Menstruation { public class Gizmo_Womb : Command_Action { - public Texture2D icon_overlay; + public Texture2D icon_overay; public Color cumcolor; public HediffComp_Menstruation comp; @@ -14,23 +14,23 @@ namespace RJW_Menstruation public override void DrawIcon(Rect rect, Material buttonMat, GizmoRenderParms parms) { Texture badTex = icon; - Texture2D overlay = icon_overlay; + Texture2D overay = icon_overay; Color color = cumcolor; if (badTex == null) { badTex = BaseContent.BadTex; } - if (overlay == null) + if (overay == null) { - overlay = BaseContent.BadTex; + overay = BaseContent.BadTex; } if (color == null) color = Color.white; rect.position += new Vector2(iconOffset.x * rect.size.x, iconOffset.y * rect.size.y); GUI.color = IconDrawColor; Widgets.DrawTextureFitted(rect, badTex, this.iconDrawScale * 0.85f, this.iconProportions, this.iconTexCoords, this.iconAngle, buttonMat); GUI.color = color; - Widgets.DrawTextureFitted(rect, overlay, iconDrawScale * 0.85f, iconProportions, iconTexCoords, iconAngle, buttonMat); + Widgets.DrawTextureFitted(rect, overay, iconDrawScale * 0.85f, iconProportions, iconTexCoords, iconAngle, buttonMat); GUI.color = Color.white; if (Configurations.DrawEggOverlay) comp.DrawEggOverlay(rect, false); Rect progressRect = new Rect(rect.x + 2f, rect.y, rect.width - 4f, progressbarHeight); diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs index db91411..13aae6e 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs @@ -53,7 +53,7 @@ namespace RJW_Menstruation 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.RaceProps?.AnyPawnKind ?? + pawn.def.race?.AnyPawnKind ?? pawn.kindDef; } @@ -433,7 +433,7 @@ namespace RJW_Menstruation } - public static float LerpMultiple(this float a, float b, float t, float num) + public static float LerpMultiple(this float a, float b, float t, int num) { float tmult = Mathf.Pow(1 - t, num); return tmult * a + (1 - tmult) * b; diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs index 6c5e143..7f368cc 100644 --- a/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs @@ -167,10 +167,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"); - - // Defs from Sexperience Ideology - public static readonly PreceptDef Pregnancy_Elevated = DefDatabase.GetNamedSilentFail("Pregnancy_Elevated"); - public static readonly PreceptDef Pregnancy_Holy = DefDatabase.GetNamedSilentFail("Pregnancy_Holy"); - public static readonly PreceptDef Pregnancy_Required = DefDatabase.GetNamedSilentFail("Pregnancy_Required"); } } diff --git a/About/Manifest.xml b/About/Manifest.xml index 3299391..fc6edef 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ RJW Menstruation - 1.0.9.0 + 1.0.8.9 diff --git a/changelogs.txt b/changelogs.txt index 97ae1c8..f68bbbe 100644 --- a/changelogs.txt +++ b/changelogs.txt @@ -1,11 +1,3 @@ -Version 1.0.9.0 - - Fix errors when opening the womb dialog of some low fertility pawns. - - Updated Traditional Chinese translation by Hydrogen. - - New options to update wombs more or less often, defaulting to every hour. - - When using the sexperience-ideology mod, pawns with pro-pregnancy precepts will have thoughts more agreeable with potential pregnancies. - - More generous egg allocation for newly spawned periodic ovulators. - - Menstruation-related genes will now stay on females during initial pawn setup. - Version 1.0.8.9 - Fix bug that sent pawns into menopause very early. Please use the recalculate ovary power dev action to restore lost eggs.