From b12e9afbc09f12f134895e43af27ad297e62213f Mon Sep 17 00:00:00 2001 From: Vegapnk Date: Thu, 4 Jul 2024 16:04:51 +0200 Subject: [PATCH] Added two genes for steal and swap genes on sex --- CHANGELOG.md | 4 +- Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml | 33 ++++++++- Source/Common/Defs/ChanceExtension.cs | 15 ++++ Source/GeneDefOf.cs | 2 + .../Special/Patches/Patch_GeneticSexSwap.cs | 69 +++++++++++++++++++ .../Special/Patches/Patch_GeneticSexThief.cs | 68 ++++++++++++++++++ .../Special/Patches/Patch_HormonalSaliva.cs | 1 - Source/Rjw-Genes.csproj | 3 + 8 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 Source/Common/Defs/ChanceExtension.cs create mode 100644 Source/Genes/Special/Patches/Patch_GeneticSexSwap.cs create mode 100644 Source/Genes/Special/Patches/Patch_GeneticSexThief.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index df36886..5b63394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,7 +68,7 @@ but they are meant mostly to have infectors immune against their own diseases. **Additions:** -- Passive Gene: *Genetic Disease Immunity* - cannot get infected by any genetic diseases, and won't be affected by some other genes (see relevant genes) +- Passive Gene: Genetic Disease Immunity. cannot get infected by any genetic diseases, and won't be affected by some other genes (see relevant genes) - Disease Gene: Vulnerability. Pawn is likelier to be raped - Disease Gene: Infectious Hypersexuality - Disease Gene: Infectious Homosexuality & Bisexuality @@ -78,6 +78,8 @@ but they are meant mostly to have infectors immune against their own diseases. - Disease Gene: Size Blinded. Pawns have a higher chance for hooking up with pawns with a big cock, lower chance for small cocks. - Infector Gene: Genetic Stretcher. Pawns can infect other pawns with *Size Blinded* - Gene: Hardwired Progenity. Pawns with this get a malus on having no-children, and bonus on having a lot. +- Gene: Sexual Genetic Swap. Pawns have a chance to switch a random gene with their sexpartner. +- (Archite) Gene: Sexual Genetic Thief. Pawns have a chance to steal a gene from their sexpartner. Genetic Disease Immunity shields against this. - Pawns will have negative thoughts about pawns with more genetic diseases than themselves. **Fixes:** diff --git a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml index 189a6c8..0fe012a 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml @@ -140,7 +140,7 @@ rjw_genes_sex_tamer - + sextamer Bestiality has a chance to tame animals or advance their training. Genes/Icons/RJW_Genes_SexualTamer @@ -149,4 +149,35 @@ -1 + + rjw_genes_sexual_genetic_swap + + Carriers with this gene may switch a gene with their sex-partner. Switched Genes are always endogenes. + UI/Icons/Genes/Gene_PsychicBonding + 20 + 3 + 0 + +
  • + 0.1 +
  • +
    +
    + + + rjw_genes_sexual_genetic_thief + + Carriers with this gene may steal a gene from their sex-partner. Stolen genes are always xenogenes. + UI/Icons/Genes/Gene_PsychicBonding + 21 + 5 + -2 + 1 + +
  • + 0.2 +
  • +
    +
    + \ No newline at end of file diff --git a/Source/Common/Defs/ChanceExtension.cs b/Source/Common/Defs/ChanceExtension.cs new file mode 100644 index 0000000..ff8b260 --- /dev/null +++ b/Source/Common/Defs/ChanceExtension.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class ChanceExtension : DefModExtension + { + public float chance; + } + +} diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs index f7612cc..873df6f 100644 --- a/Source/GeneDefOf.cs +++ b/Source/GeneDefOf.cs @@ -105,6 +105,8 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_hormonal_saliva; public static readonly GeneDef rjw_genes_cocoonweaver; public static readonly GeneDef rjw_genes_sex_tamer; + public static readonly GeneDef rjw_genes_sexual_genetic_swap; + public static readonly GeneDef rjw_genes_sexual_genetic_thief; // Cosmetic public static readonly GeneDef rjw_genes_succubus_tail; diff --git a/Source/Genes/Special/Patches/Patch_GeneticSexSwap.cs b/Source/Genes/Special/Patches/Patch_GeneticSexSwap.cs new file mode 100644 index 0000000..377b71d --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_GeneticSexSwap.cs @@ -0,0 +1,69 @@ +using HarmonyLib; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public class Patch_GeneticSexSwap + { + public static void Postfix(SexProps props) + { + if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal()) + { + return; + } + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (pawn.genes == null || partner.genes == null) return; + + // If both have the swap gene, nothing happens + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_sexual_genetic_swap) + && GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_sexual_genetic_swap)) + return; + // If neither has the swap gene, nothing happens + if (!GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_sexual_genetic_swap) + && !GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_sexual_genetic_swap)) + return; + + ChanceExtension chanceExt = GeneDefOf.rjw_genes_sexual_genetic_swap.GetModExtension(); + if (chanceExt != null && (new Random()).NextDouble() < chanceExt.chance) + SwapOneRandomGene(pawn, partner); + } + + /// + /// Removes a random gene from one pawn and adds it too the other as xenogene. + /// The "gene swap" gene cannot be swapped! + /// + private static void SwapOneRandomGene(Pawn a, Pawn b, bool AddAsXenogene = true) + { + + var geneFromA = a.genes.GenesListForReading + .Where(gene => a.genes.HasActiveGene(gene.def)) + .Where(gene => gene.def != GeneDefOf.rjw_genes_sexual_genetic_swap) + .RandomElement(); + var geneFromB = b.genes.GenesListForReading + .Where(gene => b.genes.HasActiveGene(gene.def)) + .Where(gene => gene.def != GeneDefOf.rjw_genes_sexual_genetic_swap) + .RandomElement(); + + if (geneFromA == null || geneFromB == null) return; + + ModLog.Debug($"Sexual Genetic Swap: Swapping {geneFromA.def} from {a} with {geneFromB.def} from {b}"); + + a.genes.AddGene(geneFromB.def, AddAsXenogene); + b.genes.AddGene(geneFromA.def, AddAsXenogene); + a.genes.RemoveGene(geneFromA); + b.genes.RemoveGene(geneFromB); + } + + } +} diff --git a/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs b/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs new file mode 100644 index 0000000..ecc2201 --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs @@ -0,0 +1,68 @@ +using HarmonyLib; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public class Patch_GeneticSexThief + { + public static void Postfix(SexProps props) + { + if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal()) + { + return; + } + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (pawn.genes == null || partner.genes == null) return; + + // If both have the swap gene, nothing happens + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_sexual_genetic_thief) + && GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_sexual_genetic_thief)) + return; + + if (GeneUtility.HasGeneNullCheck(pawn,GeneDefOf.rjw_genes_sexual_genetic_thief) && + !GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_genetic_disease_immunity)) + { + ChanceExtension chanceExt = GeneDefOf.rjw_genes_sexual_genetic_thief.GetModExtension(); + if (chanceExt != null && (new Random()).NextDouble() < chanceExt.chance) + StealRandomGene(pawn, partner); + } + + if (GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_sexual_genetic_thief) && + !GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_genetic_disease_immunity)) + { + ChanceExtension chanceExt = GeneDefOf.rjw_genes_sexual_genetic_thief.GetModExtension(); + if (chanceExt != null && (new Random()).NextDouble() < chanceExt.chance) + StealRandomGene(partner, pawn); + } + } + + /// + /// Removes a random gene from one pawn and adds it too the other as xenogene. + /// + private static void StealRandomGene(Pawn stealer, Pawn victim, bool AddAsXenogene = true) + { + var stolenGene = victim.genes.GenesListForReading + .Where(gene => victim.genes.HasActiveGene(gene.def)) + .RandomElement(); + + if (stolenGene == null) return; + + ModLog.Debug($"Sexual Gene Thief: {stealer} steals {stolenGene.def} from {victim}"); + + stealer.genes.AddGene(stolenGene.def, AddAsXenogene); + victim.genes.RemoveGene(stolenGene); + } + + } +} diff --git a/Source/Genes/Special/Patches/Patch_HormonalSaliva.cs b/Source/Genes/Special/Patches/Patch_HormonalSaliva.cs index 150eeec..fed69d7 100644 --- a/Source/Genes/Special/Patches/Patch_HormonalSaliva.cs +++ b/Source/Genes/Special/Patches/Patch_HormonalSaliva.cs @@ -12,7 +12,6 @@ namespace RJW_Genes [HarmonyPatch(typeof(SexUtility), "Aftersex")] public class Patch_HormonalSaliva { - // TODO: Reduce to 0.02 after debug. const float SIZE_INCREMENT_FALLBACK = 0.02f; const float MAX_BODY_SIZE_FALLBACK = 2.5f; const float CUM_MULTIPLIER_FALLBACK = 1.05f; diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index 0e0df2d..306bcb7 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -56,6 +56,7 @@ + @@ -188,6 +189,8 @@ + +