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 float antisperm = 0.0f;
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()
{
@ -147,7 +148,7 @@ namespace RJW_Menstruation
new CurvePoint(1.0f,0.5f)
};
public Hediff_BasePregnancy Pregnancy {
public Hediff Pregnancy {
get
{
if (pregnancy == null) return null;
@ -538,7 +539,22 @@ namespace RJW_Menstruation
get
{
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
float discoveryTime = 0.5f;
@ -673,8 +689,19 @@ namespace RJW_Menstruation
Log.Warning($"Attempted to remove menstruation comp from wrong pawn ({Pawn}).");
return;
}
if (pregnancy != null && !(pregnancy is Hediff_MechanoidPregnancy))
pregnancy.Miscarry();
switch (pregnancy)
{
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();
}
@ -1197,6 +1224,13 @@ namespace RJW_Menstruation
deadeggs.Add(egg);
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)
{
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
{
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);
pregnant = true;
deadeggs.Add(egg);
}
pregnancy.p_start_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour;
pregnancy.p_end_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour;
if (pregnancy is Hediff_BasePregnancy rjw_preg)
{
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;
}
// 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()
{
if (pregnancy != null) return;
List<Hediff_BasePregnancy> pregnancies = new List<Hediff_BasePregnancy>();
Pawn.health.hediffSet.GetHediffs(ref pregnancies);
IEnumerable<Hediff> pregnancies = Pawn.health.hediffSet.hediffs.Where(hediff =>
hediff is Hediff_BasePregnancy ||
hediff is Hediff_Pregnant ||
hediff is Hediff_Labor ||
hediff is Hediff_LaborPushing);
pregnancy =
pregnancies.Except(

View File

@ -44,7 +44,7 @@ namespace RJW_Menstruation
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))
{
@ -53,7 +53,7 @@ namespace RJW_Menstruation
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);
}
@ -112,6 +112,7 @@ namespace RJW_Menstruation
else if (h.GestationProgress < 0.8f) icon += fetustex + "04";
else icon += fetustex + "05";
}
// TODO: Biotech
else icon = "Fetus/Slime_Abomi02";
Texture2D result = TryGetTwinsIcon(icon, babycount);
@ -299,14 +300,17 @@ namespace RJW_Menstruation
return ContentFinder<Texture2D>.Get((icon), true);
}
public static float GestationHours(this Hediff_BasePregnancy hediff)
public static float GestationHours(this Hediff hediff)
{
if (hediff == null)
{
Log.Error("Tried to get gestation length without a pregnancy.");
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)

View File

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

View File

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

View File

@ -149,7 +149,7 @@ namespace RJW_Menstruation
if (Configurations.EnableBirthVaginaMorph)
{
// 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) return;
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;
float preginfoheight = 0f;
Hediff_BasePregnancy hediff = comp.Pregnancy;
Hediff hediff = comp.Pregnancy;
if (hediff != null && Utility.ShowFetusImage(hediff))
{
womb = comp.GetPregnancyIcon(hediff);
@ -218,6 +218,7 @@ namespace RJW_Menstruation
}
}
else cum = ContentFinder<Texture2D>.Get(("Womb/Empty"), true);
// TODO: Biotech pregnancy
}
else
{

View File

@ -141,8 +141,29 @@ namespace RJW_Menstruation
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)
{
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>();
pawn.health.hediffSet.GetHediffs(ref pregnancies);
return pregnancies.MaxByWithFallback(hediff => hediff.GestationProgress)?.GestationProgress ?? 0;
@ -151,19 +172,24 @@ namespace RJW_Menstruation
public static float GetPregnancyProgress(this HediffComp_Menstruation comp)
{
if (comp.Pregnancy == null) return 0;
else return comp.Pregnancy.GestationProgress;
else return comp.StageProgress;
}
public static Pawn GetFetus(this HediffComp_Menstruation comp)
{
if (comp.Pregnancy == null) return null;
if (!comp.Pregnancy.babies.NullOrEmpty()) return comp.Pregnancy.babies.First();
else
if (comp.Pregnancy is Hediff_BasePregnancy rjw_preg)
{
Log.Error("Baby not exist: baby was not created or removed. Remove pregnancy.");
comp.Pregnancy.Miscarry();
return null;
if (!rjw_preg.babies.NullOrEmpty()) return rjw_preg.babies.First();
else
{
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)
@ -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;
else if (Configurations.InfoDetail == Configurations.DetailLevel.Hide) return false;