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

Binary file not shown.

View file

@ -162,5 +162,17 @@
</li>
</modExtensions>
</GeneDef>
<GeneDef>
<defName>LitteredBirths</defName>
<label>littered births</label>
<displayCategory>Reproduction</displayCategory>
<description>Female carriers of this gene birth litters instead of just one baby, with a chance of having two to four babies per pregnancy.</description>
<iconPath>Genes/Icons/Gene_LitteredBirths</iconPath>
<displayOrderInCategory>110</displayOrderInCategory>
<marketValueFactor>1.10</marketValueFactor>
<biostatMet>-2</biostatMet>
<biostatCpx>1</biostatCpx>
</GeneDef>
</Defs>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<HediffDef>
<defName>Bioscaffold</defName>
<hediffClass>HediffWithComps</hediffClass>
<label>bioscaffold</label>
<description>This woman has an bioscaffold mesh within her womb, providing an enriching environment for an unborn baby to grow more quickly.</description>
<descriptionHyperlinks>
<ThingDef>Bioscaffold</ThingDef>
</descriptionHyperlinks>
<initialSeverity>0.001</initialSeverity>
<everCurableByItem>false</everCurableByItem>
<!-- <comps>
<li Class="HediffCompProperties_Disappears">
<showRemainingTime>true</showRemainingTime>
<disappearsAfterTicks>540000</disappearsAfterTicks> <!10 Days>
</li>
</comps> -->
</HediffDef>
</Defs>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<HediffDef>
<defName>LimbicStimulator</defName>
<hediffClass>HediffWithComps</hediffClass>
<label>limbic stimulator</label>
<labelNoun>limbic stimulator</labelNoun>
<description>An installed limbic stimulator.</description>
<descriptionHyperlinks>
<ThingDef>Scrambler</ThingDef>
</descriptionHyperlinks>
<defaultLabelColor>(1.0, 0.6, 0.7)</defaultLabelColor>
<stages>
<li>
<minSeverity>0</minSeverity>
<statOffsets>
<Vulnerability>-1.0</Vulnerability>
<SexFrequency>6.0</SexFrequency>
</statOffsets>
</li>
</stages>
</HediffDef>
</Defs>

