Compare commits

...

4 commits

Author SHA1 Message Date
Vegapnk
b5033deef6 Added Generous Donor Gene, updated some docs 2022-11-27 08:36:44 +01:00
Vegapnk
dd40ae40ee Elasticising Gene now stays elastic, does not decay 2022-11-26 21:56:44 +01:00
Vegapnk
84c0ab012e Added Elasticity Gene and Zoophile Trait Gene 2022-11-26 21:32:32 +01:00
Vegapnk
f17da08394 Added Cumflation Immunity, Rapist Trait 2022-11-26 20:09:57 +01:00
21 changed files with 332 additions and 33 deletions

2
Common/Assemblies/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*dll
!RJW-Genes.dll

Binary file not shown.

View file

@ -4,30 +4,55 @@
<!-- Note: It is very important that rjw_genes_gender has a higher priority than the other genes
That way they run in the correct order.
If the Gender Change happens after e.g. genitalia change, it will produce errors.
General Order:
1. Gender
2. Genitalia Types
3. Extra Genitalia
4. Genitalia Sizes
5. Others
-->
<GeneCategoryDef>
<defName>rjw_genes_gender</defName>
<label>Gender</label>
<displayPriorityInXenotype>20</displayPriorityInXenotype>
<displayPriorityInXenotype>21</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_genitalia</defName>
<label>Genitalia</label>
<displayPriorityInXenotype>16</displayPriorityInXenotype>
<defName>rjw_genes_genitalia_type</defName>
<label>Genitalia Types</label>
<displayPriorityInXenotype>19</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_genitalia_extras</defName>
<label>Genitalia Amounts</label>
<displayPriorityInXenotype>17</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_genitalia_size</defName>
<label>Genitalia Size / Attributes</label>
<displayPriorityInXenotype>15</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_breeding</defName>
<label>Breeding</label>
<displayPriorityInXenotype>15</displayPriorityInXenotype>
<displayPriorityInXenotype>13</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_cum</defName>
<label>Cum</label>
<displayPriorityInXenotype>14</displayPriorityInXenotype>
<displayPriorityInXenotype>12</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_damage</defName>
<label>Genital Related Damage</label>
<displayPriorityInXenotype>11</displayPriorityInXenotype>
</GeneCategoryDef>
</Defs>

View file

@ -26,7 +26,21 @@
<description>Pawns with this gene are able to fertilize eggs with any fertile penis.</description>
<iconPath>World/WorldObjects/Expanding/Mechanoids</iconPath>
<displayOrderInCategory>53</displayOrderInCategory>
<displayCategory>rjw_genes_breeding</displayCategory>
<displayCategory>rjw_genes_breeding</displayCategory>
</GeneDef>
<GeneDef>
<defName>rjw_genes_zoophile</defName>
<label>Zoophile</label>
<displayCategory>rjw_genes_breeding</displayCategory>
<description>Xenotypes with this Gene are Zoophile.</description>
<iconPath>Genes/Icons/Placeholder</iconPath>
<displayOrderInCategory>54</displayOrderInCategory>
<forcedTraits>
<li>
<def>Zoophile</def>
</li>
</forcedTraits>
</GeneDef>
</Defs>

View file

@ -58,8 +58,6 @@
</exclusionTags>
</GeneDef>
<!-- Does not Work like this (yet)-->
<!--
<GeneDef MayRequire="LustLicentia.RJWLabs">
<defName>rjw_genes_cumflation_immunity</defName>
<label>Cumflation Immunity</label>
@ -67,13 +65,19 @@
<description>This Xenotype cannot get cumflated.</description>
<iconPath>Genes/Icons/Placeholder</iconPath>
<displayOrderInCategory>537</displayOrderInCategory>
<hediffGiversCannotGive>
<li>Cumflation</li>
</hediffGiversCannotGive>
<exclusionTags>
<li>NotCumflatable</li>
</exclusionTags>
</GeneDef>
-->
<GeneDef MayRequire="LustLicentia.RJWLabs">
<defName>rjw_genes_generous_donor</defName>
<label>Generous Donor</label>
<displayCategory>rjw_genes_cum</displayCategory>
<description>When this Xenotype transfers nutrition via cumshot, the giver will not get hungry. (Licentia Configuration for Transfer Nutrition must be enabled).</description>
<iconPath>Genes/Icons/Placeholder</iconPath>
<displayOrderInCategory>538</displayOrderInCategory>
</GeneDef>
</Defs>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<GeneDef MayRequire="LustLicentia.RJWLabs">
<defName>rjw_genes_elasticity</defName>
<label>Elasticity</label>
<displayCategory>rjw_damage</displayCategory>
<description>This Xenotype cannot get stretched by huge penetrators.</description>
<iconPath>Genes/Icons/Placeholder</iconPath>
<geneClass>RJW_Genes.Gene_Elasticity</geneClass>
<displayOrderInCategory>1</displayOrderInCategory>
</GeneDef>
</Defs>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<GeneDef Name="GeneExtraGenitaliaBase" Abstract="True">
<displayCategory>rjw_genes_genitalia</displayCategory>
<displayCategory>rjw_genes_genitalia_extras</displayCategory>
</GeneDef>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<GeneDef Name="GeneGenitaliaSizeBase" Abstract="True">
<displayCategory>rjw_genes_genitalia</displayCategory>
<displayCategory>rjw_genes_genitalia_size</displayCategory>
<!--These Genes need to be loaded quite last, otherwise e.g. genitalia types will re-roll and overrule genitalia size-->
</GeneDef>

