Basic framework of biotech pregnancy handling

This commit is contained in:
lutepickle 2022-10-27 13:57:25 -07:00
parent 141c84580c
commit 31c3026ca0
7 changed files with 101 additions and 29 deletions

View File

@ -121,7 +121,8 @@ namespace RJW_Menstruation
protected int opcache = -1; protected int opcache = -1;
protected float antisperm = 0.0f; protected float antisperm = 0.0f;
protected float? originvagsize = null; protected float? originvagsize = null;
protected Hediff_BasePregnancy pregnancy = null; // RJW pregnancy, or Biotech pregnancy/labor/laborpushing
protected Hediff pregnancy = null;
private static readonly SimpleCurve SexFrequencyCurve = new SimpleCurve() private static readonly SimpleCurve SexFrequencyCurve = new SimpleCurve()
{ {
@ -147,7 +148,7 @@ namespace RJW_Menstruation
new CurvePoint(1.0f,0.5f) new CurvePoint(1.0f,0.5f)
}; };
public Hediff_BasePregnancy Pregnancy { public Hediff Pregnancy {
get get
{ {
if (pregnancy == null) return null; if (pregnancy == null) return null;
@ -538,7 +539,22 @@ namespace RJW_Menstruation
get get
{ {
if (pregnancy == null) return Mathf.Clamp01(curStageHrs / CurStageIntervalHours); if (pregnancy == null) return Mathf.Clamp01(curStageHrs / CurStageIntervalHours);
if (pregnancy.is_discovered || Configurations.infoDetail == Configurations.DetailLevel.All) return pregnancy.Severity; bool is_discovered = false;
switch (pregnancy)
{
case Hediff_BasePregnancy rjw_preg:
is_discovered = rjw_preg.is_discovered;
break;
case Hediff_Pregnant vanilla_preg:
is_discovered = vanilla_preg.Visible;
break;
case Hediff_Labor _:
case Hediff_LaborPushing _:
is_discovered = true;
break;
}
if (is_discovered || Configurations.infoDetail == Configurations.DetailLevel.All) return pregnancy.Severity;
// Luteal will appear to progress, hitting the end of the phase when the pregnancy is discovered // Luteal will appear to progress, hitting the end of the phase when the pregnancy is discovered
float discoveryTime = 0.5f; float discoveryTime = 0.5f;
@ -673,8 +689,19 @@ namespace RJW_Menstruation
Log.Warning($"Attempted to remove menstruation comp from wrong pawn ({Pawn})."); Log.Warning($"Attempted to remove menstruation comp from wrong pawn ({Pawn}).");
return; return;
} }
if (pregnancy != null && !(pregnancy is Hediff_MechanoidPregnancy)) switch (pregnancy)
pregnancy.Miscarry(); {
case null:
case Hediff_MechanoidPregnancy _:
break;
case Hediff_BasePregnancy rjw_preg:
rjw_preg.Miscarry();
break;
case Hediff_Pregnant vanilla_preg:
Pawn.health.RemoveHediff(vanilla_preg);
break;
}
base.CompPostPostRemoved(); base.CompPostPostRemoved();
} }
@ -1197,6 +1224,13 @@ namespace RJW_Menstruation
deadeggs.Add(egg); deadeggs.Add(egg);
continue; continue;
} }
else if (Pawn.IsBiotechPregnant())
{
// TODO: Initiate Biotech pregnancy
if (Configurations.Debug) Log.Message($"Could not implant {Pawn}'s egg due to existing Biotech pregnancy");
deadeggs.Add(egg);
continue;
}
else if (Pawn.health.hediffSet.GetFirstHediff<Hediff_InsectEgg>() != null || pregnancy is Hediff_MechanoidPregnancy) else if (Pawn.health.hediffSet.GetFirstHediff<Hediff_InsectEgg>() != null || pregnancy is Hediff_MechanoidPregnancy)
{ {
if (Configurations.Debug) Log.Message($"Could not implant {Pawn}'s egg due to insect or mechanoid pregnancy"); if (Configurations.Debug) Log.Message($"Could not implant {Pawn}'s egg due to insect or mechanoid pregnancy");
@ -1239,13 +1273,17 @@ namespace RJW_Menstruation
} }
else else
{ {
if (Configurations.Debug) Log.Message($"Creating new pregnancy"); if (Configurations.Debug) Log.Message($"Creating new menstruation pregnancy");
pregnancy = Hediff_BasePregnancy.Create<Hediff_MultiplePregnancy>(Pawn, egg.fertilizer); pregnancy = Hediff_BasePregnancy.Create<Hediff_MultiplePregnancy>(Pawn, egg.fertilizer);
pregnant = true; pregnant = true;
deadeggs.Add(egg); deadeggs.Add(egg);
} }
pregnancy.p_start_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour; if (pregnancy is Hediff_BasePregnancy rjw_preg)
pregnancy.p_end_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour; {
rjw_preg.p_start_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour;
rjw_preg.p_end_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour;
}
// TODO: advance biotech pregnancy
} }
} }
@ -1722,13 +1760,16 @@ namespace RJW_Menstruation
return stage; return stage;
} }
// Searches for an RJW pregnancy unclaimed by any womb and put it in this one // Searches for a pregnancy unclaimed by any womb and put it in this one
public void TakeLoosePregnancy() public void TakeLoosePregnancy()
{ {
if (pregnancy != null) return; if (pregnancy != null) return;
List<Hediff_BasePregnancy> pregnancies = new List<Hediff_BasePregnancy>(); IEnumerable<Hediff> pregnancies = Pawn.health.hediffSet.hediffs.Where(hediff =>
Pawn.health.hediffSet.GetHediffs(ref pregnancies); hediff is Hediff_BasePregnancy ||
hediff is Hediff_Pregnant ||
hediff is Hediff_Labor ||
hediff is Hediff_LaborPushing);
pregnancy = pregnancy =
pregnancies.Except( pregnancies.Except(

View File

@ -44,7 +44,7 @@ namespace RJW_Menstruation
return comps.Where(c => c.IsDangerDay).RandomElementWithFallback() ?? comps.RandomElementWithFallback(); return comps.Where(c => c.IsDangerDay).RandomElementWithFallback() ?? comps.RandomElementWithFallback();
} }
public static HediffComp_Menstruation GetMenstruationComp(this Hediff vagina) public static HediffComp_Menstruation GetMenstruationCompFromVagina(this Hediff vagina)
{ {
if (VariousDefOf.AllVaginas.Contains(vagina?.def)) if (VariousDefOf.AllVaginas.Contains(vagina?.def))
{ {
@ -53,7 +53,7 @@ namespace RJW_Menstruation
return null; return null;
} }
public static HediffComp_Menstruation GetMenstruationComp(this Hediff_BasePregnancy pregnancy) public static HediffComp_Menstruation GetMenstruationCompFromPregnancy(this Hediff pregnancy)
{ {
return pregnancy?.pawn.GetMenstruationComps().FirstOrDefault(comp => comp.Pregnancy == pregnancy); return pregnancy?.pawn.GetMenstruationComps().FirstOrDefault(comp => comp.Pregnancy == pregnancy);
} }
@ -112,6 +112,7 @@ namespace RJW_Menstruation
else if (h.GestationProgress < 0.8f) icon += fetustex + "04"; else if (h.GestationProgress < 0.8f) icon += fetustex + "04";
else icon += fetustex + "05"; else icon += fetustex + "05";
} }
// TODO: Biotech
else icon = "Fetus/Slime_Abomi02"; else icon = "Fetus/Slime_Abomi02";
Texture2D result = TryGetTwinsIcon(icon, babycount); Texture2D result = TryGetTwinsIcon(icon, babycount);
@ -299,14 +300,17 @@ namespace RJW_Menstruation
return ContentFinder<Texture2D>.Get((icon), true); return ContentFinder<Texture2D>.Get((icon), true);
} }
public static float GestationHours(this Hediff_BasePregnancy hediff) public static float GestationHours(this Hediff hediff)
{ {
if (hediff == null) if (hediff == null)
{ {
Log.Error("Tried to get gestation length without a pregnancy."); Log.Error("Tried to get gestation length without a pregnancy.");
return 1f; return 1f;
} }
else return (hediff.p_end_tick - hediff.p_start_tick) / GenDate.TicksPerHour; 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.def.race.gestationPeriodDays * GenDate.HoursPerDay;
} }
public static float RandomVariabilityPercent(int recursion = 0) public static float RandomVariabilityPercent(int recursion = 0)

