rjw_menstruation/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_PregeneratedBabi...

140 lines
6.2 KiB
C#
Raw Normal View History

2023-01-08 04:18:17 +00:00
using RimWorld;
using RimWorld.BaseGen;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Verse;
namespace RJW_Menstruation
{
public class HediffComp_PregeneratedBabies : HediffComp
{
public List<Pawn> babies;
// Unused, but can't hurt to track
protected Dictionary<Pawn, Pawn> enzygoticSiblings;
protected static readonly MethodInfo RandomLastName = typeof(PregnancyUtility).GetMethod("RandomLastName", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(Pawn), typeof(Pawn), typeof(Pawn) }, null);
public bool HasBaby
{
get => !babies.NullOrEmpty();
}
public Pawn PopBaby()
{
if (babies.NullOrEmpty()) return null;
Pawn firstBaby = babies.First();
babies.Remove(firstBaby);
return firstBaby;
}
public override void CompPostPostRemoved()
{
// At this point in the hediff removal process, the new hediff is already on the pawn
// But it is possible that there is no new hediff (be it a birth, miscarrage, or dev edit)
base.CompPostPostRemoved();
// Send the babies from this comp to the new one
2023-01-08 04:18:17 +00:00
switch (parent)
{
case Hediff_Pregnant hediff_Pregnant:
Hediff_Labor labor = (Hediff_Labor)Pawn.health.hediffSet.hediffs.Where(hediff => hediff is Hediff_Labor).MaxByWithFallback(hediff => hediff.loadID);
HediffComp_PregeneratedBabies laborcomp = labor?.TryGetComp<HediffComp_PregeneratedBabies>();
if (laborcomp == null) return;
laborcomp.babies = this.babies;
laborcomp.enzygoticSiblings = this.enzygoticSiblings;
break;
case Hediff_Labor hediff_Labor:
Hediff_LaborPushing pushing = (Hediff_LaborPushing)Pawn.health.hediffSet.hediffs.Where(hediff => hediff is Hediff_LaborPushing).MaxByWithFallback(hediff => hediff.loadID);
HediffComp_PregeneratedBabies pushingcomp = pushing?.TryGetComp<HediffComp_PregeneratedBabies>();
if (pushingcomp == null) return;
pushingcomp.babies = this.babies;
pushingcomp.enzygoticSiblings = this.enzygoticSiblings;
break;
case Hediff_LaborPushing hediff_LaborPushing:
// Nothing to do, the laborpushing transpiler will pick it up
break;
}
}
public override void CompExposeData()
{
base.CompExposeData();
Scribe_Collections.Look(ref babies, "babies", LookMode.Deep);
Scribe_Collections.Look(ref enzygoticSiblings, "enzygoticSiblings", keyLookMode: LookMode.Reference, valueLookMode: LookMode.Reference);
}
public void AddNewBaby(Pawn mother, Pawn father)
{
if (babies == null) babies = new List<Pawn>();
PawnKindDef babyPawnKind = PregnancyCommon.BabyPawnKindDecider(mother, father, true);
2023-01-08 04:18:17 +00:00
PawnGenerationRequest request = new PawnGenerationRequest
(
kind: babyPawnKind,
faction: mother.Faction,
allowDowned: true,
fixedLastName: (string)RandomLastName.Invoke(null, new object[] { mother, mother, xxx.is_human(father) ? father : null }),
forceNoIdeo: true,
// Kill on bad positivity in the post-birth
// forceDead: positivityIndex == -1
forcedEndogenes: PregnancyUtility.GetInheritedGenes(father, mother),
forcedXenotype: XenotypeDefOf.Baseliner,
developmentalStages: DevelopmentalStage.Newborn
);
int division = 1;
Pawn firstbaby = null;
while (Rand.Chance(Configurations.EnzygoticTwinsChance) && division < Configurations.MaxEnzygoticTwins) division++;
if (division > 1 && enzygoticSiblings == null) enzygoticSiblings = new Dictionary<Pawn, Pawn>();
for (int i = 0; i < division; i++)
{
Pawn baby = PawnGenerator.GeneratePawn(request);
if (baby == null) break;
PregnancyCommon.SetupBabyXenotype(mother, father, baby);
if (division > 1)
{
if (i == 0)
{
if (baby.IsHAR())
baby.Drawer.renderer.graphics.ResolveAllGraphics();
firstbaby = baby;
request.FixedGender = baby.gender;
request.ForcedEndogenes = baby.genes?.Endogenes.Select(gene => gene.def).ToList();
}
else
{
enzygoticSiblings.Add(baby, firstbaby);
if (baby.story != null)
{
baby.story.headType = firstbaby.story.headType;
baby.story.hairDef = firstbaby.story.hairDef;
baby.story.bodyType = firstbaby.story.bodyType;
baby.story.furDef = firstbaby.story.furDef;
}
if (baby.genes != null)
2023-01-08 04:18:17 +00:00
{
baby.genes.SetXenotypeDirect(firstbaby.genes.Xenotype);
baby.genes.xenotypeName = firstbaby.genes.xenotypeName;
baby.genes.iconDef = firstbaby.genes.iconDef;
baby.genes.hybrid = firstbaby.genes.hybrid;
}
if (baby.IsHAR())
HARCompatibility.CopyHARProperties(baby, firstbaby);
// MultiplePregnancy calls this post-birth because RJW resets private parts
// So xenotype things shouldn't be shared
PregnancyCommon.ProcessIdenticalSibling(baby, firstbaby);
}
}
babies.Add(baby);
}
}
}
}