update and integration of lewdbiotech

This commit is contained in:
Jaaldabaoth 2024-05-28 21:40:07 +02:00
parent 2b39105fe0
commit 25614f42ae
29 changed files with 892 additions and 32 deletions

View file

@ -0,0 +1,24 @@

using Verse;
namespace RJW_Genes
{
class LaborState
{
public Pawn pawn;
public int birthTotal = 0;
public int birthCount = 1;
public bool hasOvaryAgitator = false;
public bool hasBioscaffold = false;
public LaborState(Pawn pawn, int birthTotal)
{
this.pawn = pawn;
this.birthTotal = birthTotal;
this.birthCount = 0;
this.hasOvaryAgitator = pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator"));
this.hasBioscaffold = pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator"));
}
}
}

View file

@ -0,0 +1,35 @@
using Verse;
namespace RJW_Genes
{
public static class RJW_GenesLogger
{
public static void Message(string message)
{
Log.Message("[INFO][RJW_Genes] - " + message);
}
public static void Warning(string message)
{
Log.Message("[WARN][RJW_Genes] - " + message);
}
public static void Error(string message)
{
Log.Message("[ ERR][RJW_Genes] - " + message);
}
public static void MessageGroupHead(string message)
{
Log.Message("[INFO][RJW_Genes]╦═ " + message);
}
public static void MessageGroupBody(string message)
{
Log.Message("[INFO][RJW_Genes]╠═══ " + message);
}
public static void MessageGroupFoot(string message)
{
Log.Message("[INFO][RJW_Genes]╚═══ " + message);
}
}
}

View file