View File

@ -38,7 +38,7 @@ namespace RJW_Menstruation
public override void Miscarry() public override void Miscarry()
{ {
this.GetMenstruationComp().Pregnancy = null; this.GetMenstruationCompFromPregnancy().Pregnancy = null;
base.Miscarry(); base.Miscarry();
} }
@ -70,7 +70,7 @@ namespace RJW_Menstruation
} }
pawn.health.RemoveHediff(this); pawn.health.RemoveHediff(this);
HediffComp_Menstruation comp = this.GetMenstruationComp(); HediffComp_Menstruation comp = this.GetMenstruationCompFromPregnancy();
if(comp != null) comp.Pregnancy = null; if(comp != null) comp.Pregnancy = null;
pawn.GetBreastComp()?.GaveBirth(); pawn.GetBreastComp()?.GaveBirth();
} }
@ -206,10 +206,10 @@ namespace RJW_Menstruation
comp.FluidModifier = originalComp.FluidModifier; comp.FluidModifier = originalComp.FluidModifier;
} }
HediffComp_Menstruation originalMenstruationComp = originalPart.GetMenstruationComp(); HediffComp_Menstruation originalMenstruationComp = originalPart.GetMenstruationCompFromVagina();
if (originalMenstruationComp != null) if (originalMenstruationComp != null)
{ {
part.GetMenstruationComp()?.CopyCycleProperties(originalMenstruationComp); part.GetMenstruationCompFromVagina()?.CopyCycleProperties(originalMenstruationComp);
} }
HediffComp_Breast originalBreastComp = originalPart.GetBreastComp(); HediffComp_Breast originalBreastComp = originalPart.GetBreastComp();
if (originalBreastComp != null) if (originalBreastComp != null)