View file

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<HediffDef>
<defName>OvaryAgitator</defName>
<label>ovary agitator</label>
<description>An installed ovary agitator.</description>
<descriptionHyperlinks>
<ThingDef>OvaryAgitator</ThingDef>
</descriptionHyperlinks>
<hediffClass>HediffWithComps</hediffClass>
<initialSeverity>0.0001</initialSeverity>
<stages>
<li>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>0.50</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.1</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>0.22</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.2</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>0</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.3</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.17</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.4</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.32</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.5</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.48</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.6</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.54</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.7</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.63</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.8</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.69</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>0.9</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-0.75</offset>
</li>
</capMods>
</li>
<li>
<minSeverity>1</minSeverity>
<capMods>
<li>
<capacity>RJW_Fertility</capacity>
<offset>-100</offset>
</li>
</capMods>
</li>
</stages>
<comps>
<li Class="HediffCompProperties_SeverityPerDay">
<severityPerDay>0.0045</severityPerDay>
</li>
</comps>
</HediffDef>
</Defs>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<HediffDef>
<defName>Scrambler</defName>
<label>scrambler</label>
<labelNoun>scrambler</labelNoun>
<description>An installed scrambler.</description>
<descriptionHyperlinks>
<ThingDef>Scrambler</ThingDef>
</descriptionHyperlinks>
<defaultLabelColor>(0.9, 0.5, 1.0)</defaultLabelColor>
<stages>
<li>
<minSeverity>0</minSeverity>
<statOffsets>
<SlaveSuppressionOffset>0.40</SlaveSuppressionOffset>
<Vulnerability>3.0</Vulnerability>
</statOffsets>
<capMods>
<li>
<capacity>Consciousness</capacity>
<setMax>0.6</setMax>
</li>
<li>
<capacity>Talking</capacity>
<setMax>0.2</setMax>
</li>
</capMods>
</li>
</stages>
</HediffDef>
</Defs>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<LetterDef Name="AnotherBaby">
<defName>AnotherBaby</defName>
<color>(120, 176, 216)</color>
<flashColor>(106, 179, 231)</flashColor>
<flashInterval>40</flashInterval>
<arriveSound>LetterArrive_Good</arriveSound>
<pauseMode>MajorThreat</pauseMode>
</LetterDef>
</Defs>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<RecipeDef ParentName="SurgeryInstallImplantBase">
<defName>InstallBioscaffold</defName>
<label>install bioscaffold</label>
<description>Install a bioscaffold.</description>
<descriptionHyperlinks>
<ThingDef>Bioscaffold</ThingDef>
<HediffDef>Bioscaffold</HediffDef>
</descriptionHyperlinks>
<jobString>Installing bioscaffold.</jobString>
<ingredients>
<li>
<filter>
<thingDefs>
<li>Bioscaffold</li>
</thingDefs>
</filter>
<count>1</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>Bioscaffold</li>
</thingDefs>
</fixedIngredientFilter>
<appliedOnFixedBodyParts>
<li>Torso</li>
</appliedOnFixedBodyParts>
<addsHediff>Bioscaffold</addsHediff>
</RecipeDef>
</Defs>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<RecipeDef ParentName="SurgeryInstallImplantBase">
<defName>InstallLimbicStimulator</defName>
<label>install limbic stimulator</label>
<description>Install a limbic stimulator.</description>
<descriptionHyperlinks>
<ThingDef>LimbicStimulator</ThingDef>
<HediffDef>LimbicStimulator</HediffDef>
</descriptionHyperlinks>
<jobString>Installing limbic stimulator.</jobString>
<ingredients>
<li>
<filter>
<thingDefs>
<li>LimbicStimulator</li>
</thingDefs>
</filter>
<count>1</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>LimbicStimulator</li>
</thingDefs>
</fixedIngredientFilter>
<appliedOnFixedBodyParts>
<li>Brain</li>
</appliedOnFixedBodyParts>
<addsHediff>LimbicStimulator</addsHediff>
</RecipeDef>
</Defs>

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<RecipeDef ParentName="SurgeryInstallImplantBase">
<defName>InstallOvaryAgitator</defName>
<label>install ovary agitator</label>
<description>Install an ovary agitator.</description>
<descriptionHyperlinks>
<ThingDef>OvaryAgitator</ThingDef>
<HediffDef>OvaryAgitator</HediffDef>
</descriptionHyperlinks>
<workerClass>Recipe_InstallImplant</workerClass>
<jobString>Installing ovary agitator.</jobString>
<isViolation>true</isViolation>
<ingredients>
<li>
<filter>
<thingDefs>
<li>OvaryAgitator</li>
</thingDefs>
</filter>
<count>1</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>OvaryAgitator</li>
</thingDefs>
</fixedIngredientFilter>
<appliedOnFixedBodyParts>
<li>Torso</li>
</appliedOnFixedBodyParts>
<addsHediff>OvaryAgitator</addsHediff>
</RecipeDef>
</Defs>

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<RecipeDef ParentName="SurgeryInstallImplantBase">
<defName>InstallScrambler</defName>
<label>install scrambler</label>
<description>Install a scrambler.</description>
<descriptionHyperlinks>
<ThingDef>Scrambler</ThingDef>
<HediffDef>Scrambler</HediffDef>
</descriptionHyperlinks>
<workerClass>Recipe_InstallImplant</workerClass>
<jobString>Installing scrambler.</jobString>
<isViolation>true</isViolation>
<ingredients>
<li>
<filter>
<thingDefs>
<li>Scrambler</li>
</thingDefs>
</filter>
<count>1</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>Scrambler</li>
</thingDefs>
</fixedIngredientFilter>
<appliedOnFixedBodyParts>
<li>Brain</li>
</appliedOnFixedBodyParts>
<addsHediff>Scrambler</addsHediff>
</RecipeDef>
</Defs>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BodyPartNaturalBase">
<defName>Bioscaffold</defName>
<label>bioscaffold</label>
<description>A single-use nanite-constructed lattice of organic mesh material meant to be installed inside a woman's womb prior to pregnancy. It provides an enriching environment for an unborn baby to grow more quickly.</description>
<descriptionHyperlinks>
<RecipeDef>InstallBioscaffold</RecipeDef>
</descriptionHyperlinks>
<techLevel>Spacer</techLevel>
<tickerType>Rare</tickerType>
<drawGUIOverlay>true</drawGUIOverlay>
<stackLimit>25</stackLimit>
<healthAffectsPrice>false</healthAffectsPrice>
<statBases>
<MaxHitPoints>30</MaxHitPoints>
<MarketValue>350</MarketValue>
<Mass>0.15</Mass>
<Flammability>1.3</Flammability>
<DeteriorationRate>6</DeteriorationRate>
<WorkToMake>800</WorkToMake>
</statBases>
<comps>
<li Class="CompProperties_Rottable">
<daysToRotStart>5</daysToRotStart>
<rotDestroys>true</rotDestroys>
</li>
</comps>
<costList>
<Plasteel>5</Plasteel>
<BabyFood>10</BabyFood>
<MedicineUltratech>1</MedicineUltratech>
<ComponentSpacer>1</ComponentSpacer>
</costList>
<recipeMaker>
<workSpeedStat>DrugSynthesisSpeed</workSpeedStat>
<workSkill>Intellectual</workSkill>
<recipeUsers>
<li>DrugLab</li>
</recipeUsers>
<skillRequirements>
<Crafting>6</Crafting>
<Intellectual>4</Intellectual>
</skillRequirements>
<researchPrerequisite>FertilityProcedures</researchPrerequisite>
<bulkRecipeCount>4</bulkRecipeCount>
</recipeMaker>
<tradeTags>
<li>ExoticMisc</li>
</tradeTags>
</ThingDef>
</Defs>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BodyPartProstheticImperialBase">
<defName>LimbicStimulator</defName>
<label>limbic stimulator</label>
<description>A perpetual slow-release chemical stimulation implant that is embedded deep within the reward center of the brain, greatly increasing the need for lovin'. The need is said to become so strong that it can drive people to force themselves onto others, even if they wouldn't otherwise. Post-lovin' clarity will leave the implanted in a state of bliss, but they may also feel a sense of regret if they steal lovin' if they normally wouldn't - at least until they become used to doing it.</description>
<descriptionHyperlinks>
<RecipeDef>InstallLimbicStimulator</RecipeDef>
</descriptionHyperlinks>
<costList>
<Steel>30</Steel>
<ComponentIndustrial>4</ComponentIndustrial>
<ComponentSpacer>1</ComponentSpacer>
</costList>
<recipeMaker>
<researchPrerequisite>BrainWiring</researchPrerequisite>
</recipeMaker>
</ThingDef>
</Defs>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BodyPartBionicBase">
<defName>OvaryAgitator</defName>
<label>ovary agitator</label>
<description>A crude slaver implant used to increase the number of eggs released during ovulation, increasing the likelihood of having multiple children per pregnancy. Their use is largely limited to rimworlds lacking in cloning infrastructure as most civilized and unified worlds have outlawed them.\n\nWhile it provides an initial boost in fertility, the implant will slowly deplete the victims's ovaries over several years until they're infertile. Allies of implanted victims will be angered.</description>
<descriptionHyperlinks>
<RecipeDef>InstallOvaryAgitator</RecipeDef>
</descriptionHyperlinks>
<costList>
<Plasteel>10</Plasteel>
<MedicineIndustrial>1</MedicineIndustrial>
<ComponentIndustrial>6</ComponentIndustrial>
</costList>
<recipeMaker>
<researchPrerequisite>FertilityProcedures</researchPrerequisite>
</recipeMaker>
</ThingDef>
</Defs>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BodyPartProstheticImperialBase">
<defName>Scrambler</defName>
<label>scrambler</label>
<description>A slaver implant, made from a modified mindscrew, that can inject disorienting mind imagery directly into the visual cortex of the brain through a complex network of nanoelectrodes. Victims of scrambler implantation tend to socially withdraw to minimize additional stimulation. As a consequence of their confusion, they also become physically meek, making them easy to impose upon. Allies of implanted victims will be angered.</description>
<descriptionHyperlinks><RecipeDef>InstallScrambler</RecipeDef></descriptionHyperlinks>
<statBases>
<WorkToMake>50</WorkToMake>
</statBases>
<costList>
<Mindscrew>1</Mindscrew>
<ComponentIndustrial>1</ComponentIndustrial>
<ComponentSpacer>1</ComponentSpacer>
</costList>
<recipeMaker>
<researchPrerequisite>BrainWiring</researchPrerequisite>
</recipeMaker>
</ThingDef>
</Defs>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThoughtDef>
<defName>RegretsStealingLovin</defName>
<thoughtClass>Thought_Memory</thoughtClass>
<durationDays>1.5</durationDays>
<stackLimit>3</stackLimit>
<stackedEffectMultiplier>0.4</stackedEffectMultiplier>
<stages>
<li>
<label>regrets stealing some lovin'</label>
<description>I don't remember how or why, but I violated someone. It felt good in the moment, but it felt so wrong afterward. My cravings from my implant are just too strong!</description>
<baseMoodEffect>-5</baseMoodEffect>
</li>
</stages>
</ThoughtDef>
</Defs>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

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;
}