@ -8,7 +8,7 @@ using RimWorld;
using Verse;
using rjw;
namespace RJW_BGS
namespace RJW_Genes
{
[HarmonyPatch(typeof(ParentRelationUtility))]
public class PatchGetParents

View file

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using RimWorld;
using Verse;
using rjw;
using LewdBiotech;
namespace RJW_Genes
{
public class PatchImplants
{
public static readonly ThoughtDef regretsStealingLovin = DefDatabase<ThoughtDef>.GetNamed("RegretsStealingLovin");
public static readonly ThoughtDef stoleSomeLovin = DefDatabase<ThoughtDef>.GetNamed("StoleSomeLovin");
public static readonly ThoughtDef bloodlustStoleSomeLovin = DefDatabase<ThoughtDef>.GetNamed("BloodlustStoleSomeLovin");
public static readonly TraitDef rapist = DefDatabase<TraitDef>.GetNamed("Rapist");
public static readonly TraitDef sadist = DefDatabase<TraitDef>.GetNamed("rjw_genes_sadist");
static Dictionary<string, LaborState> laborStateMap = new Dictionary<string, LaborState>();
static public void would_rape_PostFix(ref bool __result, Pawn rapist)
{
if (rapist.health.hediffSet.HasHediff(HediffDef.Named("LimbicStimulator")))
{
if (LBTSettings.devMode)
{
RJW_GenesLogger.MessageGroupHead("Found LimbicStimulator hediff during xxx.would_rape check");
RJW_GenesLogger.MessageGroupBody("Pawn: " + rapist.NameShortColored + " (" + rapist.ThingID + ")");
RJW_GenesLogger.MessageGroupBody("__result (Before roll): " + __result);
}
__result = Rand.Chance(0.95f);
if (LBTSettings.devMode)
{
RJW_GenesLogger.MessageGroupFoot("__result (After roll): " + __result);
}
}
}
static public void is_rapist_PostFix(ref bool __result, Pawn pawn)
{
if (pawn.health.hediffSet.HasHediff(HediffDef.Named("LimbicStimulator")))
{
if (LBTSettings.devMode)
{
RJW_GenesLogger.Message("Found LimbicStimulator hediff during xxx.is_rapist check for " + pawn.NameShortColored + " (" + pawn.ThingID + ")" + " with __result = " + __result + " - forcing to true");
__result = true;
}
}
}
static public void think_about_sex_Rapist_PostFix(ref ThoughtDef __result, Pawn pawn)
{
if (LBTSettings.regretStealingLovinThoughtDisabled) return;
if (pawn.health.hediffSet.HasHediff(HediffDef.Named("LimbicStimulator")) && (__result == stoleSomeLovin || __result == bloodlustStoleSomeLovin) && !pawn.story.traits.HasTrait(rapist) && !pawn.story.traits.HasTrait(sadist))
{
__result = regretsStealingLovin;
}
}
public static void MultiplyPregnancy(ref float __result, Pawn pawn)
{
if (pawn != null && pawn.health.hediffSet.HasHediff(HediffDef.Named("Bioscaffold")))
{
__result *= 2f;
}
}
}
}

View file

@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using RimWorld;
using Verse;
using rjw;
using LewdBiotech;
namespace RJW_Genes
{
public class PatchLitteredBirth
{
static Dictionary<string, LaborState> laborStateMap = new Dictionary<string, LaborState>();
public static void Hediff_Labor_PostRemovedPostFix(ref Hediff_Labor __instance)
{
bool randomTwinsRoll;
int totalBirths;
bool laborStateIsNull = !laborStateMap.ContainsKey(__instance.pawn.ThingID);
bool hasLitteredBirthsGene = __instance.pawn.genes.HasActiveGene(GeneDefOf.LitteredBirths);
// we'll never do additional processing if this is the guaranteed last birth (eg birth #4)
if (!laborStateIsNull && laborStateMap.TryGetValue(__instance.pawn.ThingID).birthCount == 4)
{
return;
}
// For now, littered birth overrides ovary agitator and twin calculations, so if a LaborState already exists
// with littered births gene, move on
if (!laborStateIsNull && hasLitteredBirthsGene)
{
if (LBTSettings.devMode)
{
RJW_GenesLogger.MessageGroupHead("Found active LaborState and LitteredBirths gene - skipping additional Hediff_Labor_PostRemovedPostFix work");
RJW_GenesLogger.MessageGroupBody("Pawn: " + __instance.pawn.NameShortColored + " (" + __instance.pawn.ThingID + ")");
RJW_GenesLogger.MessageGroupFoot("birthCount: " + laborStateMap.TryGetValue(__instance.pawn.ThingID).birthCount);
}
return;
}
// Make a new LaborState for the null case with littered births
if (laborStateIsNull && hasLitteredBirthsGene)
{
RJW_GenesLogger.Message("Found littered births gene");
int litteredBirthsTotalRoll = Rand.RangeInclusive(2, 4);
laborStateMap.SetOrAdd(__instance.pawn.ThingID, new LaborState(__instance.pawn, litteredBirthsTotalRoll));
return;
}
// Finally, regardless of littered births gene, we only want new state creation on
// pawns that don't already have state, so return if state is !null (STATE SHOULD ALWAYS BE CLEANED IN LABORPUSHING POSTFIX)
if (!laborStateIsNull)
{
if (LBTSettings.devMode)
{
RJW_GenesLogger.Warning("Labor state for pawn " + __instance.pawn.NameShortColored + " (" + __instance.pawn.ThingID + ") is not null despite all checks passing for determining first instance of Hediff_Labor - this warning should never occur, and may indicate a bug in Hediff_LaborPushing of lingering labor state from a previous pregnancy");
}
return;
}
// For everything else, we do random twin and OvaryAgitator handling
// -------
// If we fail a base chance twins roll, return without any additional processing and proceed with vanilla childbirth
// Notes on rolls:
// -> Chance without OvaryAgitator to have twins: 1%
// -> Chance with OvaryAgitator to have twins: Guaranteed
// ---> Chance with OvaryAgitator to have triplets (MUST HAVE SUCCEEDED TWINS ROLL): 50%
// ---> Chance with OvaryAgitator to have quadruplets (MUST HAVE SUCCEEDED TRIPLETS ROLL): 10%
// -> Chance with Littered Births gene: random between 2 and 4 (inclusive)
randomTwinsRoll = Rand.Chance(0.01f);
bool hasAgitator = __instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator"));
if (!randomTwinsRoll && !hasAgitator)
{
// We failed rolls, and we don't have an agitator - no additional processing, do vanilla single baby birth
if (LBTSettings.devMode)
{
RJW_GenesLogger.MessageGroupHead("Inside Hediff_Labor_PostRemovedPostFix random twins check fail");
RJW_GenesLogger.MessageGroupBody("Pawn: " + __instance.pawn.NameShortColored);
RJW_GenesLogger.MessageGroupBody("Random twins roll outcome: " + randomTwinsRoll);
RJW_GenesLogger.MessageGroupFoot("Has OvaryAgitator: " + hasAgitator);
}
return;
}
// Beyond this point, we can assume the pawn has an agitator
totalBirths = 2;
bool agitatorTriplets = Rand.Chance(0.5f);
bool agitatorQuadruplets = Rand.Chance(0.1f);
if (hasAgitator)
{
if (agitatorTriplets) totalBirths = 3;
if (agitatorTriplets && agitatorQuadruplets) totalBirths = 4;
}
// Set new LaborState
laborStateMap.Add(__instance.pawn.ThingID, new LaborState(__instance.pawn, totalBirths));
}
public static void Hediff_LaborPushing_PostRemovedPostFix(ref Hediff_LaborPushing __instance)
{
bool hasAgitator = __instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator"));
bool hasLitteredBirthsGene = __instance.pawn.genes.HasActiveGene(GeneDefOf.LitteredBirths);
bool laborStateIsNull = !laborStateMap.ContainsKey(__instance.pawn.ThingID);
LaborState currentLaborState;
laborStateMap.TryGetValue(__instance.pawn.ThingID, out currentLaborState);
if (laborStateIsNull)
{
if (__instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("Bioscaffold")))
{
__instance.pawn.health.RemoveHediff(__instance.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Bioscaffold));
}
return;
}
if (currentLaborState.birthTotal == currentLaborState.birthCount)
{
laborStateMap.Remove(__instance.pawn.ThingID);
if (__instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("Bioscaffold")))
{
__instance.pawn.health.RemoveHediff(__instance.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Bioscaffold));
}
return;
}
((Hediff_Labor)__instance.pawn.health.AddHediff(RimWorld.HediffDefOf.PregnancyLabor)).SetParents(__instance.pawn, __instance.Father, PregnancyUtility.GetInheritedGeneSet(__instance.Father, __instance.pawn));
currentLaborState.birthCount++;
if (!hasAgitator && !hasLitteredBirthsGene)
{
if (LBTSettings.devMode)
{
RJW_GenesLogger.Message("Pawn " + __instance.pawn.NameShortColored + " (" + __instance.pawn.ThingID + ") is having random twins");
}
Find.LetterStack.ReceiveLetter("Twins!", __instance.pawn.NameShortColored + " is still in labor and is having twins!\n\nBe sure to gather your doctor and additional friends and family to ensure the other baby is also born healthy!", LetterDefOf.AnotherBaby, __instance.pawn);
return;
}
Find.LetterStack.ReceiveLetter("Another baby!", __instance.pawn.NameShortColored + " is still in labor and is having another baby!\n\nBe sure to gather your doctor and additional friends and family to ensure the next baby is also born healthy!", LetterDefOf.AnotherBaby, __instance.pawn);
}
}
}