View File

@ -86,7 +86,7 @@ namespace RJW_Menstruation
{ {
foreach (Hediff diff in diffs) foreach (Hediff diff in diffs)
{ {
HediffComp_Menstruation comp = diff.GetMenstruationComp(); HediffComp_Menstruation comp = diff.GetMenstruationCompFromVagina();
if (comp != null) return comp; if (comp != null) return comp;
} }
return null; return null;

View File

@ -149,7 +149,7 @@ namespace RJW_Menstruation
if (Configurations.EnableBirthVaginaMorph) if (Configurations.EnableBirthVaginaMorph)
{ {
// The comp still has the pregnancy attached at this point in the process // The comp still has the pregnancy attached at this point in the process
Hediff vagina = __instance.GetMenstruationComp()?.parent; Hediff vagina = __instance.GetMenstruationCompFromPregnancy()?.parent;
if (vagina == null) vagina = mother.health.hediffSet.hediffs.FirstOrFallback(x => VariousDefOf.AllVaginas.Contains(x.def)); if (vagina == null) vagina = mother.health.hediffSet.hediffs.FirstOrFallback(x => VariousDefOf.AllVaginas.Contains(x.def));
if (vagina == null) return; if (vagina == null) return;
float morph = Mathf.Max(baby.BodySize - Mathf.Pow(vagina.Severity * mother.BodySize, 2), 0f); float morph = Mathf.Max(baby.BodySize - Mathf.Pow(vagina.Severity * mother.BodySize, 2), 0f);

View File

@ -161,7 +161,7 @@ namespace RJW_Menstruation
fontstyleleft.normal.textColor = Color.white; fontstyleleft.normal.textColor = Color.white;
float preginfoheight = 0f; float preginfoheight = 0f;
Hediff_BasePregnancy hediff = comp.Pregnancy; Hediff hediff = comp.Pregnancy;
if (hediff != null && Utility.ShowFetusImage(hediff)) if (hediff != null && Utility.ShowFetusImage(hediff))
{ {
womb = comp.GetPregnancyIcon(hediff); womb = comp.GetPregnancyIcon(hediff);
@ -218,6 +218,7 @@ namespace RJW_Menstruation
} }
} }
else cum = ContentFinder<Texture2D>.Get(("Womb/Empty"), true); else cum = ContentFinder<Texture2D>.Get(("Womb/Empty"), true);
// TODO: Biotech pregnancy
} }
else else
{ {

View File

@ -141,8 +141,29 @@ namespace RJW_Menstruation
return pawn.health.hediffSet.GetFirstHediff<Hediff_BasePregnancy>() != null; return pawn.health.hediffSet.GetFirstHediff<Hediff_BasePregnancy>() != null;
} }
public static bool IsBiotechPregnant(this Pawn pawn)
{
if (!ModsConfig.BiotechActive) return false;
foreach (HediffDef def in pawn.health.hediffSet.hediffs.Select(hediff => hediff.def))
{
if (def == HediffDefOf.PregnantHuman || def == HediffDefOf.PregnancyLabor || def == HediffDefOf.PregnancyLaborPushing)
return true;
}
return false;
}
public static float GetFarthestPregnancyProgress(this Pawn pawn) public static float GetFarthestPregnancyProgress(this Pawn pawn)
{ {
if (ModsConfig.BiotechActive)
{
foreach (Hediff hediff in pawn.health.hediffSet.hediffs)
{
if (hediff.def == HediffDefOf.PregnancyLabor || hediff.def == HediffDefOf.PregnancyLaborPushing)
return 1.0f;
if (hediff.def == HediffDefOf.PregnantHuman)
return hediff.Severity;
}
}
List<Hediff_BasePregnancy> pregnancies = new List<Hediff_BasePregnancy>(); List<Hediff_BasePregnancy> pregnancies = new List<Hediff_BasePregnancy>();
pawn.health.hediffSet.GetHediffs(ref pregnancies); pawn.health.hediffSet.GetHediffs(ref pregnancies);
return pregnancies.MaxByWithFallback(hediff => hediff.GestationProgress)?.GestationProgress ?? 0; return pregnancies.MaxByWithFallback(hediff => hediff.GestationProgress)?.GestationProgress ?? 0;
@ -151,19 +172,24 @@ namespace RJW_Menstruation
public static float GetPregnancyProgress(this HediffComp_Menstruation comp) public static float GetPregnancyProgress(this HediffComp_Menstruation comp)
{ {
if (comp.Pregnancy == null) return 0; if (comp.Pregnancy == null) return 0;
else return comp.Pregnancy.GestationProgress; else return comp.StageProgress;
} }
public static Pawn GetFetus(this HediffComp_Menstruation comp) public static Pawn GetFetus(this HediffComp_Menstruation comp)
{ {
if (comp.Pregnancy == null) return null; if (comp.Pregnancy == null) return null;
if (!comp.Pregnancy.babies.NullOrEmpty()) return comp.Pregnancy.babies.First(); if (comp.Pregnancy is Hediff_BasePregnancy rjw_preg)
else
{ {
Log.Error("Baby not exist: baby was not created or removed. Remove pregnancy."); if (!rjw_preg.babies.NullOrEmpty()) return rjw_preg.babies.First();
comp.Pregnancy.Miscarry(); else
return null; {
Log.Error("Baby not exist: baby was not created or removed. Remove pregnancy.");
rjw_preg.Miscarry();
return null;
}
} }
// TODO: Biotech
return null;
} }
public static void DrawBreastIcon(this Pawn pawn, Rect rect) public static void DrawBreastIcon(this Pawn pawn, Rect rect)
@ -347,7 +373,7 @@ namespace RJW_Menstruation
} }
public static bool ShowFetusImage(this Hediff_BasePregnancy hediff) public static bool ShowFetusImage(this Hediff hediff)
{ {
if (Configurations.InfoDetail == Configurations.DetailLevel.All) return true; if (Configurations.InfoDetail == Configurations.DetailLevel.All) return true;
else if (Configurations.InfoDetail == Configurations.DetailLevel.Hide) return false; else if (Configurations.InfoDetail == Configurations.DetailLevel.Hide) return false;