View file

@ -2,7 +2,7 @@
<Defs>
<GeneDef Name="GeneGenitalTypeBase" Abstract="True">
<displayCategory>rjw_genes_genitalia</displayCategory>
<displayCategory>rjw_genes_genitalia_type</displayCategory>
<exclusionTags>
<li>GenitalType</li>
</exclusionTags>

View file

@ -15,4 +15,17 @@
</forcedTraits>
</GeneDef>
<GeneDef>
<defName>rjw_genes_rapist</defName>
<label>Rapist</label>
<displayCategory>Reproduction</displayCategory>
<description>Xenotypes with this Gene are Rapists.</description>
<iconPath>Genes/Icons/Placeholder</iconPath>
<displayOrderInCategory>2</displayOrderInCategory>
<forcedTraits>
<li>
<def>Rapist</def>
</li>
</forcedTraits>
</GeneDef>
</Defs>

View file

@ -25,4 +25,35 @@ Error: I added all "no-XXX" genes but my pawn has genitalia on map!
Reason: If you go with Full-No-Genitals (No Penis, No Anus, No Breasts, No Vagina) then the pawn spawns without any Genitalia on the map,
however then the RJW base-logic runs the sexualizer.
**Workaround**: Have atleast 1 genitalia enabled with Genes, I recommend the anus.
**Workaround**: Have atleast 1 genitalia enabled with Genes, I recommend the anus.
## Log Pops up for Xenotypes with Female/Male Only Gene
Error:
When using a Xenotype with the Female only gene, upon refresh it can open the log with the following (red) statement:
```
[RJW] ChangeSex error (PAWNNAME) faction (FACTION). Probably tried to change sex at world gen for royalty implant, skipping
UnityEngine.StackTraceUtility:ExtractStackTrace ()
Verse.Log:Error (string)
rjw.ModLog:Error (string)
rjw.GenderHelper:ChangeSex (Verse.Pawn,rjw.GenderHelper/Sex,rjw.GenderHelper/Sex)
rjw.GenderHelper:ChangeSex (Verse.Pawn,System.Action)
RJW_Genes.Gene_FemaleOnly:AdjustPawnToFemale ()
RJW_Genes.Gene_FemaleOnly:PostMake ()
RimWorld.GeneMaker:MakeGene (Verse.GeneDef,Verse.Pawn)
[... some more ...]
```
Reason:
RJW covers some corner cases when the pawn is changed before creation.
Current Solution:
Ignore this. The pawns seem to have the right sex and genitalia, I cannot "catch" the exception as it is only a Log Error. I would need to do harmony patching and ... that seems to be too much.
Aimed Solution:
Patch ChangeSex to skip for pawns with the two genes producing this.

View file

@ -9,8 +9,8 @@ This is my first Mod I started from scratch so any feedback is very welcome.
- Different Genitalia Types
- Genitalia Size Scaling
- Extra Genitalia (and a Futa Attempt)
- Some Traits
- Cum-Amount Changes
- Some Traits, Cumflation Immunity, Elasticity
- Cum-Amount Changes, Transfer Nutrition
- Mech Breeding / Insect Breeding Support
See [planned things](TODOS.md) and feel free to contribute.
@ -23,5 +23,5 @@ Please consider looking at [the known bugs](./KNOWN_BUGS.md)
## Genes vs. Races
I currently don't use Genes after Biotech was introduced.
I currently don't use Races after Biotech was introduced.
One of the main motivations was to have genes being added to the xenotypes that other mods and the base game add, e.g. adding demonic penis for impids.

View file

