mirror of
				https://gitgud.io/lutepickle/rjw_menstruation.git
				synced 2024-08-14 22:46:52 +00:00 
			
		
		
		
	Initial implementation of new variance code
This commit is contained in:
		
							parent
							
								
									9c9e120b92
								
							
						
					
					
						commit
						9cc8897103
					
				
					 3 changed files with 95 additions and 88 deletions
				
			
		| 
						 | 
				
			
			@ -43,16 +43,15 @@ namespace RJW_Menstruation
 | 
			
		|||
                GoNextStage(Stage.Anestrus);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (curStageHrs >= FollicularIntervalHours)
 | 
			
		||||
            if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                estrusflag = false;
 | 
			
		||||
                lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor);
 | 
			
		||||
                GoNextStage(Stage.Luteal);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24)
 | 
			
		||||
                if (!estrusflag && curStageHrs > currentIntervalhours - Props.estrusDaysBeforeOvulation * 24)
 | 
			
		||||
                {
 | 
			
		||||
                    estrusflag = true;
 | 
			
		||||
                    SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation);
 | 
			
		||||
| 
						 | 
				
			
			@ -68,22 +67,20 @@ namespace RJW_Menstruation
 | 
			
		|||
                RemoveClimactericEffect();
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
            }
 | 
			
		||||
            else if (curStageHrs >= (follicularIntervalhours - bleedingIntervalhours) * CycleFactor)
 | 
			
		||||
            else if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                estrusflag = false;
 | 
			
		||||
                lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor);
 | 
			
		||||
                GoNextStage(Stage.ClimactericLuteal);
 | 
			
		||||
            }
 | 
			
		||||
            else if (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.2f)  // Might randomly skip to luteal early)
 | 
			
		||||
            {
 | 
			
		||||
                estrusflag = false;
 | 
			
		||||
                lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6);
 | 
			
		||||
                GoNextStage(Stage.ClimactericLuteal);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24)
 | 
			
		||||
                if (!estrusflag && curStageHrs > currentIntervalhours - Props.estrusDaysBeforeOvulation * 24)
 | 
			
		||||
                {
 | 
			
		||||
                    estrusflag = true;
 | 
			
		||||
                    SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,9 +65,10 @@ namespace RJW_Menstruation
 | 
			
		|||
        const float minmakefilthvalue = 1.0f;
 | 
			
		||||
        //const int ovarypowerthreshold = 72;
 | 
			
		||||
 | 
			
		||||
        public const int tickInterval = GenDate.TicksPerHour;
 | 
			
		||||
        public const int maxImplantDelayDays = 30;
 | 
			
		||||
        public const int minImplantAgeHours = 72;
 | 
			
		||||
        const int tickInterval = GenDate.TicksPerHour;
 | 
			
		||||
        const int maxImplantDelayDays = 30;
 | 
			
		||||
        const int minImplantAgeHours = 72;
 | 
			
		||||
 | 
			
		||||
        public CompProperties_Menstruation Props;
 | 
			
		||||
        public Stage curStage = Stage.Follicular;
 | 
			
		||||
        public int curStageHrs = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -108,10 +109,8 @@ namespace RJW_Menstruation
 | 
			
		|||
 | 
			
		||||
        protected List<Cum> cums;
 | 
			
		||||
        protected List<Egg> eggs;
 | 
			
		||||
        protected int follicularIntervalhours = -1;
 | 
			
		||||
        protected int lutealIntervalhours = -1;
 | 
			
		||||
        protected int bleedingIntervalhours = -1;
 | 
			
		||||
        protected int recoveryIntervalhours = -1;
 | 
			
		||||
        protected float cycleSpeed = -1;
 | 
			
		||||
        protected float cycleVariability = -1;
 | 
			
		||||
        protected int currentIntervalhours = -1;
 | 
			
		||||
        protected float crampPain = -1;
 | 
			
		||||
        protected Need sexNeed = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -132,14 +131,6 @@ namespace RJW_Menstruation
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int FollicularIntervalHours
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return (int)((follicularIntervalhours - bleedingIntervalhours) * CycleFactor);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public float TotalCum
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
| 
						 | 
				
			
			@ -442,7 +433,7 @@ namespace RJW_Menstruation
 | 
			
		|||
                {
 | 
			
		||||
                    case Stage.Follicular:
 | 
			
		||||
                    case Stage.ClimactericFollicular:
 | 
			
		||||
                        return curStageHrs > 0.7f * (follicularIntervalhours - bleedingIntervalhours);
 | 
			
		||||
                        return curStageHrs > 0.7f * currentIntervalhours;
 | 
			
		||||
                    case Stage.Ovulatory:
 | 
			
		||||
                        return true;
 | 
			
		||||
                    case Stage.Luteal:
 | 
			
		||||
| 
						 | 
				
			
			@ -509,24 +500,7 @@ namespace RJW_Menstruation
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                switch (curStage)
 | 
			
		||||
                {
 | 
			
		||||
                    case Stage.Follicular:
 | 
			
		||||
                    case Stage.ClimactericFollicular:
 | 
			
		||||
                        return FollicularIntervalHours;
 | 
			
		||||
                    case Stage.Luteal:
 | 
			
		||||
                    case Stage.ClimactericLuteal:
 | 
			
		||||
                        return lutealIntervalhours;
 | 
			
		||||
                    case Stage.Bleeding:
 | 
			
		||||
                    case Stage.ClimactericBleeding:
 | 
			
		||||
                        return bleedingIntervalhours;
 | 
			
		||||
                    case Stage.Recover:
 | 
			
		||||
                        return recoveryIntervalhours;
 | 
			
		||||
                    case Stage.Pregnant:
 | 
			
		||||
                        return currentIntervalhours;
 | 
			
		||||
                    default:
 | 
			
		||||
                        return float.PositiveInfinity;
 | 
			
		||||
                }
 | 
			
		||||
                return currentIntervalhours;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -554,10 +528,10 @@ namespace RJW_Menstruation
 | 
			
		|||
            Scribe_Collections.Look(ref eggs, saveDestroyedThings: true, label: "eggs", lookMode: LookMode.Deep, ctorArgs: new object[0]);
 | 
			
		||||
            Scribe_Values.Look(ref curStage, "curStage", curStage, true);
 | 
			
		||||
            Scribe_Values.Look(ref curStageHrs, "curStageHrs", curStageHrs, true);
 | 
			
		||||
            Scribe_Values.Look(ref follicularIntervalhours, "follicularIntervalhours", follicularIntervalhours, true);
 | 
			
		||||
            Scribe_Values.Look(ref lutealIntervalhours, "lutealIntervalhours", lutealIntervalhours, true);
 | 
			
		||||
            Scribe_Values.Look(ref bleedingIntervalhours, "bleedingIntervalhours", bleedingIntervalhours, true);
 | 
			
		||||
            Scribe_Values.Look(ref recoveryIntervalhours, "recoveryIntervalhours", recoveryIntervalhours, true);
 | 
			
		||||
            //Scribe_Values.Look(ref follicularIntervalhours, "follicularIntervalhours", follicularIntervalhours, true);
 | 
			
		||||
            //Scribe_Values.Look(ref lutealIntervalhours, "lutealIntervalhours", lutealIntervalhours, true);
 | 
			
		||||
            //Scribe_Values.Look(ref bleedingIntervalhours, "bleedingIntervalhours", bleedingIntervalhours, true);
 | 
			
		||||
            //Scribe_Values.Look(ref recoveryIntervalhours, "recoveryIntervalhours", recoveryIntervalhours, true);
 | 
			
		||||
            Scribe_Values.Look(ref currentIntervalhours, "currentIntervalhours", currentIntervalhours, true);
 | 
			
		||||
            Scribe_Values.Look(ref crampPain, "crampPain", crampPain, true);
 | 
			
		||||
            Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true);
 | 
			
		||||
| 
						 | 
				
			
			@ -925,17 +899,16 @@ namespace RJW_Menstruation
 | 
			
		|||
 | 
			
		||||
            if (!Props.infertile)
 | 
			
		||||
            {
 | 
			
		||||
                if (follicularIntervalhours < 0)
 | 
			
		||||
                if (cycleSpeed < 1) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f);
 | 
			
		||||
                if (cycleVariability < 1) cycleVariability = Utility.RandomVariabilityPercent();
 | 
			
		||||
                if (currentIntervalhours < 0)
 | 
			
		||||
                {
 | 
			
		||||
                    follicularIntervalhours = PeriodRandomizer(Props.follicularIntervalDays * 24, Props.deviationFactor);
 | 
			
		||||
                    //follicularIntervalhours = PeriodRandomizer(Props.follicularIntervalDays * 24, Props.deviationFactor);
 | 
			
		||||
                    if (parent.pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) curStage = Stage.Young;
 | 
			
		||||
                    else if (!IsBreedingSeason()) curStage = Stage.Anestrus;
 | 
			
		||||
                    else curStage = RandomStage();
 | 
			
		||||
                    currentIntervalhours = PeriodRandomizer(curStage);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (lutealIntervalhours < 0) lutealIntervalhours = PeriodRandomizer(Props.lutealIntervalDays * 24, Props.deviationFactor);
 | 
			
		||||
                if (bleedingIntervalhours < 0) bleedingIntervalhours = PeriodRandomizer(Props.bleedingIntervalDays * 24, Props.deviationFactor);
 | 
			
		||||
                if (recoveryIntervalhours < 0) recoveryIntervalhours = PeriodRandomizer(Props.recoveryIntervalDays * 24, Props.deviationFactor);
 | 
			
		||||
                if (crampPain < 0) crampPain = PainRandomizer();
 | 
			
		||||
                if (cums == null) cums = new List<Cum>();
 | 
			
		||||
                if (eggs == null) eggs = new List<Egg>();
 | 
			
		||||
| 
						 | 
				
			
			@ -1323,7 +1296,7 @@ namespace RJW_Menstruation
 | 
			
		|||
            Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_MenstrualCramp, parent.pawn);
 | 
			
		||||
            hediff.Severity = crampPain * Rand.Range(0.9f, 1.1f);
 | 
			
		||||
            HediffCompProperties_SeverityPerDay Prop = (HediffCompProperties_SeverityPerDay)hediff.TryGetComp<HediffComp_SeverityPerDay>().props;
 | 
			
		||||
            Prop.severityPerDay = -hediff.Severity / (bleedingIntervalhours / 24) * Configurations.CycleAcceleration;
 | 
			
		||||
            Prop.severityPerDay = -hediff.Severity / (currentIntervalhours / 24) * Configurations.CycleAcceleration;
 | 
			
		||||
            parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1334,14 +1307,14 @@ namespace RJW_Menstruation
 | 
			
		|||
                GoNextStage(Stage.Anestrus);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (curStageHrs >= FollicularIntervalHours)
 | 
			
		||||
            if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                GoNextStage(Stage.Ovulatory);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                if (!estrusflag && curStageHrs > FollicularIntervalHours - Props.estrusDaysBeforeOvulation * 24)
 | 
			
		||||
                if (!estrusflag && curStageHrs > currentIntervalhours - Props.estrusDaysBeforeOvulation * 24)
 | 
			
		||||
                {
 | 
			
		||||
                    estrusflag = true;
 | 
			
		||||
                    SetEstrus(Props.eggLifespanDays + Props.estrusDaysBeforeOvulation);
 | 
			
		||||
| 
						 | 
				
			
			@ -1392,12 +1365,10 @@ namespace RJW_Menstruation
 | 
			
		|||
                Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_Climacteric, parent.pawn);
 | 
			
		||||
                hediff.Severity = 0.008f * i;
 | 
			
		||||
                parent.pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(parent.pawn));
 | 
			
		||||
                lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6);
 | 
			
		||||
                GoNextStage(Stage.ClimactericLuteal);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor);
 | 
			
		||||
                GoNextStage(Stage.Luteal);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1422,7 +1393,7 @@ namespace RJW_Menstruation
 | 
			
		|||
                    StayCurrentStage();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (curStageHrs <= lutealIntervalhours)
 | 
			
		||||
            else if (curStageHrs <= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
| 
						 | 
				
			
			@ -1432,12 +1403,10 @@ namespace RJW_Menstruation
 | 
			
		|||
                eggs.Clear();
 | 
			
		||||
                if (Props.bleedingIntervalDays == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
 | 
			
		||||
                    GoNextStage(Stage.Follicular);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor);
 | 
			
		||||
                    if (crampPain >= 0.05f)
 | 
			
		||||
                    {
 | 
			
		||||
                        AddCrampPain();
 | 
			
		||||
| 
						 | 
				
			
			@ -1449,16 +1418,22 @@ namespace RJW_Menstruation
 | 
			
		|||
 | 
			
		||||
        protected virtual void BleedingAction()
 | 
			
		||||
        {
 | 
			
		||||
            if (curStageHrs >= bleedingIntervalhours)
 | 
			
		||||
            if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
 | 
			
		||||
                Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp);
 | 
			
		||||
                if (hediff != null) parent.pawn.health.RemoveHediff(hediff);
 | 
			
		||||
                GoNextStage(Stage.Follicular);
 | 
			
		||||
                int totalFollicularHours = PeriodRandomizer(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
 | 
			
		||||
                    GoNextStage(Stage.Ovulatory);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    currentIntervalhours = totalFollicularHours - currentIntervalhours;
 | 
			
		||||
                    GoNextStage(Stage.Follicular, false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (curStageHrs < bleedingIntervalhours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
 | 
			
		||||
                if (curStageHrs < currentIntervalhours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1490,7 +1465,7 @@ namespace RJW_Menstruation
 | 
			
		|||
 | 
			
		||||
        protected virtual void RecoverAction()
 | 
			
		||||
        {
 | 
			
		||||
            if (curStageHrs >= recoveryIntervalhours)
 | 
			
		||||
            if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                if (Configurations.EnableMenopause && ovarypower < OvaryPowerThreshold)
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -1502,7 +1477,6 @@ namespace RJW_Menstruation
 | 
			
		|||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
 | 
			
		||||
                    GoNextStage(Stage.Follicular);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1523,7 +1497,11 @@ namespace RJW_Menstruation
 | 
			
		|||
            {
 | 
			
		||||
                StayCurrentStageConst(Stage.Young);
 | 
			
		||||
            }
 | 
			
		||||
            else GoNextStage(IsBreedingSeason() ? Stage.Follicular : Stage.Anestrus);
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                bool breedingSeason = IsBreedingSeason();
 | 
			
		||||
                GoNextStage(breedingSeason ? Stage.Follicular : Stage.Anestrus, breedingSeason);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual void ClimactericFollicularAction()
 | 
			
		||||
| 
						 | 
				
			
			@ -1533,13 +1511,12 @@ namespace RJW_Menstruation
 | 
			
		|||
                RemoveClimactericEffect();
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
            }
 | 
			
		||||
            else if (curStageHrs >= (follicularIntervalhours - bleedingIntervalhours) * CycleFactor)
 | 
			
		||||
            else if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                GoNextStage(Stage.Ovulatory);
 | 
			
		||||
            }
 | 
			
		||||
            else if (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.2f) //skips ovulatory
 | 
			
		||||
            {
 | 
			
		||||
                lutealIntervalhours = PeriodRandomizer(lutealIntervalhours, Props.deviationFactor * 6);
 | 
			
		||||
                GoNextStage(Stage.ClimactericLuteal);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
| 
						 | 
				
			
			@ -1567,7 +1544,7 @@ namespace RJW_Menstruation
 | 
			
		|||
                    StayCurrentStage();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (curStageHrs <= lutealIntervalhours)
 | 
			
		||||
            else if (curStageHrs <= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
| 
						 | 
				
			
			@ -1577,17 +1554,14 @@ namespace RJW_Menstruation
 | 
			
		|||
                eggs.Clear();
 | 
			
		||||
                if (Props.bleedingIntervalDays == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor * 6);
 | 
			
		||||
                    GoNextStage(Stage.ClimactericFollicular);
 | 
			
		||||
                }
 | 
			
		||||
                else if (ovarypower < OvaryPowerThreshold / 4 || (ovarypower < OvaryPowerThreshold / 3 && Rand.Range(0.0f, 1.0f) < 0.3f)) //skips bleeding
 | 
			
		||||
                {
 | 
			
		||||
                    follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor * 6);
 | 
			
		||||
                    GoNextStage(Stage.ClimactericFollicular);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor);
 | 
			
		||||
                    if (crampPain >= 0.05f)
 | 
			
		||||
                    {
 | 
			
		||||
                        AddCrampPain();
 | 
			
		||||
| 
						 | 
				
			
			@ -1604,14 +1578,22 @@ namespace RJW_Menstruation
 | 
			
		|||
                RemoveClimactericEffect();
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
            }
 | 
			
		||||
            else if (curStageHrs >= bleedingIntervalhours)
 | 
			
		||||
            else if (curStageHrs >= currentIntervalhours)
 | 
			
		||||
            {
 | 
			
		||||
                follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor * 6);
 | 
			
		||||
                GoNextStage(Stage.ClimactericFollicular);
 | 
			
		||||
                Hediff hediff = parent.pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp);
 | 
			
		||||
                if (hediff != null) parent.pawn.health.RemoveHediff(hediff);
 | 
			
		||||
                int totalFollicularHours = PeriodRandomizer(Stage.Follicular);
 | 
			
		||||
                if (totalFollicularHours <= currentIntervalhours)
 | 
			
		||||
                    GoNextStage(Stage.Ovulatory);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    currentIntervalhours = totalFollicularHours - currentIntervalhours;
 | 
			
		||||
                    GoNextStage(Stage.Follicular, false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (curStageHrs < bleedingIntervalhours / 6) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
 | 
			
		||||
                if (curStageHrs < currentIntervalhours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut();
 | 
			
		||||
                curStageHrs += Configurations.CycleAcceleration;
 | 
			
		||||
                StayCurrentStage();
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1733,7 +1715,7 @@ namespace RJW_Menstruation
 | 
			
		|||
                default:
 | 
			
		||||
                    curStage = Stage.Follicular;
 | 
			
		||||
                    curStageHrs = 0;
 | 
			
		||||
                    if (follicularIntervalhours < 0) follicularIntervalhours = PeriodRandomizer(Props.follicularIntervalDays * 24, Props.deviationFactor);
 | 
			
		||||
                    if (currentIntervalhours < 0) currentIntervalhours = PeriodRandomizer(curStage);
 | 
			
		||||
                    HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(Stage.Follicular), GetNextUpdate(), parent.pawn, false);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1763,17 +1745,11 @@ namespace RJW_Menstruation
 | 
			
		|||
            return ((nextOffset - currentOffset + tickInterval - 1) % tickInterval) + 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void GoNextStage(Stage nextstage)
 | 
			
		||||
        protected void GoNextStage(Stage nextstage, bool calculateHours = true)
 | 
			
		||||
        {
 | 
			
		||||
            curStageHrs = 0;
 | 
			
		||||
            curStage = nextstage;
 | 
			
		||||
            HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), GetNextUpdate(), parent.pawn, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        protected void GoNextStageSetHour(Stage nextstage, int hour)
 | 
			
		||||
        {
 | 
			
		||||
            curStageHrs = hour;
 | 
			
		||||
            float variabilityFactor = nextstage == Stage.ClimactericFollicular || nextstage == Stage.ClimactericLuteal || nextstage == Stage.ClimactericBleeding ? 6f : 1f;
 | 
			
		||||
            if (calculateHours) currentIntervalhours = PeriodRandomizer(nextstage, variabilityFactor);
 | 
			
		||||
            curStage = nextstage;
 | 
			
		||||
            HugsLibController.Instance.TickDelayScheduler.ScheduleCallback(PeriodSimulator(nextstage), GetNextUpdate(), parent.pawn, false);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1794,12 +1770,10 @@ namespace RJW_Menstruation
 | 
			
		|||
        {
 | 
			
		||||
            if (Props.bleedingIntervalDays == 0)
 | 
			
		||||
            {
 | 
			
		||||
                follicularIntervalhours = PeriodRandomizer(follicularIntervalhours, Props.deviationFactor);
 | 
			
		||||
                GoNextStage(Stage.Follicular);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                bleedingIntervalhours = PeriodRandomizer(bleedingIntervalhours, Props.deviationFactor);
 | 
			
		||||
                GoNextStage(Stage.Bleeding);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1820,6 +1794,27 @@ namespace RJW_Menstruation
 | 
			
		|||
            return intervalhours + (int)(intervalhours * Rand.Range(-deviation, deviation));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected int PeriodRandomizer(Stage stage, float variabilityFactor = 1f)
 | 
			
		||||
        {
 | 
			
		||||
            // Most cycle lengthening or shortening occurs in the follicular phase, so weight towards that
 | 
			
		||||
            switch (stage)
 | 
			
		||||
            {
 | 
			
		||||
                case Stage.Follicular:
 | 
			
		||||
                case Stage.ClimactericFollicular:
 | 
			
		||||
                    return (int)(Props.follicularIntervalDays * 24 * (cycleSpeed * 1.5f) * (1 + Rand.Range(-cycleVariability, cycleVariability) * 1.5f * variabilityFactor));
 | 
			
		||||
                case Stage.Luteal:
 | 
			
		||||
                case Stage.ClimactericLuteal:
 | 
			
		||||
                    return (int)(Props.lutealIntervalDays * 24 * (cycleSpeed * 0.5f) * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor));
 | 
			
		||||
                case Stage.Bleeding:
 | 
			
		||||
                case Stage.ClimactericBleeding:
 | 
			
		||||
                    return (int)(Props.bleedingIntervalDays * 24 * (cycleSpeed * 0.5f) * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor));
 | 
			
		||||
                case Stage.Recover:
 | 
			
		||||
                    return (int)(Props.recoveryIntervalDays * 24 * Rand.Range(-0.05f, 0.05f));
 | 
			
		||||
                default:    // Can happen on init, shouldn't happen during a cycle
 | 
			
		||||
                    return 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected float InterspeciesImplantFactor(Pawn fertilizer)
 | 
			
		||||
        {
 | 
			
		||||
            if (fertilizer.def.defName == parent.pawn.def.defName) return 1.0f;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -439,6 +439,21 @@ namespace RJW_Menstruation
 | 
			
		|||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static float RandomVariabilityPercent(int recursion = 0)
 | 
			
		||||
        {
 | 
			
		||||
            // Humans, in days
 | 
			
		||||
            const float mean = 1.635f;
 | 
			
		||||
            const float stddev = 0.9138f;
 | 
			
		||||
            const float lambda = 0.234f;
 | 
			
		||||
            if (recursion >= 10) return mean;
 | 
			
		||||
 | 
			
		||||
            float variability = Rand.Gaussian(mean, stddev) - Mathf.Log(Rand.Value) / lambda;
 | 
			
		||||
            variability /= 28 * 2;  // Convert to percentage
 | 
			
		||||
 | 
			
		||||
            if (variability < 0 || variability > 0.35f) return RandomVariabilityPercent(recursion + 1); // ~2% chance, about the limit on how far variability can go before things start to break
 | 
			
		||||
            else return variability;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static float LerpMultiple(this float a, float b, float t, int num)
 | 
			
		||||
        {
 | 
			
		||||
            float tmult = Mathf.Pow(1 - t, num);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue