diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f25417..0e066a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,11 +66,52 @@ Any gene can give immunity against any genetic disease using an extension: These extensions can be slapped on any gene, but they are meant mostly to have infectors immune against their own diseases. +**Twinkification / Feminization**: + +Both approaches follow the same general logic. + +- Pawn `A` has Twinkifier Gene and fucks Pawn `B` +- `B` receives a `twinkification progress` hediff with some effects +- Upon having ANY sex, `B` can gain genes from a relevant genepool. +- Genes can be minor or major, depending on the progress of twinkification. + +Pawn `B` might be immune against twinkifier as normal immunity logic against diseases. +But once the hediff is there, the twinkification can happen unless you wait for it to cool down. +Gene additions are subject to an application chance (25% for minor, 10% for major) +and might try to add a gene that already exists - then nothing happens. + +*Twink Genepool*: +- (Minor) Body_Thin +- (Minor) Homosexual +- (Minor) Beard_NoBeardOnly +- (Minor) Small male genitalia +- (Major) Minor Vulnerability +- (Major) Infectious Homosexuality +- (Major) Delicate +- (Major) Beauty Pretty +- (Major) Fertile Anus + +*Feminization Genepool*: +- (Minor) Long Hair +- (Minor) No-Beard +- (Minor) Small Male Genitals +- (Minor) No Cum +- (Minor) Big Breasts (will only show later) +- (Major) Female Only +- (Major) No Penis +- (Major) Minor Vulnerability + +These are currently hardcoded but I can change them on popular demand. +In general minor changes are only cosmetic and wont change metabolism. + +*Why are these changes Genetic?* +Because this is the genes mod, and I find things here quite robust. + ## Changelog **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) +- 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 @@ -83,6 +124,10 @@ but they are meant mostly to have infectors immune against their own diseases. - 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. - Gene: Sperm Displacement. Pawns might overwrite an existing pregnancy, becoming the new father. The pregnancy will stay in its gestation progress. +- Gene: Twinkification: Pawns turn their (male) sexual partners into breedable twinks. +- Gene: Feminization: Pawns turn their (male) sexual partners into women. +- Gene: Blocked Masturbation: Pawns cannot masturbate. +- Disease Gene: Infectious Blocked Masturbation - Pawns will have negative thoughts about pawns with more genetic diseases than themselves. - Faction Penalties for spreading diseases, stealing genes and aging pawns with age transfer - Patch for [Imphilee Xeno](https://steamcommunity.com/sharedfiles/filedetails/?id=2990674516) by @Bunuffin @@ -118,6 +163,11 @@ Verse.Log:Error (string) This is not dangerous. +*Blocked Masturbation* + +Might not be fully working - for testing, I run things in DevMode, and I can just order people to masturbate. +Please playtest this a bit for me, as I want to make it work nicely. + *Supporting* You can now support me with [buying me a coffee](https://buymeacoffee.com/vegapnk). diff --git a/Common/Assemblies/Rjw-Genes.dll b/Common/Assemblies/Rjw-Genes.dll index 1099308..19855eb 100644 Binary files a/Common/Assemblies/Rjw-Genes.dll and b/Common/Assemblies/Rjw-Genes.dll differ diff --git a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml index 33a8078..d9ded6c 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml @@ -15,7 +15,6 @@ - rjw_genes_mechbreeder @@ -81,7 +80,6 @@ -1 - rjw_genes_mating_call @@ -98,7 +96,6 @@ -1 - rjw_genes_pheromone_spit diff --git a/Common/Defs/GeneDefs/GeneDefs_Diseases.xml b/Common/Defs/GeneDefs/GeneDefs_Diseases.xml index 167fd0b..a4afbd0 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Diseases.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Diseases.xml @@ -7,8 +7,8 @@
  • - Genes/Icons/RJW_Genes_Endogene_Background - Genes/Icons/RJW_Genes_Xenogene_Background + Genes/Icons/RJW_Genes_Endogene_Disease_Background + Genes/Icons/RJW_Genes_Endogene_Disease_Background
  • @@ -85,6 +85,22 @@ + + + rjw_genes_infectious_blocked_masturbation + + Carriers of this gene are unable to masturbate - they need a partner or equipment. + Genes/Icons/Hypersexual + 55 + 1 + 2 + +
  • + 0.05 +
  • +
    +
    + rjw_genes_infectious_low_fertility @@ -178,7 +194,7 @@ rjw_genes_infectious_bisexuality This gene makes the pawn bisexual, and has a chance to spread on intercourse. - UI\Ideoligions\Universal\RoundC + Genes/Icons/RoundC 1 0 8 @@ -205,7 +221,7 @@ rjw_genes_infectious_homosexuality This gene makes the pawn homosexual, and has a chance to spread on intercourse. - UI\Ideoligions\Universal\RoundC + Genes/Icons/RoundC 1 0 9 diff --git a/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml b/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml index 5ff7ec6..ada888c 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml @@ -205,4 +205,22 @@ + + rjw_genes_blocked_masturbation + + Reproduction + Carriers of this gene are unable to masturbate - they need a partner or equipment. + Genes/Icons/Hypersexual + 60 + 0 + 1 + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    + \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml index 001b765..d715892 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml @@ -186,7 +186,7 @@ Carriers with this gene slowly turn male sexual partners into females. UI/Icons/Genes/Gene_PsychicBonding 31 - 5 + 4 -1
  • @@ -214,7 +214,7 @@ UI/Icons/Genes/Gene_PsychicBonding 50 4 - 0 + -1
  • @@ -224,7 +224,7 @@
  • rjw_genes_twinkification_progress true - 0.99 + 0.01 1.00 false true diff --git a/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml b/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml index 3dce4c0..1ca0191 100644 --- a/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml +++ b/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml @@ -17,7 +17,7 @@
  • - +
  • false @@ -89,7 +89,7 @@
  • - +
  • false diff --git a/Common/Textures/Genes/Icons/RJW_Genes_Endogene_Disease_Background.png b/Common/Textures/Genes/Icons/RJW_Genes_Endogene_Disease_Background.png new file mode 100644 index 0000000..c614dc9 Binary files /dev/null and b/Common/Textures/Genes/Icons/RJW_Genes_Endogene_Disease_Background.png differ diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs index 64b84f6..7f0465f 100644 --- a/Source/GeneDefOf.cs +++ b/Source/GeneDefOf.cs @@ -74,8 +74,9 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_insectbreeder; public static readonly GeneDef rjw_genes_insectincubator; public static readonly GeneDef rjw_genes_hardwired_progenity; - - // Cum + public static readonly GeneDef rjw_genes_blocked_masturbation; + + // 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; @@ -139,6 +140,7 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_infectious_homosexuality; public static readonly GeneDef rjw_genes_infectious_hypersexuality; public static readonly GeneDef rjw_genes_stretcher; + public static readonly GeneDef rjw_genes_infectious_blocked_masturbation; //Other Defs public static readonly XenotypeDef rjw_genes_succubus; diff --git a/Source/Genes/Breeding/Patches/Patch_BlockedMasturbation.cs b/Source/Genes/Breeding/Patches/Patch_BlockedMasturbation.cs new file mode 100644 index 0000000..c888bda --- /dev/null +++ b/Source/Genes/Breeding/Patches/Patch_BlockedMasturbation.cs @@ -0,0 +1,26 @@ +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(xxx), "can_masturbate")] + public class Patch_BlockedMasturbation + { + public void PostFix(Pawn pawn, ref bool __result) + { + if (pawn != null && !pawn.IsAnimal() && pawn.genes != null) + { + __result = __result + && !pawn.genes.HasActiveGene(GeneDefOf.rjw_genes_blocked_masturbation) + && !pawn.genes.HasActiveGene(GeneDefOf.rjw_genes_infectious_blocked_masturbation); + } + } + + } +} diff --git a/Source/Genes/Special/Patches/Patch_Feminizer.cs b/Source/Genes/Special/Patches/Patch_Feminizer.cs new file mode 100644 index 0000000..952f63a --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_Feminizer.cs @@ -0,0 +1,120 @@ +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 +{ + /// + /// This patch handles the changes produced by `rjw_genes_feminizer`. + /// It requires the hediff `rjw_genes_feminzation_in_progress` which is managed separately, in `Patch_HediffIncreaseOnSex`. + /// + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public static class Patch_Feminizer + { + const float MINOR_APPLICATION_CHANCE = 0.25f; // = 25% to have a minor transformation + const float MAJOR_APPLICATION_CHANCE = 0.10f; // = 10% to have a major transformation + + public static void Postfix(SexProps props) + { + if (props == null || props.pawn == null || !props.hasPartner() || props.partner == null) + return; + if (props.pawn.IsAnimal() || props.partner.IsAnimal()) + return; + + ApplyFeminization(props.pawn); + ApplyFeminization(props.partner); + } + + private static void ApplyFeminization(Pawn pawn) + { + if (pawn == null) return; + Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_feminization_progress); + if (hediff == null) return; + + var Random = new Random(); + // DevNote: I first had a switch (hediff.SeverityLabel) but SeverityLabel was null. + // So now I have this approach which feels a bit more robust. + // I was thinking about looking for strings in the label, but I think that will break the logic in case of translations. + switch (hediff.Severity) + { + case float f when f > 0.8f: + { + if (Random.NextDouble() < MAJOR_APPLICATION_CHANCE) + MajorChange(pawn); + } break; + case float f when f > 0.6f: + { + if (Random.NextDouble() < MINOR_APPLICATION_CHANCE) + MinorChange(pawn); + } break; + default: + { + ModLog.Debug($"Tried to feminize {pawn} - severity of feminization was too low ({hediff.def} @ {hediff.Severity} - {hediff.Label})") ; + } break; + } + + } + + private static void MinorChange(Pawn pawn) + { + List possibleGenes = new List() { + GeneDefOf.rjw_genes_small_male_genitalia, + GeneDefOf.rjw_genes_big_breasts, + GeneDefOf.rjw_genes_no_cum, + DefDatabase.GetNamed("Beard_NoBeardOnly"), + DefDatabase.GetNamed("Hair_LongOnly") + }; + + GeneDef chosen = possibleGenes.RandomElement(); + if (chosen == null) + { + ModLog.Warning($"Error in retrieving a minor-feminization gene for feminizing {pawn}"); + return; + } + + // DevNote: I could do "hasActiveGene" but that could lead to the gene being there but not active. + if (!pawn.genes.GenesListForReading.Any(p => p.def == chosen)) + { + ModLog.Debug($"{pawn} experienced a minor feminization change; {pawn} got new gene {chosen}."); + pawn.genes.AddGene(chosen, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + } else + { + ModLog.Debug($"Tryed a minor feminization for {pawn} - {pawn} already had {chosen}"); + } + } + + private static void MajorChange(Pawn pawn) + { + List possibleGenes = new List() { + GeneDefOf.rjw_genes_female_only, + GeneDefOf.rjw_genes_no_penis, + GeneDefOf.rjw_genes_minor_vulnerability, + }; + + GeneDef chosen = possibleGenes.RandomElement(); + if (chosen == null) + { + ModLog.Warning($"Error in retrieving a minor-feminization gene for feminizing {pawn}"); + return; + } + + // DevNote: I could do "hasActiveGene" but that could lead to the gene being there but not active. + if (!pawn.genes.GenesListForReading.Any(p => p.def == chosen)) + { + ModLog.Debug($"{pawn} experienced a major feminization change; {pawn} got new gene {chosen}."); + pawn.genes.AddGene(chosen, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + } + else + { + ModLog.Debug($"Tryed a major feminization for {pawn} - {pawn} already had {chosen}"); + ModLog.Debug($"Trying minor feminization for {pawn} instead ..."); + MinorChange(pawn); + } + } + } +} diff --git a/Source/Genes/Special/Patches/Patch_Twinkifier.cs b/Source/Genes/Special/Patches/Patch_Twinkifier.cs index 53c9d46..87b43bc 100644 --- a/Source/Genes/Special/Patches/Patch_Twinkifier.cs +++ b/Source/Genes/Special/Patches/Patch_Twinkifier.cs @@ -35,44 +35,87 @@ namespace RJW_Genes if (pawn == null) return; Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_twinkification_progress); if (hediff == null) return; - + var Random = new Random(); - switch (hediff.SeverityLabel) + // DevNote: I first had a switch (hediff.SeverityLabel) but SeverityLabel was null. + // So now I have this approach which feels a bit more robust. + // I was thinking about looking for strings in the label, but I think that will break the logic in case of translations. + switch (hediff.Severity) { - case "severe": - case "critical": + case float f when f > 0.8f: { if (Random.NextDouble() < MAJOR_APPLICATION_CHANCE) - majorChange(pawn); + MajorChange(pawn); } break; - case "minor": + case float f when f > 0.6f: { if (Random.NextDouble() < MINOR_APPLICATION_CHANCE) - minorChange(pawn); + MinorChange(pawn); + } break; + default: + { + ModLog.Debug($"Tried to twinkify {pawn} - severity of twinkification was too low ({hediff.def} @ {hediff.Severity} - {hediff.Label})") ; } break; } } - private static void minorChange(Pawn pawn) + private static void MinorChange(Pawn pawn) { - // Minor Infectious Vulnerability - // Smaller Genitalia - // Remove Beard - // Thin Body Type + List possibleGenes = new List() { + GeneDefOf.rjw_genes_small_male_genitalia, + DefDatabase.GetNamed("Beard_NoBeardOnly"), + DefDatabase.GetNamed("Body_Thin"), + GeneDefOf.rjw_genes_homosexual + }; + + GeneDef chosen = possibleGenes.RandomElement(); + if (chosen == null) + { + ModLog.Warning($"Error in retrieving a minor-twinkification gene for twinkifying {pawn}"); + return; + } + + // DevNote: I could do "hasActiveGene" but that could lead to the gene being there but not active. + if (!pawn.genes.GenesListForReading.Any(p => p.def == chosen)) + { + ModLog.Debug($"{pawn} experienced a minor twinkification change; {pawn} got new gene {chosen}."); + pawn.genes.AddGene(chosen, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + } else + { + ModLog.Debug($"Tryed a minor twinkification for {pawn} - {pawn} already had {chosen}"); + } } - private static void majorChange(Pawn pawn) + private static void MajorChange(Pawn pawn) { - // Final Gene-Pool should have: - // - Fragile (?) - // - Infectious Vulnerability - // - Infectious Homosexuality - // - Beauty - // - Fertile Anus + List possibleGenes = new List() { + GeneDefOf.rjw_genes_fertile_anus, + DefDatabase.GetNamed("Beauty_Pretty"), + DefDatabase.GetNamed("Delicate"), + GeneDefOf.rjw_genes_minor_vulnerability, + GeneDefOf.rjw_genes_infectious_homosexuality + }; - pawn.genes.AddGene(GeneDefOf.rjw_genes_fertile_anus, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); - pawn.genes.AddGene(GeneDefOf.rjw_genes_infectious_homosexuality, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + GeneDef chosen = possibleGenes.RandomElement(); + if (chosen == null) + { + ModLog.Warning($"Error in retrieving a minor-twinkification gene for twinkifying {pawn}"); + return; + } + + // DevNote: I could do "hasActiveGene" but that could lead to the gene being there but not active. + if (!pawn.genes.GenesListForReading.Any(p => p.def == chosen)) + { + ModLog.Debug($"{pawn} experienced a major twinkification change; {pawn} got new gene {chosen}."); + pawn.genes.AddGene(chosen, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + } + else + { + ModLog.Debug($"Tryed a major twinkification for {pawn} - {pawn} already had {chosen}"); + ModLog.Debug($"Trying minor twinkification for {pawn} instead ..."); + MinorChange(pawn); + } } } } diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index 8300996..5182089 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -81,6 +81,7 @@ + @@ -197,6 +198,7 @@ +