View file

@ -83,9 +83,10 @@ namespace RJW_Genes
public static readonly GeneDef rjw_genes_homosexual;
public static readonly GeneDef rjw_genes_bisexual;
public static readonly GeneDef rjw_genes_no_sex_need;
public static readonly GeneDef LitteredBirths;
// Damage & Side Effects
[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_elasticity;
// Damage & Side Effects
[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_elasticity;
public static readonly GeneDef rjw_genes_unbreakable;
// Special

View file

@ -3,6 +3,7 @@ using HarmonyLib;
using System;
using rjw;
using RJWLoveFeeding;
using RimWorld;
namespace RJW_Genes
{
@ -21,7 +22,29 @@ namespace RJW_Genes
{
harmony.Patch(typeof(SexUtility).GetMethod("ProcessSex"), new HarmonyMethod(typeof(LustFeeding), "Postfix", null));
}
// Non-rapist would_rape bypass for limbic stimulator
harmony.Patch(AccessTools.Method(typeof(SexAppraiser), nameof(SexAppraiser.would_rape)),
postfix: new HarmonyMethod(typeof(PatchImplants), nameof(PatchImplants.would_rape_PostFix)));
// Non-rapist is_rapist bypass for limbic stimulator
harmony.Patch(AccessTools.Method(typeof(xxx), nameof(xxx.is_rapist)),
postfix: new HarmonyMethod(typeof(PatchImplants), nameof(PatchImplants.is_rapist_PostFix)));
// Non-Rapist trait rape thoughts
harmony.Patch(AccessTools.Method(typeof(AfterSexUtility), nameof(AfterSexUtility.think_about_sex_Rapist)),
postfix: new HarmonyMethod(typeof(PatchImplants), nameof(PatchImplants.think_about_sex_Rapist_PostFix)));
// Bioscaffold double gestation speed tick
harmony.Patch(AccessTools.Method(typeof(PawnUtility), nameof(PawnUtility.BodyResourceGrowthSpeed)),
postfix: new HarmonyMethod(typeof(PatchImplants), nameof(PatchImplants.MultiplyPregnancy)));
// Hediff_Labor state capture
harmony.Patch(AccessTools.Method(typeof(Hediff_Labor), nameof(Hediff_Labor.PostRemoved)),
postfix: new HarmonyMethod(typeof(PatchLitteredBirth), nameof(PatchLitteredBirth.Hediff_Labor_PostRemovedPostFix)));
// OvaryAgitator/Gene_LitteredBirths multibirth logic
harmony.Patch(AccessTools.Method(typeof(Hediff_LaborPushing), nameof(Hediff_LaborPushing.PostRemoved)),
postfix: new HarmonyMethod(typeof(PatchLitteredBirth), nameof(PatchLitteredBirth.Hediff_LaborPushing_PostRemovedPostFix)));
// Patch Licentia, if Licentia exists
// Logic & Explanation taken from https://rimworldwiki.com/wiki/Modding_Tutorials/Compatibility_with_DLLs
// Adjusted to use ModsConfig (which makes it work, the example above does not run out of the box)

View file

@ -16,10 +16,10 @@ namespace RJW_Genes
public static readonly HediffDef rjw_genes_succubus_drained;
public static readonly HediffDef rjw_genes_orgasm_rush_hediff;
public static readonly HediffDef rjw_genes_fertilin_craving;
public static readonly HediffDef rjw_genes_evergrowth_sideeffect;
public static readonly HediffDef rjw_genes_orgasmic_mytosis_hediff;
public static readonly HediffDef rjw_genes_mytosis_shock_hediff;
public static readonly HediffDef OvaryAgitator;
public static readonly HediffDef Bioscaffold;
}
}

11
Source/LetterDefOf.cs Normal file
View file

@ -0,0 +1,11 @@
using Verse;
using RimWorld;
namespace RJW_Genes
{
[DefOf]
public static class LetterDefOf
{
public static LetterDef AnotherBaby;
}
}

View file

@ -42,10 +42,14 @@
<Compile Include="Common\Defs\DistanceExtension.cs" />
<Compile Include="Common\Defs\ModExtensionHelper.cs" />
<Compile Include="Common\Either.cs" />
<Compile Include="Common\Helpers\LaborState.cs" />
<Compile Include="Common\Helpers\RJW_GenesLogger.cs" />
<Compile Include="Common\ModLog.cs" />
<Compile Include="Common\Defs\TickIntervalExtension.cs" />
<Compile Include="Common\patches\PatchGetParents.cs" />
<Compile Include="Common\patches\PatchPregnancyHelper.cs" />
<Compile Include="Common\Patches\PatchImplants.cs" />
<Compile Include="Common\Patches\PatchLitteredBirth.cs" />
<Compile Include="Common\Patches\PatchGetParents.cs" />
<Compile Include="Common\Patches\PatchPregnancyHelper.cs" />
<Compile Include="GeneDefOf.cs" />
<Compile Include="Genes\Breeding\Gene_MechBreeder.cs" />
<Compile Include="Genes\Breeding\PatchMechBirth.cs" />
@ -139,6 +143,7 @@
<Compile Include="Genes\Special\Patches\Patch_HormonalSaliva.cs" />
<Compile Include="Genes\Special\Patches\Patch_OrgasmMytosis.cs" />
<Compile Include="Genes\Special\Thoughts\ThoughtWorker_Aphrodisiac_Pheromones_Social.cs" />
<Compile Include="LetterDefOf.cs" />
<Compile Include="Interactions\SuccubusTailjob\CompAbility_SexInteractionRequirements.cs" />
<Compile Include="Interactions\SuccubusTailjob\CompProperties_SexInteractionRequirements.cs" />
<Compile Include="Genes\RJW_Gene.cs" />
@ -152,6 +157,7 @@
<Compile Include="JobDefOf.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RJW_Genes.cs" />
<Compile Include="Settings\LBTSettings.cs" />
<Compile Include="Settings\RJW_Genes_Settings.cs" />
<Compile Include="Settings\RJW_Genes_SettingsController.cs" />
<Compile Include="ThoughtDefOf.cs" />

View file

@ -0,0 +1,54 @@
using UnityEngine;
using Verse;
// If it isn't blatantly obvious, I unabashedly ripped this settings template from RJW, minus the fact that
// I won't be (personally) supporting multiplayer, and it's all in one file - but I digress ...
namespace LewdBiotech
{
class LBTSettingsController : Mod
{
public LBTSettingsController(ModContentPack content) : base(content)
{
GetSettings<LBTSettings>();
}
public override string SettingsCategory()
{
return "LBTSettings".Translate();
}
public override void DoSettingsWindowContents(Rect inRect)
{
LBTSettings.DoWindowContents(inRect);
}
}
public class LBTSettings : ModSettings
{
// For my own sanity, all now and future settings will have a default disabled/false state (at least, that's the plan), and
// the settings name and description should reflect that (not that I'm going to add that many settings, mind you)
public static bool devMode = false;
public static bool regretStealingLovinThoughtDisabled = false;
public static void DoWindowContents(Rect inRect)
{
// Shrink the settings window a bit - don't need to be that w i d e
inRect.width = inRect.width - 400;
inRect.x = inRect.x + 200;
Listing_Standard listingStandard = new Listing_Standard();
listingStandard.Begin(inRect);
listingStandard.Gap(4f);
listingStandard.CheckboxLabeled("EnableLBTDevLogging".Translate(), ref devMode, "EnableLBTDevLoggingDesc".Translate());
listingStandard.Gap(4f);
listingStandard.CheckboxLabeled("RegretStealingLovinThoughtDisabled".Translate(), ref regretStealingLovinThoughtDisabled, "RegretStealingLovinThoughtDisabledDesc".Translate());
listingStandard.End();
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref devMode, "EnableLBTDevLogging", devMode, true);
Scribe_Values.Look(ref regretStealingLovinThoughtDisabled, "regretStealingLovinThoughtDisabled", regretStealingLovinThoughtDisabled, true);
}
}
}