View file

@ -10,7 +10,7 @@ using rjw;
using RJW_Genes;
using rjw.Modules.Interactions.Enums;
namespace RJW_BGS
namespace RJW_Genes
{
[HarmonyPatch(typeof(PregnancyHelper))]
public class PatchPregnancyHelper
@ -45,39 +45,39 @@ namespace RJW_BGS
return;
}
if (!(props.sexType == xxx.rjwSextype.Anal && receiver.genes.HasActiveGene(RJW_Genes.GeneDefOf.rjw_genes_fertile_anus)))
if (!(props.sexType == xxx.rjwSextype.Anal && receiver.genes.HasActiveGene(GeneDefOf.rjw_genes_fertile_anus)))
return;
//"normal" and "beastial" pregnancy
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message(" 'normal' pregnancy checks");
if (RJWSettings.DevMode) ModLog.Message(" 'normal' pregnancy checks");
//interaction stuff if for handling futa/see who penetrates who in interaction
if (!props.isReceiver &&
interaction.DominantHasTag(GenitalTag.CanPenetrate) &&
interaction.SubmissiveHasFamily(GenitalFamily.Anus))
{
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message(" impregnate - by initiator");
if (RJWSettings.DevMode) ModLog.Message(" impregnate - by initiator");
}
else if (props.isReceiver && props.isRevese &&
interaction.DominantHasFamily(GenitalFamily.Anus) &&
interaction.SubmissiveHasTag(GenitalTag.CanPenetrate))
{
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message(" impregnate - by receiver (reverse)");
if (RJWSettings.DevMode) ModLog.Message(" impregnate - by receiver (reverse)");
}
else
{
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message(" no valid interaction tags/family");
if (RJWSettings.DevMode) ModLog.Message(" no valid interaction tags/family");
return;
}
if (!rjw.Modules.Interactions.Helpers.PartHelper.FindParts(giver, GenitalTag.CanFertilize).Any())
{
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message(xxx.get_pawnname(giver) + " has no parts to Fertilize with");
if (RJWSettings.DevMode) ModLog.Message(xxx.get_pawnname(giver) + " has no parts to Fertilize with");
return;
}
if (vasectomy != null)
{
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message("vasectomy check");
if (RJWSettings.DevMode) ModLog.Message("vasectomy check");
receiver.health.RemoveHediff(vasectomy);
}
if (CanImpregnate2(giver, receiver, props.sexType))
@ -88,7 +88,7 @@ namespace RJW_BGS
}
if (vasectomy != null)
{
if (RJWSettings.DevMode) RJW_Genes.ModLog.Message("vasectomy check");
if (RJWSettings.DevMode) ModLog.Message("vasectomy check");
receiver.health.AddHediff(vasectomy);
}
}
@ -118,16 +118,16 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" mechanoid 'pregnancy' disabled");
ModLog.Message(" mechanoid 'pregnancy' disabled");
}
return false;
}
if (sexType != xxx.rjwSextype.Vaginal && sexType != xxx.rjwSextype.DoublePenetration && !(sexType == xxx.rjwSextype.Anal && fucked.genes.HasActiveGene(RJW_Genes.GeneDefOf.rjw_genes_fertile_anus)))
if (sexType != xxx.rjwSextype.Vaginal && sexType != xxx.rjwSextype.DoublePenetration && !(sexType == xxx.rjwSextype.Anal && fucked.genes.HasActiveGene(GeneDefOf.rjw_genes_fertile_anus)))
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" sextype cannot result in pregnancy");
ModLog.Message(" sextype cannot result in pregnancy");
}
return false;
@ -136,7 +136,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(xxx.get_pawnname(fucked) + " androids cant breed/reproduce androids");
ModLog.Message(xxx.get_pawnname(fucked) + " androids cant breed/reproduce androids");
}
return false;
@ -145,7 +145,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" unsexy robot cant be pregnant");
ModLog.Message(" unsexy robot cant be pregnant");
}
return false;
@ -154,7 +154,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(xxx.get_pawnname(fucked) + " filtered race that cant be pregnant");
ModLog.Message(xxx.get_pawnname(fucked) + " filtered race that cant be pregnant");
}
return false;
@ -163,7 +163,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(xxx.get_pawnname(fucker) + " filtered race that cant impregnate");
ModLog.Message(xxx.get_pawnname(fucker) + " filtered race that cant impregnate");
}
return false;
@ -172,7 +172,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" already pregnant.");
ModLog.Message(" already pregnant.");
}
return false;
@ -183,7 +183,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(xxx.get_pawnname(fucked) + " cant get pregnant while eggs inside");
ModLog.Message(xxx.get_pawnname(fucked) + " cant get pregnant while eggs inside");
}
return false;
@ -194,7 +194,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" missing genitals for impregnation"+ Genital_Helper.has_penis_fertile(fucker, genitalsList)+" "+ Genital_Helper.has_anus(fucked, genitalsList2)+" "+ Genital_Helper.has_penis_fertile(fucked, genitalsList2)+" "+ Genital_Helper.has_anus(fucker, genitalsList));
ModLog.Message(" missing genitals for impregnation"+ Genital_Helper.has_penis_fertile(fucker, genitalsList)+" "+ Genital_Helper.has_anus(fucked, genitalsList2)+" "+ Genital_Helper.has_penis_fertile(fucked, genitalsList2)+" "+ Genital_Helper.has_anus(fucker, genitalsList));
}
return false;
}
@ -202,7 +202,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" one (or both) pawn(s) infertile");
ModLog.Message(" one (or both) pawn(s) infertile");
}
return false;
@ -211,7 +211,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" human pregnancy chance set to 0% or pregnancy disabled.");
ModLog.Message(" human pregnancy chance set to 0% or pregnancy disabled.");
}
return false;
@ -220,7 +220,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" bestiality pregnancy chance set to 0% or pregnancy disabled.");
ModLog.Message(" bestiality pregnancy chance set to 0% or pregnancy disabled.");
}
return false;
@ -229,7 +229,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" animal-animal pregnancy chance set to 0% or pregnancy disabled.");
ModLog.Message(" animal-animal pregnancy chance set to 0% or pregnancy disabled.");
}
return false;
@ -238,7 +238,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(" interspecies pregnancy disabled.");
ModLog.Message(" interspecies pregnancy disabled.");
}
return false;
@ -247,7 +247,7 @@ namespace RJW_BGS
{
if (RJWSettings.DevMode)
{
RJW_Genes.ModLog.Message(xxx.get_pawnname(fucked) + " mother.RaceProps.gestationPeriodDays is " + fucked.RaceProps.gestationPeriodDays.ToString() + " cant impregnate");
ModLog.Message(xxx.get_pawnname(fucked) + " mother.RaceProps.gestationPeriodDays is " + fucked.RaceProps.gestationPeriodDays.ToString() + " cant impregnate");
}
return false;
}