@ -6,8 +6,10 @@ namespace RJW_Genes
[DefOf]
public static class GeneDefOf
{
public static readonly GeneCategoryDef rjw_genes_genitalia;
public static readonly GeneCategoryDef rjw_genes_genitalia_type;
public static readonly GeneCategoryDef rjw_genes_genitalia_size;
public static readonly GeneCategoryDef rjw_genes_gender;
public static readonly GeneCategoryDef rjw_genes_breeding;
// Base Genitalia Types
public static readonly GeneDef rjw_genes_human_genitalia;
@ -53,14 +55,20 @@ namespace RJW_Genes
public static readonly GeneDef rjw_genes_insectincubator;
public static readonly GeneDef rjw_genes_insectbreeder;
//Cum
// Cum
public static readonly GeneDef rjw_genes_no_cum;
public static readonly GeneDef rjw_genes_much_cum;
public static readonly GeneDef rjw_genes_very_much_cum;
[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_likes_cumflation;
//[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_cumflation_immunity; //Does currently not work like this
//Reproduction
[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_cumflation_immunity;
[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_generous_donor;
// Reproduction
public static readonly GeneDef rjw_genes_hypersexual;
public static readonly GeneDef rjw_genes_rapist;
public static readonly GeneDef rjw_genes_zoophile;
// Damage & Side Effects
[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_elasticity;
}
}

View file

@ -17,7 +17,7 @@ namespace RJW_Genes
{
if (!__result)
{
__result = GeneUtility.isInsectBreeder(pawn);
__result = GeneUtility.IsInsectBreeder(pawn);
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using rjw;
using RimWorld;
using Verse;
using LicentiaLabs;
namespace RJW_Genes
{
/// <summary>
/// Changes LicentiaLabs (if Present) to not cumflate pawns that are cumflation immune.
/// This code is exercised / loaded in the HarmonyInit.
/// Patched File: https://gitgud.io/John-the-Anabaptist/licentia-labs/-/blob/master/Source/LicentiaLabs/LicentiaLabs/Cumflation.cs
/// </summary>
///
class Patch_Cumflation
{
// This patch does not need the normal Harmony Targetting,
// as it needs to be added only on demand (See HarmonyInit.cs)
public static bool Prefix(SexProps props)
{
// Harmony Logic skips the original Method after Prefix when "false" is returned
// See https://harmony.pardeike.net/articles/execution.html
// We skip the whole Cumflation Logic when the Partner is Cumflation Immune
if (props != null && props.partner != null && GeneUtility.IsCumflationImmune(props.partner))
{
return false;
}
return true;
}
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using rjw;
using RimWorld;
using Verse;
using LicentiaLabs;
namespace RJW_Genes
{
/// <summary>
/// Changes LicentiaLabs (if Present) to alter the TransferNutrition for rjw_genes_generous_donor.
/// This code is exercised / loaded in the HarmonyInit.
/// Patched File: https://gitgud.io/John-the-Anabaptist/licentia-labs/-/blob/master/Source/LicentiaLabs/LicentiaLabs/Cumflation.cs
/// </summary>
///
class Patch_TransferNutrition
{
// This patch does not need the normal Harmony Targetting,
// as it needs to be added only on demand (See HarmonyInit.cs)
public static void Postfix(Pawn giver, Pawn receiver, float cumAmount)
{
// Design decision:
// I could have done some transpiler stuff, but that is scary and might need to be adjusted quite a lot
// Hence, I simply re-book the nutrition back to the giver in the Postfix. That should be robust and easy.
if (GeneUtility.IsGenerousDonor(giver)) {
float donatedNutrition = CumflationHelper.CalculateNutritionAmount(giver, cumAmount);
// TODO: In theory, there could be something weird happening if the donor has food less than X and the "IgnoreThermodynamics" is set on.
// Then it can happen that the donor ends up with more food than he had before cumshot, but I think that is somewhat funny given that you have ignore Thermodynamics on.
Need_Food inflatorFood = giver.needs.TryGetNeed<Need_Food>();
inflatorFood.CurLevel += donatedNutrition;
}
}
}
}

View file

@ -0,0 +1,56 @@
using LicentiaLabs;
using Verse;
namespace RJW_Genes
{
/// <summary>
/// This Gene adds Licentia-Labs Elasticised Hediff to a Pawn.
/// Note: I had a HarmonyPatch first, similar to skipping cumflation, but the Stretching Logic is called quite a lot and for both pawns actually.
/// Hence, I think choosing the Elasticiced Hediff was good as then everything is covered by "Licentia-Logic".
/// </summary>
public class Gene_Elasticity : Gene
{
private int ticksToReset = RESET_INTERVAL;
private const int RESET_INTERVAL = 60000; // 60k should be 1 day
public override void PostAdd()
{
base.PostAdd();
// Doing it like this will add the hediff with a severity of ~0.5, but it will decay.
// Hence we check with the Ticks to update.
this.pawn.health.AddHediff(Licentia.HediffDefs.Elasticised);
ResetSeverity();
}
public override void Tick()
{
base.Tick();
--this.ticksToReset;
if (this.ticksToReset > 0)
return;
this.ticksToReset = RESET_INTERVAL;
ResetSeverity();
}
public override void PostRemove()
{
Hediff candidate = pawn.health.hediffSet.GetFirstHediffOfDef(Licentia.HediffDefs.Elasticised);
if (candidate != null)
{
pawn.health.RemoveHediff(candidate);
}
base.PostRemove();
}
private void ResetSeverity(float severity = 0.7f)
{
Hediff candidate = pawn.health.hediffSet.GetFirstHediffOfDef(Licentia.HediffDefs.Elasticised);
if (candidate != null)
{
candidate.Severity = severity;
}
}
}
}

View file

@ -1,4 +1,5 @@
using Verse;
using System;
using Verse;
namespace RJW_Genes
{
@ -22,7 +23,7 @@ namespace RJW_Genes
return pawn.genes.HasGene(GeneDefOf.rjw_genes_insectincubator);
}
public static bool isInsectBreeder(Pawn pawn)
public static bool IsInsectBreeder(Pawn pawn)
{
if (pawn.genes == null)
{
@ -40,5 +41,31 @@ namespace RJW_Genes
}
return MaxEggSize;
}
internal static bool IsElastic(Pawn pawn)
{
if (pawn.genes == null)
{
return false;
}
return pawn.genes.HasGene(GeneDefOf.rjw_genes_elasticity);
}
public static bool IsCumflationImmune(Pawn pawn)
{
if (pawn.genes == null)
{
return false;
}
return pawn.genes.HasGene(GeneDefOf.rjw_genes_cumflation_immunity);
}
public static bool IsGenerousDonor(Pawn pawn)
{
if (pawn.genes == null)
{
return false;
}
return pawn.genes.HasGene(GeneDefOf.rjw_genes_generous_donor);
}
}
}

View file

@ -1,6 +1,6 @@
using Verse;
using HarmonyLib;
using System;
namespace RJW_Genes
{
@ -11,6 +11,28 @@ namespace RJW_Genes
{
Harmony harmony = new Harmony("rjw_genes");
harmony.PatchAll();
// 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)
try
{
((Action)(() =>
{
if (ModsConfig.IsActive("LustLicentia.RJWLabs"))
{
// Gene: Cumflation Immunity [Prefix Patch]
harmony.Patch(AccessTools.Method(typeof(LicentiaLabs.CumflationHelper), nameof(LicentiaLabs.CumflationHelper.Cumflation)),
prefix: new HarmonyMethod(typeof(Patch_Cumflation), nameof(Patch_Cumflation.Prefix)));
// Gene: Generous Donor [Postfix Patch]
harmony.Patch(AccessTools.Method(typeof(LicentiaLabs.CumflationHelper), nameof(LicentiaLabs.CumflationHelper.TransferNutrition)),
postfix: new HarmonyMethod(typeof(Patch_TransferNutrition), nameof(Patch_TransferNutrition.Postfix)));
}
}))();
}
catch (TypeLoadException ex) {
// To be expected for people without Licentia Labs
}
}
}
}

View file

@ -29,6 +29,10 @@
<HintPath>..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="LicentiaLabs">
<HintPath>..\..\licentia-labs\Assemblies\LicentiaLabs.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RJW">
<HintPath>..\..\rjw\1.4\Assemblies\RJW.dll</HintPath>
<Private>False</Private>
@ -60,6 +64,9 @@
<Compile Include="Genes\Cum\Gene_VeryMuchCum.cs" />
<Compile Include="Genes\Cum\Gene_MuchCum.cs" />
<Compile Include="Genes\Cum\Gene_NoCum.cs" />
<Compile Include="Genes\Cum\Patch_TransferNutrition.cs" />
<Compile Include="Genes\Damage\Gene_Elasticity.cs" />
<Compile Include="Genes\Cum\Patch_Cumflation.cs" />
<Compile Include="Genes\ExtraGenitalia\Gene_ExtraBreasts.cs" />
<Compile Include="Genes\ExtraGenitalia\Gene_ExtraAnus.cs" />
<Compile Include="Genes\ExtraGenitalia\Gene_Futa.cs" />

View file

@ -8,10 +8,6 @@ So any help is very appreciated, even if it is just pointing me to existing simi
**Sanguophage like Cumwhores** adding Hemogen and refilling it by getting semen.
Showstopper here is the amount of code required, and that I need to understand a bit better of harmony to run the AfterSexUtility and modulate SexChances.
**Immunity to Soreness / Ignoring Cumflation Mali**
**LicentiaLabs TransferNutrition _Generous Donor_** pawns that get head do not loose nutrition or only part of what they fire.
**Adjustable Cock-Size** like e.g. artificial genitalia have
## Animal Gene Inheritance