mirror of
https://gitgud.io/lutepickle/rjw_menstruation.git
synced 2024-08-14 22:46:52 +00:00
Compare commits
5 commits
b4aa55c159
...
045e9548f6
Author | SHA1 | Date | |
---|---|---|---|
|
045e9548f6 | ||
|
3f21b760b2 | ||
|
21e471ebf3 | ||
|
da9903aaf9 | ||
|
22b2aca312 |
12 changed files with 507 additions and 299 deletions
|
@ -73,7 +73,7 @@
|
|||
<GeneDef ParentName="Menstruation_Ovulation">
|
||||
<defName>Menstruation_DoubleOvulation</defName>
|
||||
<label>double ovulation</label>
|
||||
<description>Wombs with this gene will ovulate twice as many eggs.</description>
|
||||
<description>Carriers of this gene will ovulate twice as many eggs.</description>
|
||||
<biostatMet>-1</biostatMet>
|
||||
<displayOrderInCategory>30</displayOrderInCategory>
|
||||
</GeneDef>
|
||||
|
@ -81,7 +81,7 @@
|
|||
<GeneDef ParentName="Menstruation_Ovulation">
|
||||
<defName>Menstruation_QuadOvulation</defName>
|
||||
<label>quadruple ovulation</label>
|
||||
<description>Wombs with this gene will ovulate four times as many eggs.</description>
|
||||
<description>Carriers of this gene will ovulate four times as many eggs.</description>
|
||||
<biostatMet>-1</biostatMet>
|
||||
<displayOrderInCategory>35</displayOrderInCategory>
|
||||
</GeneDef>
|
||||
|
@ -90,7 +90,7 @@
|
|||
<defName>Menstruation_NoBleeding</defName>
|
||||
<label>no bleeding</label>
|
||||
<displayCategory>Menstruation</displayCategory>
|
||||
<description>Wombs with this gene will not bleed at the end of their cycle.</description>
|
||||
<description>Carriers of this gene will not bleed at the end of their cycle.</description>
|
||||
<biostatMet>1</biostatMet>
|
||||
<displayOrderInCategory>40</displayOrderInCategory>
|
||||
</GeneDef>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LanguageData>
|
||||
<Menstruation.label>月經週期</Menstruation.label>
|
||||
<Menstruation_ShortEggLifetime.label>較短卵細胞壽命</Menstruation_ShortEggLifetime.label>
|
||||
<Menstruation_ShortEggLifetime.description>未受精卵細胞存活時長僅有原先的3/4</Menstruation_ShortEggLifetime.description>
|
||||
<Menstruation_DoubleEggLifetime.label>雙倍卵細胞壽命</Menstruation_DoubleEggLifetime.label>
|
||||
<Menstruation_DoubleEggLifetime.description>未受精卵細胞可存活至原先的2倍之久</Menstruation_DoubleEggLifetime.description>
|
||||
<Menstruation_QuadEggLifetime.label>四倍卵細胞壽命</Menstruation_QuadEggLifetime.label>
|
||||
<Menstruation_QuadEggLifetime.description>未受精卵細胞可存活至原先的4倍之久</Menstruation_QuadEggLifetime.description>
|
||||
<Menstruation_NeverEstrus.label>永不發情</Menstruation_NeverEstrus.label>
|
||||
<Menstruation_NeverEstrus.description>基因攜帶者永遠不會進入發情期。</Menstruation_NeverEstrus.description>
|
||||
<Menstruation_FullEstrus.label>始終發情</Menstruation_FullEstrus.label>
|
||||
<Menstruation_FullEstrus.description>基因攜帶者的每一個月經週期均具備發情期,無論陰道類型為何。</Menstruation_FullEstrus.description>
|
||||
<Menstruation_DoubleOvulation.label>雙倍排卵</Menstruation_DoubleOvulation.label>
|
||||
<Menstruation_DoubleOvulation.description>基因攜帶者的子宮可以在每個排卵週期產生雙倍的卵子。</Menstruation_DoubleOvulation.description>
|
||||
<Menstruation_QuadOvulation.label>四倍排卵</Menstruation_QuadOvulation.label>
|
||||
<Menstruation_QuadOvulation.description>基因攜帶者的子宮可以在每個排卵週期產生四倍的卵子。</Menstruation_QuadOvulation.description>
|
||||
<Menstruation_NoBleeding.label>無經血</Menstruation_NoBleeding.label>
|
||||
<Menstruation_NoBleeding.description>基因攜帶者的子宮內膜不會脫落出血。</Menstruation_NoBleeding.description>
|
||||
</LanguageData>
|
|
@ -8,4 +8,7 @@
|
|||
<TookContraceptivePill.stages.0.description>總算把這事了結了。</TookContraceptivePill.stages.0.description>
|
||||
<HateTookContraceptivePill.stages.0.label>吃了避孕藥</HateTookContraceptivePill.stages.0.label>
|
||||
<HateTookContraceptivePill.stages.0.description>我想要小孩!</HateTookContraceptivePill.stages.0.description>
|
||||
<!--Auto generated: Thu Jan 5 22:13:15 2023-->
|
||||
<EggRestorationReceived.stages.0.label>卵母細胞再生術</EggRestorationReceived.stages.0.label>
|
||||
<EggRestorationReceived.stages.0.description>我可以繼續繁衍一小段時間了!</EggRestorationReceived.stages.0.description>
|
||||
</LanguageData>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<Option7_Label>月經加速</Option7_Label>
|
||||
<Option7_Desc>加快月經週期</Option7_Desc>
|
||||
<Option8_Label>除錯</Option8_Label>
|
||||
<Option8_Desc>顯示除錯資訊</Option8_Desc>
|
||||
<Option8_Desc>顯示除錯資訊 啟用時會令「胎兒信息級別」選項調至「全部細節」。</Option8_Desc>
|
||||
<Option9_Label>子宮狀態</Option9_Label>
|
||||
<Option9_Desc>在狀態窗口中繪製子宮圖標</Option9_Desc>
|
||||
<Option10_Label>陰道狀態</Option10_Label>
|
||||
|
@ -62,7 +62,6 @@
|
|||
<Option17_Label>最大雙胞胎數量</Option17_Label>
|
||||
<Option17_Desc>設置最大雙胞胎數量</Option17_Desc>
|
||||
<FloatMenu_CleanSelf>清洗陰道</FloatMenu_CleanSelf>
|
||||
|
||||
<!--Auto generated: Mon Oct 3 21:49:26 2022-->
|
||||
<Stage_Menopause>絕經</Stage_Menopause>
|
||||
<Stage_Anestrus>乏情期</Stage_Anestrus>
|
||||
|
@ -98,7 +97,7 @@
|
|||
<Option21_Label>本模組作用於:</Option21_Label>
|
||||
<Option21_Desc>這些小人的「RJW月經週期」工具欄對玩家可見。</Option21_Desc>
|
||||
<Option22_Label>使用進階雜交定義</Option22_Label>
|
||||
<Option22_Desc>複寫RJW和RaceSupport插件的雜交定義。Overrides RJW and RaceSupport's hybrid definition.
|
||||
<Option22_Desc>覆寫RJW和RaceSupport插件的雜交定義。Overrides RJW and RaceSupport's hybrid definition.
|
||||
主導混合擴展決定了首先使用誰的定義。不建議更改此設置。Dominant hybrid extension determines whose definition used first. Not recommended to change this.</Option22_Desc>
|
||||
<Option23_Label>主導混合擴展Dominant hybrid extension</Option23_Label>
|
||||
<Option23_Label_1>母本</Option23_Label_1>
|
||||
|
@ -111,7 +110,7 @@
|
|||
<Option_PermanentNippleChange_Desc>乳頭在孕期間的改變會在孕期結束後保留多少?</Option_PermanentNippleChange_Desc>
|
||||
<Option28_Label>客製化雜交細節</Option28_Label>
|
||||
<Option28_Tooltip>開啟雜交編輯器
|
||||
該選項會複寫XML文件中的雜交定義。</Option28_Tooltip>
|
||||
該選項會覆寫XML文件中的雜交定義。</Option28_Tooltip>
|
||||
<Option29_Label>允許圖標縮小</Option29_Label>
|
||||
<Option29_Desc>允許圖標在特殊場合縮小。</Option29_Desc>
|
||||
<Option30_Label>卵細胞生命期乘數</Option30_Label>
|
||||
|
@ -123,7 +122,7 @@
|
|||
<Option32_Label>擴張力度</Option32_Label>
|
||||
<Option32_Desc>調節擴張力度。</Option32_Desc>
|
||||
<Option_EnableGatherCumGizmo_Label>啟用「擠出精液」按鈕</Option_EnableGatherCumGizmo_Label>
|
||||
<Option_EstrusOverride_Label>令「發情期」機制複寫RJW的濫交選項</Option_EstrusOverride_Label>
|
||||
<Option_EstrusOverride_Label>令「發情期」機制覆寫RJW的濫交選項</Option_EstrusOverride_Label>
|
||||
<Option_EstrusOverride_Desc>啟用時,處於顯式發情期的小人將會使用以下選項來選定床伴。RJW的原始設定會被忽略。
|
||||
所有數值與RJW的對應選項相同。</Option_EstrusOverride_Desc>
|
||||
<Option_EstrusFuckability_Label>發情期床伴:最低fuckability</Option_EstrusFuckability_Label>
|
||||
|
@ -139,4 +138,13 @@
|
|||
<CustomHybrid_Title>{0}之雜交</CustomHybrid_Title>
|
||||
<CustomHybrid_Tooltip>當{0}與{1}產生後代,有{3}的概率生出{2}。
|
||||
若兩個種族相互間皆存在雜交定義,則以父本的定義為準。</CustomHybrid_Tooltip>
|
||||
<!--Auto generated: Thu Jan 5 22:13:15 2023-->
|
||||
<Option_PregnancyFromBaseRJW_Label>使用RJW的簡單懷孕系統</Option_PregnancyFromBaseRJW_Label>
|
||||
<Option_PregnancyFromMultiplePregnancy_Label>使用本模組的多重懷孕</Option_PregnancyFromMultiplePregnancy_Label>
|
||||
<Option_PregnancyFromBiotech_Label>使用「生機」(Biotech)追加的懷孕機制</Option_PregnancyFromBiotech_Label>
|
||||
<Option_EnableDraftedIcon_Label>於「徵召」狀態下仍顯示子宮狀態</Option_EnableDraftedIcon_Label>
|
||||
<Option_EnableDraftedIcon_Desc>角色處於被徵召狀態時,子宮圖標不予隱藏。</Option_EnableDraftedIcon_Desc>
|
||||
<CannotNoEggs>沒有卵細胞</CannotNoEggs>
|
||||
<CannotNoWomb>必須擁有子宮</CannotNoWomb>
|
||||
<EggRestorationCompleted>{PAWN_labelShort}完成了{PAWN_possessive}卵母細胞再生術(cycle)</EggRestorationCompleted>
|
||||
</LanguageData>
|
||||
|
|
16
1.4/Patches/Pregenerated_Babies.xml
Normal file
16
1.4/Patches/Pregenerated_Babies.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Patch>
|
||||
<Operation Class="PatchOperationFindMod">
|
||||
<mods>
|
||||
<li>Biotech</li>
|
||||
</mods>
|
||||
<match Class="PatchOperationAdd">
|
||||
<xpath>/Defs/HediffDef[defName="PregnantHuman" or defName="PregnancyLabor" or defName="PregnancyLaborPushing"]/comps</xpath>
|
||||
<value>
|
||||
<li>
|
||||
<compClass>RJW_Menstruation.HediffComp_PregeneratedBabies</compClass>
|
||||
</li>
|
||||
</value>
|
||||
</match>
|
||||
</Operation>
|
||||
</Patch>
|
|
@ -0,0 +1,138 @@
|
|||
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();
|
||||
|
||||
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);
|
||||
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 && ModsConfig.BiotechActive)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,9 +13,6 @@ namespace RJW_Menstruation
|
|||
{
|
||||
protected Dictionary<Pawn, Pawn> enzygoticSiblings = new Dictionary<Pawn, Pawn>(); // Each pawn and who they split from
|
||||
|
||||
protected readonly MethodInfo TryGetInheritedXenotype = typeof(PregnancyUtility).GetMethod("TryGetInheritedXenotype", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(Pawn), typeof(Pawn), typeof(XenotypeDef).MakeByRefType() }, null );
|
||||
protected readonly MethodInfo ShouldByHybrid = typeof(PregnancyUtility).GetMethod("ShouldByHybrid", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(Pawn), typeof(Pawn) }, null);
|
||||
|
||||
public override void DiscoverPregnancy()
|
||||
{
|
||||
PregnancyThought();
|
||||
|
@ -82,48 +79,6 @@ namespace RJW_Menstruation
|
|||
breastcomp?.GaveBirth();
|
||||
}
|
||||
|
||||
public string GetBabyInfo()
|
||||
{
|
||||
if (babies.NullOrEmpty())
|
||||
return "Null";
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
IEnumerable<Pawn> babiesdistinct = babies.Distinct(new RaceComparer());
|
||||
int iteration = 0;
|
||||
foreach (Pawn baby in babiesdistinct)
|
||||
{
|
||||
int num = babies.Where(x => x.def.Equals(baby.def)).Count();
|
||||
if (iteration > 0) res.Append(", ");
|
||||
res.AppendFormat("{0} {1}", num, baby.def.label);
|
||||
iteration++;
|
||||
}
|
||||
res.AppendFormat(" {0}", Translations.Dialog_WombInfo02);
|
||||
return res.ToString();
|
||||
}
|
||||
|
||||
public string GetFatherInfo()
|
||||
{
|
||||
if (babies.NullOrEmpty())
|
||||
return "Null";
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
res.AppendFormat("{0}: ", Translations.Dialog_WombInfo03);
|
||||
|
||||
if (!is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All)
|
||||
return res.Append(Translations.Dialog_FatherUnknown).ToString();
|
||||
|
||||
IEnumerable<Pawn> babiesdistinct = babies.Distinct(new FatherComparer(pawn));
|
||||
int iteration = 0;
|
||||
foreach (Pawn baby in babiesdistinct)
|
||||
{
|
||||
if (iteration > 0) res.Append(", ");
|
||||
res.Append(Utility.GetFather(baby, pawn)?.LabelShort ?? Translations.Dialog_FatherUnknown);
|
||||
iteration++;
|
||||
}
|
||||
return res.ToString();
|
||||
}
|
||||
|
||||
private void HumanlikeBirth(Pawn baby)
|
||||
{
|
||||
Pawn mother = pawn; Pawn father = Utility.GetFather(baby, pawn);
|
||||
|
@ -167,7 +122,7 @@ namespace RJW_Menstruation
|
|||
if (ModsConfig.BiotechActive)
|
||||
{
|
||||
// Ugly, but it'll have to do
|
||||
OutcomeChance bestOutcome = RitualOutcomeEffectDefOf.ChildBirth.outcomeChances.Find(chance => chance.positivityIndex == 1);
|
||||
OutcomeChance bestOutcome = RitualOutcomeEffectDefOf.ChildBirth.BestOutcome;
|
||||
|
||||
string label = bestOutcome.label;
|
||||
string description = bestOutcome.description.Formatted(mother.Named("MOTHER"));
|
||||
|
@ -212,65 +167,12 @@ namespace RJW_Menstruation
|
|||
//baby.story.birthLastName = last_name;
|
||||
}
|
||||
|
||||
protected void CopyBodyPartProperties(Hediff part, Hediff originalPart)
|
||||
{
|
||||
CompHediffBodyPart comp = part.TryGetComp<CompHediffBodyPart>();
|
||||
CompHediffBodyPart originalComp = originalPart.TryGetComp<CompHediffBodyPart>();
|
||||
|
||||
if (comp != null && originalComp != null)
|
||||
{
|
||||
// the string properties should be the same between both pawns anyways, besides the name of the owner
|
||||
part.Severity = originalPart.Severity;
|
||||
comp.SizeBase = originalComp.SizeBase;
|
||||
comp.SizeOwner = originalComp.SizeOwner;
|
||||
comp.EffSize = originalComp.EffSize;
|
||||
comp.FluidAmmount = originalComp.FluidAmmount;
|
||||
comp.FluidModifier = originalComp.FluidModifier;
|
||||
}
|
||||
|
||||
HediffComp_Menstruation originalMenstruationComp = originalPart.GetMenstruationCompFromVagina();
|
||||
if (originalMenstruationComp != null)
|
||||
{
|
||||
part.GetMenstruationCompFromVagina()?.CopyCycleProperties(originalMenstruationComp);
|
||||
}
|
||||
HediffComp_Breast originalBreastComp = originalPart.GetBreastComp();
|
||||
if (originalBreastComp != null)
|
||||
{
|
||||
part.GetBreastComp()?.CopyBreastProperties(originalBreastComp);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CopyBodyPartRecord(Pawn baby, Pawn original, BodyPartRecord babyBPR, BodyPartRecord originalBPR)
|
||||
{
|
||||
if (babyBPR == null || originalBPR == null) return;
|
||||
|
||||
RemoveBabyParts(baby, Genital_Helper.get_PartsHediffList(baby, babyBPR));
|
||||
foreach (Hediff originalPart in Genital_Helper.get_PartsHediffList(original, originalBPR))
|
||||
{
|
||||
Hediff part = SexPartAdder.MakePart(originalPart.def, baby, babyBPR);
|
||||
CopyBodyPartProperties(part, originalPart);
|
||||
baby.health.AddHediff(part, babyBPR);
|
||||
}
|
||||
}
|
||||
|
||||
// Baby is the sibling to be changed, original is the first of the set and the one to copy to the rest.
|
||||
public virtual void ProcessIdenticalSibling(Pawn baby, Pawn original)
|
||||
{
|
||||
// They'll be the same pawnkind, which lets us make a lot of useful assumptions
|
||||
// However, some RNG might still be involved in genital generation (e.g. futas), so the easiest method is to clear out and re-generate
|
||||
// A bit wasteful since Hediff_BasePregnancy.PostBirth already redid the genitals
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_genitalsBPR(baby), Genital_Helper.get_genitalsBPR(original));
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_breastsBPR(baby), Genital_Helper.get_breastsBPR(original));
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_uddersBPR(baby), Genital_Helper.get_uddersBPR(original));
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_anusBPR(baby), Genital_Helper.get_anusBPR(original));
|
||||
}
|
||||
|
||||
public override void PostBirth(Pawn mother, Pawn father, Pawn baby)
|
||||
{
|
||||
base.PostBirth(mother, father, baby);
|
||||
// Has to happen on birth since RJW redoes the genitals at birth
|
||||
if (!enzygoticSiblings.NullOrEmpty() && enzygoticSiblings.TryGetValue(baby, out Pawn original) && baby != original)
|
||||
ProcessIdenticalSibling(baby, original);
|
||||
PregnancyCommon.ProcessIdenticalSibling(baby, original);
|
||||
}
|
||||
|
||||
// From RJW's trait code
|
||||
|
@ -411,7 +313,7 @@ namespace RJW_Menstruation
|
|||
allowAddictions: false,
|
||||
relationWithExtraPawnChanceFactor: 0,
|
||||
fixedLastName: lastname,
|
||||
kind: BabyPawnKindDecider(mother, father),
|
||||
kind: PregnancyCommon.BabyPawnKindDecider(mother, father),
|
||||
//fixedIdeo: mother.Ideo,
|
||||
forbidAnyTitle: true,
|
||||
forceNoBackstory: true,
|
||||
|
@ -428,25 +330,7 @@ namespace RJW_Menstruation
|
|||
{
|
||||
Pawn baby = GenerateBaby(request, mother, father, parentTraits, traitSeed);
|
||||
if (baby == null) break;
|
||||
if (baby.genes != null && ModsConfig.BiotechActive)
|
||||
{
|
||||
if (GeneUtility.SameHeritableXenotype(mother, father) && mother.genes.UniqueXenotype)
|
||||
{
|
||||
baby.genes.xenotypeName = mother.genes.xenotypeName;
|
||||
baby.genes.iconDef = mother.genes.iconDef;
|
||||
}
|
||||
|
||||
object[] args = new object[] { mother, father, null };
|
||||
if ((bool)TryGetInheritedXenotype.Invoke(null, args))
|
||||
{
|
||||
baby.genes.SetXenotypeDirect((XenotypeDef)args[2]);
|
||||
}
|
||||
else if((bool)ShouldByHybrid.Invoke(null, new object[] { mother, father }))
|
||||
{
|
||||
baby.genes.hybrid = true;
|
||||
baby.genes.xenotypeName = "Hybrid".Translate();
|
||||
}
|
||||
}
|
||||
PregnancyCommon.SetupBabyXenotype(mother, father, baby);
|
||||
if (division > 1)
|
||||
{
|
||||
if (i == 0)
|
||||
|
@ -466,6 +350,7 @@ namespace RJW_Menstruation
|
|||
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 && ModsConfig.BiotechActive)
|
||||
|
@ -519,174 +404,6 @@ namespace RJW_Menstruation
|
|||
return baby;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decide pawnkind from mother and father <para/>
|
||||
/// Come from RJW
|
||||
/// </summary>
|
||||
/// <param name="mother"></param>
|
||||
/// <param name="father"></param>
|
||||
/// <returns></returns>
|
||||
public PawnKindDef BabyPawnKindDecider(Pawn mother, Pawn father)
|
||||
{
|
||||
PawnKindDef motherKindDef = Utility.GetRacesPawnKind(mother);
|
||||
PawnKindDef fatherKindDef = Utility.GetRacesPawnKind(father);
|
||||
|
||||
PawnKindDef spawn_kind_def = motherKindDef;
|
||||
|
||||
int flag = 0;
|
||||
if (xxx.is_human(mother)) flag += 2;
|
||||
if (xxx.is_human(father)) flag += 1;
|
||||
//Mother - Father = Flag
|
||||
//Human - Human = 3
|
||||
//Human - Animal = 2
|
||||
//Animal - Human = 1
|
||||
//Animal - Animal = 0
|
||||
|
||||
switch (flag)
|
||||
{
|
||||
case 3:
|
||||
if (!Rand.Chance(RJWPregnancySettings.humanlike_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
case 2:
|
||||
if (RJWPregnancySettings.bestiality_DNA_inheritance == 0f) spawn_kind_def = fatherKindDef;
|
||||
else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
case 1:
|
||||
if (RJWPregnancySettings.bestiality_DNA_inheritance == 1f) spawn_kind_def = fatherKindDef;
|
||||
else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
case 0:
|
||||
if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
}
|
||||
|
||||
bool IsAndroidmother = AndroidsCompatibility.IsAndroid(mother);
|
||||
bool IsAndroidfather = AndroidsCompatibility.IsAndroid(father);
|
||||
if (IsAndroidmother && !IsAndroidfather)
|
||||
{
|
||||
spawn_kind_def = fatherKindDef;
|
||||
}
|
||||
else if (!IsAndroidmother && IsAndroidfather)
|
||||
{
|
||||
spawn_kind_def = motherKindDef;
|
||||
}
|
||||
|
||||
string MotherRaceName = "";
|
||||
string FatherRaceName = "";
|
||||
MotherRaceName = motherKindDef?.race?.defName;
|
||||
PawnKindDef non_hybrid_kind_def = spawn_kind_def;
|
||||
if (father != null)
|
||||
FatherRaceName = fatherKindDef?.race?.defName;
|
||||
|
||||
|
||||
if (FatherRaceName != "" && Configurations.UseHybridExtention)
|
||||
{
|
||||
spawn_kind_def = GetHybrid(father, mother);
|
||||
//Log.Message("pawnkind: " + spawn_kind_def?.defName);
|
||||
}
|
||||
|
||||
if (MotherRaceName != FatherRaceName && FatherRaceName != "")
|
||||
{
|
||||
if (!Configurations.UseHybridExtention || spawn_kind_def == null)
|
||||
{
|
||||
spawn_kind_def = non_hybrid_kind_def;
|
||||
IEnumerable<RaceGroupDef> groups = DefDatabase<RaceGroupDef>.AllDefs.Where(x => !(x.hybridRaceParents.NullOrEmpty() || x.hybridChildKindDef.NullOrEmpty()));
|
||||
|
||||
|
||||
//ModLog.Message(" found custom RaceGroupDefs " + groups.Count());
|
||||
foreach (RaceGroupDef t in groups)
|
||||
{
|
||||
if ((t.hybridRaceParents.Contains(MotherRaceName) && t.hybridRaceParents.Contains(FatherRaceName))
|
||||
|| (t.hybridRaceParents.Contains("Any") && (t.hybridRaceParents.Contains(MotherRaceName) || t.hybridRaceParents.Contains(FatherRaceName))))
|
||||
{
|
||||
//ModLog.Message(" has hybridRaceParents");
|
||||
if (t.hybridChildKindDef.Contains("MotherKindDef"))
|
||||
spawn_kind_def = motherKindDef;
|
||||
else if (t.hybridChildKindDef.Contains("FatherKindDef") && father != null)
|
||||
spawn_kind_def = fatherKindDef;
|
||||
else
|
||||
{
|
||||
//ModLog.Message(" trying hybridChildKindDef " + t.defName);
|
||||
List<PawnKindDef> child_kind_def_list = new List<PawnKindDef>();
|
||||
child_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => t.hybridChildKindDef.Contains(x.defName)));
|
||||
|
||||
//ModLog.Message(" found custom hybridChildKindDefs " + t.hybridChildKindDef.Count);
|
||||
if (!child_kind_def_list.NullOrEmpty())
|
||||
spawn_kind_def = child_kind_def_list.RandomElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (!Configurations.UseHybridExtention || spawn_kind_def == null)
|
||||
{
|
||||
spawn_kind_def = mother.RaceProps?.AnyPawnKind ?? motherKindDef;
|
||||
}
|
||||
|
||||
if (spawn_kind_def.defName.Contains("Nymph"))
|
||||
{
|
||||
//child is nymph, try to find other PawnKindDef
|
||||
List<PawnKindDef> spawn_kind_def_list = new List<PawnKindDef>();
|
||||
spawn_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => x.race == spawn_kind_def.race && !x.defName.Contains("Nymph")));
|
||||
//no other PawnKindDef found try mother
|
||||
if (spawn_kind_def_list.NullOrEmpty())
|
||||
spawn_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => x.race == motherKindDef.race && !x.defName.Contains("Nymph")));
|
||||
//no other PawnKindDef found try father
|
||||
if (spawn_kind_def_list.NullOrEmpty() && father != null)
|
||||
spawn_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => x.race == fatherKindDef.race && !x.defName.Contains("Nymph")));
|
||||
//no other PawnKindDef found fallback to generic colonist
|
||||
if (spawn_kind_def_list.NullOrEmpty())
|
||||
spawn_kind_def = PawnKindDefOf.Colonist;
|
||||
|
||||
if (!spawn_kind_def_list.NullOrEmpty()) spawn_kind_def = spawn_kind_def_list.RandomElement();
|
||||
}
|
||||
|
||||
return spawn_kind_def;
|
||||
|
||||
}
|
||||
|
||||
public PawnKindDef GetHybrid(Pawn first, Pawn second)
|
||||
{
|
||||
PawnKindDef res = null;
|
||||
Pawn opposite = second;
|
||||
HybridInformations info = null;
|
||||
|
||||
|
||||
if (!Configurations.HybridOverride.NullOrEmpty())
|
||||
{
|
||||
info = Configurations.HybridOverride.FirstOrDefault(x => x.DefName == first.def?.defName && (x.hybridExtension?.Exists(y => y.DefName == second.def?.defName) ?? false));
|
||||
if (info == null)
|
||||
{
|
||||
info = Configurations.HybridOverride.FirstOrDefault(x => x.DefName == second.def?.defName && (x.hybridExtension?.Exists(y => y.DefName == first.def?.defName) ?? false));
|
||||
opposite = first;
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
res = info.GetHybridWith(opposite.def.defName) ?? null;
|
||||
}
|
||||
if (res != null) return res;
|
||||
|
||||
|
||||
PawnDNAModExtension dna;
|
||||
dna = first.def.GetModExtension<PawnDNAModExtension>();
|
||||
if (dna != null)
|
||||
{
|
||||
res = dna.GetHybridWith(second.def.defName) ?? null;
|
||||
}
|
||||
else
|
||||
{
|
||||
dna = second.def.GetModExtension<PawnDNAModExtension>();
|
||||
if (dna != null)
|
||||
{
|
||||
res = dna.GetHybridWith(first.def.defName) ?? null;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy from RJW
|
||||
/// </summary>
|
||||
|
|
300
1.4/source/RJW_Menstruation/RJW_Menstruation/PregnancyCommon.cs
Normal file
300
1.4/source/RJW_Menstruation/RJW_Menstruation/PregnancyCommon.cs
Normal file
|
@ -0,0 +1,300 @@
|
|||
using RimWorld;
|
||||
using rjw;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Verse;
|
||||
|
||||
namespace RJW_Menstruation
|
||||
{
|
||||
public static class PregnancyCommon
|
||||
{
|
||||
private static readonly MethodInfo TryGetInheritedXenotype = typeof(PregnancyUtility).GetMethod("TryGetInheritedXenotype", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(Pawn), typeof(Pawn), typeof(XenotypeDef).MakeByRefType() }, null);
|
||||
private static readonly MethodInfo ShouldByHybrid = typeof(PregnancyUtility).GetMethod("ShouldByHybrid", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(Pawn), typeof(Pawn) }, null);
|
||||
|
||||
public static string GetBabyInfo(IEnumerable<Pawn> babies)
|
||||
{
|
||||
if (babies == null || !babies.Any()) return "Null";
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
IEnumerable<Pawn> babiesdistinct = babies.Distinct(new RaceComparer());
|
||||
int iteration = 0;
|
||||
foreach (Pawn baby in babiesdistinct)
|
||||
{
|
||||
int num = babies.Where(x => x.def.Equals(baby.def)).Count();
|
||||
if (iteration > 0) res.Append(", ");
|
||||
res.AppendFormat("{0} {1}", num, baby.def.label);
|
||||
iteration++;
|
||||
}
|
||||
res.AppendFormat(" {0}", Translations.Dialog_WombInfo02);
|
||||
return res.ToString();
|
||||
}
|
||||
|
||||
public static string GetFatherInfo(IEnumerable<Pawn> babies, Pawn mother, bool is_parent_known)
|
||||
{
|
||||
if (babies == null || !babies.Any()) return "Null";
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
res.AppendFormat("{0}: ", Translations.Dialog_WombInfo03);
|
||||
|
||||
if (!is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All)
|
||||
return res.Append(Translations.Dialog_FatherUnknown).ToString();
|
||||
|
||||
IEnumerable<Pawn> babiesdistinct = babies.Distinct(new FatherComparer(mother));
|
||||
int iteration = 0;
|
||||
foreach (Pawn baby in babiesdistinct)
|
||||
{
|
||||
if (iteration > 0) res.Append(", ");
|
||||
res.Append(Utility.GetFather(baby, mother)?.LabelShort ?? Translations.Dialog_FatherUnknown);
|
||||
iteration++;
|
||||
}
|
||||
return res.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decide pawnkind from mother and father <para/>
|
||||
/// Come from RJW
|
||||
/// </summary>
|
||||
/// <param name="mother"></param>
|
||||
/// <param name="father"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static PawnKindDef BabyPawnKindDecider(Pawn mother, Pawn father)
|
||||
{
|
||||
PawnKindDef motherKindDef = Utility.GetRacesPawnKind(mother);
|
||||
PawnKindDef fatherKindDef = Utility.GetRacesPawnKind(father);
|
||||
|
||||
PawnKindDef spawn_kind_def = motherKindDef;
|
||||
|
||||
int flag = 0;
|
||||
if (xxx.is_human(mother)) flag += 2;
|
||||
if (xxx.is_human(father)) flag += 1;
|
||||
//Mother - Father = Flag
|
||||
//Human - Human = 3
|
||||
//Human - Animal = 2
|
||||
//Animal - Human = 1
|
||||
//Animal - Animal = 0
|
||||
|
||||
switch (flag)
|
||||
{
|
||||
case 3:
|
||||
if (!Rand.Chance(RJWPregnancySettings.humanlike_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
case 2:
|
||||
if (RJWPregnancySettings.bestiality_DNA_inheritance == 0f) spawn_kind_def = fatherKindDef;
|
||||
else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
case 1:
|
||||
if (RJWPregnancySettings.bestiality_DNA_inheritance == 1f) spawn_kind_def = fatherKindDef;
|
||||
else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
case 0:
|
||||
if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef;
|
||||
break;
|
||||
}
|
||||
|
||||
bool IsAndroidmother = AndroidsCompatibility.IsAndroid(mother);
|
||||
bool IsAndroidfather = AndroidsCompatibility.IsAndroid(father);
|
||||
if (IsAndroidmother && !IsAndroidfather)
|
||||
{
|
||||
spawn_kind_def = fatherKindDef;
|
||||
}
|
||||
else if (!IsAndroidmother && IsAndroidfather)
|
||||
{
|
||||
spawn_kind_def = motherKindDef;
|
||||
}
|
||||
|
||||
string MotherRaceName = "";
|
||||
string FatherRaceName = "";
|
||||
MotherRaceName = motherKindDef?.race?.defName;
|
||||
PawnKindDef non_hybrid_kind_def = spawn_kind_def;
|
||||
if (father != null)
|
||||
FatherRaceName = fatherKindDef?.race?.defName;
|
||||
|
||||
|
||||
if (FatherRaceName != "" && Configurations.UseHybridExtention)
|
||||
{
|
||||
spawn_kind_def = GetHybrid(father, mother);
|
||||
//Log.Message("pawnkind: " + spawn_kind_def?.defName);
|
||||
}
|
||||
|
||||
if (MotherRaceName != FatherRaceName && FatherRaceName != "")
|
||||
{
|
||||
if (!Configurations.UseHybridExtention || spawn_kind_def == null)
|
||||
{
|
||||
spawn_kind_def = non_hybrid_kind_def;
|
||||
IEnumerable<RaceGroupDef> groups = DefDatabase<RaceGroupDef>.AllDefs.Where(x => !(x.hybridRaceParents.NullOrEmpty() || x.hybridChildKindDef.NullOrEmpty()));
|
||||
|
||||
|
||||
//ModLog.Message(" found custom RaceGroupDefs " + groups.Count());
|
||||
foreach (RaceGroupDef t in groups)
|
||||
{
|
||||
if ((t.hybridRaceParents.Contains(MotherRaceName) && t.hybridRaceParents.Contains(FatherRaceName))
|
||||
|| (t.hybridRaceParents.Contains("Any") && (t.hybridRaceParents.Contains(MotherRaceName) || t.hybridRaceParents.Contains(FatherRaceName))))
|
||||
{
|
||||
//ModLog.Message(" has hybridRaceParents");
|
||||
if (t.hybridChildKindDef.Contains("MotherKindDef"))
|
||||
spawn_kind_def = motherKindDef;
|
||||
else if (t.hybridChildKindDef.Contains("FatherKindDef") && father != null)
|
||||
spawn_kind_def = fatherKindDef;
|
||||
else
|
||||
{
|
||||
//ModLog.Message(" trying hybridChildKindDef " + t.defName);
|
||||
List<PawnKindDef> child_kind_def_list = new List<PawnKindDef>();
|
||||
child_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => t.hybridChildKindDef.Contains(x.defName)));
|
||||
|
||||
//ModLog.Message(" found custom hybridChildKindDefs " + t.hybridChildKindDef.Count);
|
||||
if (!child_kind_def_list.NullOrEmpty())
|
||||
spawn_kind_def = child_kind_def_list.RandomElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (!Configurations.UseHybridExtention || spawn_kind_def == null)
|
||||
{
|
||||
spawn_kind_def = mother.RaceProps?.AnyPawnKind ?? motherKindDef;
|
||||
}
|
||||
|
||||
if (spawn_kind_def.defName.Contains("Nymph"))
|
||||
{
|
||||
//child is nymph, try to find other PawnKindDef
|
||||
List<PawnKindDef> spawn_kind_def_list = new List<PawnKindDef>();
|
||||
spawn_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => x.race == spawn_kind_def.race && !x.defName.Contains("Nymph")));
|
||||
//no other PawnKindDef found try mother
|
||||
if (spawn_kind_def_list.NullOrEmpty())
|
||||
spawn_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => x.race == motherKindDef.race && !x.defName.Contains("Nymph")));
|
||||
//no other PawnKindDef found try father
|
||||
if (spawn_kind_def_list.NullOrEmpty() && father != null)
|
||||
spawn_kind_def_list.AddRange(DefDatabase<PawnKindDef>.AllDefs.Where(x => x.race == fatherKindDef.race && !x.defName.Contains("Nymph")));
|
||||
//no other PawnKindDef found fallback to generic colonist
|
||||
if (spawn_kind_def_list.NullOrEmpty())
|
||||
spawn_kind_def = PawnKindDefOf.Colonist;
|
||||
|
||||
if (!spawn_kind_def_list.NullOrEmpty()) spawn_kind_def = spawn_kind_def_list.RandomElement();
|
||||
}
|
||||
|
||||
return spawn_kind_def;
|
||||
|
||||
}
|
||||
|
||||
public static void SetupBabyXenotype(Pawn mother, Pawn father, Pawn baby)
|
||||
{
|
||||
if (baby.genes == null || !ModsConfig.BiotechActive) return;
|
||||
|
||||
if (GeneUtility.SameHeritableXenotype(mother, father) && mother.genes.UniqueXenotype)
|
||||
{
|
||||
baby.genes.xenotypeName = mother.genes.xenotypeName;
|
||||
baby.genes.iconDef = mother.genes.iconDef;
|
||||
}
|
||||
|
||||
object[] args = new object[] { mother, father, null };
|
||||
if ((bool)TryGetInheritedXenotype.Invoke(null, args))
|
||||
{
|
||||
baby.genes.SetXenotypeDirect((XenotypeDef)args[2]);
|
||||
}
|
||||
else if ((bool)ShouldByHybrid.Invoke(null, new object[] { mother, father }))
|
||||
{
|
||||
baby.genes.hybrid = true;
|
||||
baby.genes.xenotypeName = "Hybrid".Translate();
|
||||
}
|
||||
}
|
||||
|
||||
public static PawnKindDef GetHybrid(Pawn first, Pawn second)
|
||||
{
|
||||
PawnKindDef res = null;
|
||||
Pawn opposite = second;
|
||||
HybridInformations info = null;
|
||||
|
||||
|
||||
if (!Configurations.HybridOverride.NullOrEmpty())
|
||||
{
|
||||
info = Configurations.HybridOverride.FirstOrDefault(x => x.DefName == first.def?.defName && (x.hybridExtension?.Exists(y => y.DefName == second.def?.defName) ?? false));
|
||||
if (info == null)
|
||||
{
|
||||
info = Configurations.HybridOverride.FirstOrDefault(x => x.DefName == second.def?.defName && (x.hybridExtension?.Exists(y => y.DefName == first.def?.defName) ?? false));
|
||||
opposite = first;
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
res = info.GetHybridWith(opposite.def.defName) ?? null;
|
||||
}
|
||||
if (res != null) return res;
|
||||
|
||||
|
||||
PawnDNAModExtension dna;
|
||||
dna = first.def.GetModExtension<PawnDNAModExtension>();
|
||||
if (dna != null)
|
||||
{
|
||||
res = dna.GetHybridWith(second.def.defName) ?? null;
|
||||
}
|
||||
else
|
||||
{
|
||||
dna = second.def.GetModExtension<PawnDNAModExtension>();
|
||||
if (dna != null)
|
||||
{
|
||||
res = dna.GetHybridWith(first.def.defName) ?? null;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static void CopyBodyPartProperties(Hediff part, Hediff originalPart)
|
||||
{
|
||||
CompHediffBodyPart comp = part.TryGetComp<CompHediffBodyPart>();
|
||||
CompHediffBodyPart originalComp = originalPart.TryGetComp<CompHediffBodyPart>();
|
||||
|
||||
if (comp != null && originalComp != null)
|
||||
{
|
||||
// the string properties should be the same between both pawns anyways, besides the name of the owner
|
||||
part.Severity = originalPart.Severity;
|
||||
comp.SizeBase = originalComp.SizeBase;
|
||||
comp.SizeOwner = originalComp.SizeOwner;
|
||||
comp.EffSize = originalComp.EffSize;
|
||||
comp.FluidAmmount = originalComp.FluidAmmount;
|
||||
comp.FluidModifier = originalComp.FluidModifier;
|
||||
}
|
||||
|
||||
HediffComp_Menstruation originalMenstruationComp = originalPart.GetMenstruationCompFromVagina();
|
||||
if (originalMenstruationComp != null)
|
||||
{
|
||||
part.GetMenstruationCompFromVagina()?.CopyCycleProperties(originalMenstruationComp);
|
||||
}
|
||||
HediffComp_Breast originalBreastComp = originalPart.GetBreastComp();
|
||||
if (originalBreastComp != null)
|
||||
{
|
||||
part.GetBreastComp()?.CopyBreastProperties(originalBreastComp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyBodyPartRecord(Pawn baby, Pawn original, BodyPartRecord babyBPR, BodyPartRecord originalBPR)
|
||||
{
|
||||
if (babyBPR == null || originalBPR == null) return;
|
||||
|
||||
Hediff_BasePregnancy.RemoveBabyParts(baby, Genital_Helper.get_PartsHediffList(baby, babyBPR));
|
||||
foreach (Hediff originalPart in Genital_Helper.get_PartsHediffList(original, originalBPR))
|
||||
{
|
||||
Hediff part = SexPartAdder.MakePart(originalPart.def, baby, babyBPR);
|
||||
CopyBodyPartProperties(part, originalPart);
|
||||
baby.health.AddHediff(part, babyBPR);
|
||||
}
|
||||
}
|
||||
|
||||
// Baby is the sibling to be changed, original is the first of the set and the one to copy to the rest.
|
||||
public static void ProcessIdenticalSibling(Pawn baby, Pawn original)
|
||||
{
|
||||
// They'll be the same pawnkind, which lets us make a lot of useful assumptions
|
||||
// However, some RNG might still be involved in genital generation (e.g. futas), so the easiest method is to clear out and re-generate
|
||||
// A bit wasteful since Hediff_BasePregnancy.PostBirth already redid the genitals
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_genitalsBPR(baby), Genital_Helper.get_genitalsBPR(original));
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_breastsBPR(baby), Genital_Helper.get_breastsBPR(original));
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_uddersBPR(baby), Genital_Helper.get_uddersBPR(original));
|
||||
CopyBodyPartRecord(baby, original, Genital_Helper.get_anusBPR(baby), Genital_Helper.get_anusBPR(original));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -69,12 +69,14 @@
|
|||
<Compile Include="EstrusPartKindUsageRule.cs" />
|
||||
<Compile Include="HediffComps\HediffComp_InducedOvulator.cs" />
|
||||
<Compile Include="HediffComps\HediffComp_PeriodicOvulator.cs" />
|
||||
<Compile Include="HediffComps\HediffComp_PregeneratedBabies.cs" />
|
||||
<Compile Include="HediffComps\MenstruationUtility.cs" />
|
||||
<Compile Include="Hediff_Estrus.cs" />
|
||||
<Compile Include="IngestionOutcomeDoers.cs" />
|
||||
<Compile Include="Patch\Biotech_Patch.cs" />
|
||||
<Compile Include="Patch\GC_Patch.cs" />
|
||||
<Compile Include="Patch\Gizmo_Patch.cs" />
|
||||
<Compile Include="PregnancyCommon.cs" />
|
||||
<Compile Include="Recipe_Surgery.cs" />
|
||||
<Compile Include="StatParts.cs" />
|
||||
<Compile Include="UI\Dialog_HybridCustom.cs" />
|
||||
|
|
|
@ -172,8 +172,8 @@ namespace RJW_Menstruation
|
|||
Pawn fetus = comp.GetFetus();
|
||||
if (fetus != null && Utility.ShowFetusInfo())
|
||||
{
|
||||
string feinfo = m.GetBabyInfo();
|
||||
string fainfo = m.GetFatherInfo() + " ";
|
||||
string feinfo = PregnancyCommon.GetBabyInfo(m.babies);
|
||||
string fainfo = PregnancyCommon.GetFatherInfo(m.babies, m.pawn, m.is_parent_known) + " ";
|
||||
if (feinfo.Length + fainfo.Length > 45)
|
||||
{
|
||||
preginfoheight = fontheight + 2;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Manifest>
|
||||
<identifier>RJW Menstruation</identifier>
|
||||
<version>1.0.8.5</version>
|
||||
<version>1.0.8.6</version>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
<incompatibleWith />
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
Version 1.0.8.6
|
||||
- Updated Traditional Chinese translation by Hydrogen.
|
||||
- Added several menstruation-related genes.
|
||||
|
||||
Version 1.0.8.5
|
||||
- Added biosculpter recipe to restore 1 year's worth of eggs, with icon by DestinyPlayer.
|
||||
- Vaginal sex with the "avoid pregnancy" relation will (usually) pull out prevent cum from entering the womb if there's a risk of pregnancy.
|
||||
|
|
Loading…
Reference in a new issue