diff --git a/CHANGELOG.md b/CHANGELOG.md index 26387d8..c6b9f65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,196 @@ -# 2.1.0 +# 2.2.0 (23-07-2024) + +## Explanations + +**Genetic Diseases**: + +This update introduces genetic diseases that are shared on sex. +Infection is handled when sex finishes, so a coitus-interruptus will not result in infections. + +Infections can be + +- Turned off entirely +- Spread only on penetrative sex +- Chances are adjustable per XML per Gene + +By turning their spread off, you effectively have a set of normal negative genes. +Dead pawns can spread diseases, but cannot receive them. For all you necros out there. + +*Why???* + +Most of the genes so far were positive or neutral, +so I got some fair requests to introduce negative genes to keep xenotypes balanced. +I know that this is some overlap with the STD mod, but well ... you are free to turn things off? + +In theory, you can specify and gene of any kind to be spreadable by sex, not only ones written by this mod. + +**Genetic Infectors**: + +These Genes can apply a genetic disease, but are not genetic diseases themselves. +A single infector gene can have multiple resulting diseases, see this extension example: + +```xml +
  • + 0.05 + +
  • rjw_genes_size_blinded
  • +
  • rjw_genes_infectious_bisexuality
  • + + +``` + +The infection-chance is applied per gene - for the example above there would be a 5% chance to apply `size_blinded` and 5% chance to apply `infectious_bisexuality`. +Multiple infections can happen on a single sex. +The `infectionGenes` can be any gene, this is not limited to genetic diseases (e.g. ugly or something). + +*Infectors* are always applied even if the genetic disease spread is turned off. +The created genetic diseases will follow the logic outlined above. + +**Disease Immunity**: + +Pawns can be immune to genetic diseases. + +This is either done with a specialised gene (`rjw_genes_genetic_disease_immunity`) +or by genes giving specific immunities. + +Any gene can give immunity against any genetic disease using an extension: + +```xml +
  • + +
  • rjw_genes_size_blinded
  • + + +``` + +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 + +You can configure all genes, as well as their application chance, in the Genes` XML. + +*Why are these changes Genetic?* +Because this is the genes mod, and I find things here quite robust. + +## Changelog + +**Additions:** + +- 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 +- Disease Gene: Infectious lower fertility +- Disease Gene: Infectious higher sex need +- Disease Gene: Fluctual Sexual Need. (Configurable) Chance to reset sex-need to near-zero and gain a bit of rest-need. +- 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. +- 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. +- {Sexperience} Gene: Living Cumbucket. Pawns with this Gene get "filled" upon sex, and slowly disperse usable gathered cum. +- Disease Gene: Infectious Blocked Masturbation +- Gene: Rut. Pawns have a chance to go into heat and need more sex for a day. (Default: 5% chance per day, to go 1 day in heat). +- Disease Gene: Infectious Rut. +- 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 + +**Changes**:: + +- Cum-Amount-Changing genes now are XML Adjustable and share a single `.cs`-class +- Incubi are now Bisexual too, as they should be. + +**Fixes:** + +- Fixed an Issue where pawns would always get the Pheromone social boost, unless they had the pheromone (#113) +- Fixed two hidden dependencies on Ideology and Royalty (#115) +- Fixed some more hidden dependencies on Ideology Icons (#118) +- Fixed a hidden dependency on Licentialabs (#119) + +**Internal:** + +- GenderFluid-Gene now uses a generalized `TickBasedChanceExtension` over its unique special `GenderFluidExtension` +- Introduced a `ModLog.Debug` Function that checks for the settings before printing - trying to spread it over the whole project. +- Removed TODO File. I have enough to do. + +**Notes:** + +*One Time Error Load* + +The changes to the cum-gene will give a 1-time warning on loading the save. The warning looks like this: +``` +Could not find class RJW_Genes.Gene_MuchCum while resolving node li. Trying to use Verse.Gene instead. Full node:
  • rjw_genes_much_cumThing_Human697null82
  • +UnityEngine.StackTraceUtility:ExtractStackTrace () +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). +The mod will remain free, open source and I will not hide or lock any features. +Its just meant if you want to drop me a tip. + +**Since Beta-1** (11-07-2024) + +- Made the Feminizer and Twinkifier configurable with XML. +- Typos in the Hediff Defs, tweaking of some values. +- Living Cum-Bucket & Rut Genes +- Great icons by @Alpenglow + +**Since Beta-2** (17-07-2024) + +- Changed behaviour of living cumbucket. Now, once "really full" the output happens more rarely but is much more at once. +- More Icons by @Alpenglow <3 this time attributed correct. +- Adjusted some of the metabolic values - likes cumflation, generous donor and living cumbucket have small costs. + +# 2.1.0 (27-06-2024) **Additions**: @@ -45,7 +237,7 @@ - Some new Icons thanks to Kira-Bad-Artist - Some new Icons thanks to Archer -# 2.0.0 +# 2.0.0 (30-05-2024) **Summary**: @@ -92,20 +284,20 @@ - Patches to RJW-Pregnancy Helper to account for Male Pregs. - Some replacements from `hasGene` to `hasActiveGene` -# 1.3.3 +# 1.3.3 (02-11-2023) **Fixes:** - Added another check to the AG Malachai Xenotype (Fixes #68) - Fixed the `GatheredCum`Fertilin Ingestion Patch throwing an Error for people without Sexperience (Fixes #69 (nice)) -# 1.3.2 +# 1.3.2 (24-10-2023) **Fixes:** - Removed patch for Malachai, needs a different patching operator but I don't want to have broken fixes for now (Tracked in a new Issue) -# 1.3.1 +# 1.3.1 (22-10-2023) **Changes** @@ -144,7 +336,7 @@ The pawns that are gender fluid can get pregnant. However, with RJW 5.3.7 these pregnancies disappear. This is a change needed upstream, but I will have a look. -# 1.2.1 +# 1.2.1 (18-06-2023) **Fixes**: @@ -224,9 +416,9 @@ And I am aware that the TiTs-Myr work different than the things I made now. - Mostly Patches and Changes to the Halamyr Defs - Some re-arranging and mayRequires for other mods -# 1.1.4 +# 1.1.4 (06-04-2023) -Fixes: +**Fixes:** - Youth Fountain and Age Drainer **really** "stop" at 18 (#26, #28) and never age pawns - Drastically reduced vomiting time due to an missunderstanding (#29). `0.4` instead of `0.01` @@ -234,37 +426,37 @@ Fixes: Sometimes life is like that, and you have to fix the fixes. It was never really broken, life is just very long. -# 1.1.3 +# 1.1.3 (28-03-2023) -Changes: +**Changes:** - Youth Fountain and Age Drainer "stop" at 18 (#26) - Youth Fountain and Age Drainer activate only for pawns at 18 (#26) - Drained Pawns vomit less (from mtb 0.05 to 0.01)(#29) -Fixes: +**Fixes:** - InsectBreeder would mess with normal Pawn-Animal pregancy for egg laying animals (#23) -# 1.1.2 +# 1.1.2 (19-03-2023) -Changes: +**Changes:** - Added more cool images from WasMachenDennSachen (#22) -Fixes: +**Fixes:** - Aphrodisiac Pheromones checks for children and other conditions (#25) -# 1.1.1 +# 1.1.1 (10-03-2023) -Changes: +**Changes:** - Drastically increased mood-penalty for Fertilin-Loss (if the pawn is still too happy, there will never be a breakdown for missing fertilin) - No-Breast Genes add Nipples - Featureless Chest Gene (No Nipples at all, adds the RJW Featureless Chest as requested per some Kobold fetishists) -Fixes: +**Fixes:** - Small and Big Male Genitalia had images wrong way round - Fertilin should activate at a MinAge of 18 diff --git a/Common/Assemblies/Rjw-Genes.dll b/Common/Assemblies/Rjw-Genes.dll index 1099308..bb1f065 100644 Binary files a/Common/Assemblies/Rjw-Genes.dll and b/Common/Assemblies/Rjw-Genes.dll differ diff --git a/Common/Defs/GeneDefs/GeneCategories.xml b/Common/Defs/GeneDefs/GeneCategories.xml index e506741..e799489 100644 --- a/Common/Defs/GeneDefs/GeneCategories.xml +++ b/Common/Defs/GeneDefs/GeneCategories.xml @@ -67,5 +67,11 @@ 8 + + rjw_genes_diseases + + 22 + + \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml index bb6fbe4..1b946c2 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml @@ -15,7 +15,6 @@ - rjw_genes_mechbreeder @@ -42,8 +41,9 @@ rjw_genes_fertile_anus - Xenotypes with this gene have a functional uterus connected to the anal cavity even - for males + Xenotypes with this gene have a functional uterus if they do not possess one by + means of their vagina. + For males, it is connected to the anal cavity and leads to a normal pregnancy. Genes/Icons/Fertile_anus 54 @@ -81,7 +81,6 @@ -1 - rjw_genes_mating_call @@ -98,7 +97,6 @@ -1 - rjw_genes_pheromone_spit @@ -115,4 +113,62 @@ -1 + + rjw_genes_hardwired_progenity + + Carriers of this gene need to procreate. They suffer negative effects if they are + childless, and have increased capabilities if they reach a high amount of offsprings. + Genes/Icons/hardwired_progenity + 70 + + +
  • + + -0.1 + 1.2 + 1.2 + +0.15 + -0.1 + +
  • +
  • + + 0.05 + 0.1 + 0.1 + 0.4 + +
  • +
  • + + 0.15 + 0.25 + -0.25 + +
  • +
    + + 1 + 0 +
    + + + rjw_genes_basic_rut + + Carriers of this gene can enter a state of heat, resulting in drastically higher + sexual activity. + Genes/Icons/rut + 1 + 1 + 11 + RJW_Genes.Gene_Rut + +
  • + + 60000 + 0.05 +
  • +
    +
    + \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Cum.xml b/Common/Defs/GeneDefs/GeneDefs_Cum.xml index 32ac80c..95580a8 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Cum.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Cum.xml @@ -21,10 +21,15 @@ Males of these species have no fluid. Genes/Icons/No_Cum - RJW_Genes.Gene_NoCum + RJW_Genes.Gene_ChangeCumAmount 533 0 1 + +
  • + 0.0 +
  • +
    @@ -32,10 +37,15 @@ Males of this species produce a lot of fluid. Genes/Icons/Much_Cum - RJW_Genes.Gene_MuchCum + RJW_Genes.Gene_ChangeCumAmount 534 1 - -1 + 0 + +
  • + 3.0 +
  • +
    @@ -44,10 +54,15 @@ Males of this species produce a whole lot of fluid. They are like fountains basically. Genes/Icons/Very_Much_Cum - RJW_Genes.Gene_VeryMuchCum + RJW_Genes.Gene_ChangeCumAmount 535 1 - -2 + -1 + +
  • + 15.0 +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Damage.xml b/Common/Defs/GeneDefs/GeneDefs_Damage.xml index d045a68..2e7f941 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Damage.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Damage.xml @@ -7,7 +7,7 @@ rjw_genes_damage This Gene makes the Carrier unable to get mood or social penalties from being raped and they cannot be broken for a long period of time. - UI/Icons/Rituals/TrialDefend + Genes/Icons/TrialDefend 2 -1 1 diff --git a/Common/Defs/GeneDefs/GeneDefs_Diseases.xml b/Common/Defs/GeneDefs/GeneDefs_Diseases.xml new file mode 100644 index 0000000..017c1c4 --- /dev/null +++ b/Common/Defs/GeneDefs/GeneDefs_Diseases.xml @@ -0,0 +1,336 @@ + + + + + rjw_genes_diseases + false + +
  • + Genes/Icons/RJW_Genes_Endogene_Disease_Background + Genes/Icons/RJW_Genes_Endogene_Disease_Background +
  • +
    +
    + + + rjw_genes_diseases + rjw_genes_genetic_disease_immunity + 1 + 0.95 + + This gene makes the pawn immune against genetic STDs and some other genes that + imply negative side-effects. + 1 + -1 + Genes/Icons/disease_immunity + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    + + + + rjw_genes_minor_vulnerability + + This gene makes the pawn a bit more vulnerable, and a slightly more attractive + target for rape. + 1 + 1 + 0.85 + Genes/Icons/minor_vulnerability + 5 + + + 0.15 + + + +
  • RJW_Genes_Vulnerability
  • +
    + + +
  • + 0.05 +
  • +
    +
    + + + rjw_genes_major_vulnerability + + This gene makes the pawn more vulnerable, and a more attractive target for + rape. + 2 + 1 + Genes/Icons/major_vulnerability + 6 + + +
  • RJW_Genes_Vulnerability
  • +
    + + + 0.3 + + + +
  • + 0.03 +
  • +
    +
    + + + + rjw_genes_infectious_blocked_masturbation + + Carriers of this gene are unable to masturbate - they need a partner or + equipment. + Genes/Icons/blocked_masturbation + 55 + 1 + 2 + +
  • + 0.05 +
  • +
    +
    + + + rjw_genes_infectious_low_fertility + + Carriers of this genetic disease have lower fertility. + 1 + 1 + 0.9 + UI/Icons/ColonistBar/Idle + 5 + + + -0.15 + + + +
  • + 0.05 +
  • +
    +
    + + + rjw_genes_infectious_increased_sex_need + + Carriers of this genetic disease need more sex. + 0 + 1 + 0.9 + UI/Icons/ColonistBar/Idle + 5 + + + 0.15 + + + +
  • + 0.08 +
  • +
    +
    + + + rjw_genes_infectious_major_increased_sex_need + + Carriers of this genetic disease need a lot more sex. + 1 + 2 + 0.85 + UI/Icons/ColonistBar/Idle + 5 + + + 1.0 + + + +
  • + 0.03 +
  • +
    +
    + + + rjw_genes_infectious_hypersexuality + + This gene makes the pawn hypersexual, and has a chance to spread on + intercourse. + Genes/Icons/Hypersexual + 2 + 2 + 7 + +
  • rjw_genes_hypersexuality_trait_giver
  • +
    + + +
  • + Nymphomaniac +
  • +
    + + +
  • + 0.05 +
  • +
    +
    + + + rjw_genes_infectious_bisexuality + + This gene makes the pawn bisexual, and has a chance to spread on intercourse. + Genes/Icons/bisexuality + 1 + 0 + 8 + + +
  • rjw_genes_bisexuality_trait_giver
  • +
  • rjw_genes_sexual_orientation
  • +
    + + +
  • + Bisexual +
  • +
    + + +
  • + 0.1 +
  • +
    +
    + + + rjw_genes_infectious_homosexuality + + This gene makes the pawn homosexual, and has a chance to spread on intercourse. + Genes/Icons/homosexuality + 1 + 0 + 9 + + +
  • rjw_genes_homosexuality_trait_giver
  • +
  • rjw_genes_sexual_orientation
  • +
    + + +
  • + Gay +
  • +
    + + +
  • + 0.1 +
  • +
    +
    + + + rjw_genes_fluctual_sexual_needs + + Carriers of this genetic disease have a chance to suddenly require sex, gaining + a bit of energy to find quick relief. + UI/Icons/ColonistBar/Idle + 1 + 2 + 11 + RJW_Genes.Gene_FluctualSexualNeed + +
  • + 0.1 +
  • +
  • + + 30000 + 0.15 +
  • +
    +
    + + + + rjw_genes_size_blinded + + This genetic disease makes the carrier dramatically more drawn to pawns with + huge cocks. + Genes/Icons/size_blinded + 1 + 1 + 11 + +
  • + 0.1 +
  • +
    +
    + + + rjw_genes_stretcher + + Pawns with this gene have a chance to alter the genes of their sexual partners + to prefer large cocks. + Genes/Icons/stretcher + 1 + 0 + 12 + +
  • + +
  • rjw_genes_size_blinded
  • + + +
  • + 0.05 + +
  • rjw_genes_size_blinded
  • + + +
    +
    + + + + rjw_genes_infectious_rut + + Carriers of this gene can enter a state of heat, resulting in drastically + higher + sexual activity. + Genes/Icons/rut + 1 + 2 + 11 + RJW_Genes.Gene_Rut + +
  • + + 60000 + 0.05 +
  • +
  • + 0.1 +
  • +
    +
    + + +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml b/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml index 8a9d018..a01e245 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml @@ -14,6 +14,10 @@ + +
  • rjw_genes_hypersexuality_trait_giver
  • +
    + false
  • - - rjw_genes_masochist @@ -102,7 +81,7 @@ Reproduction This Gene makes you gay. - UI\Ideoligions\Universal\RoundC + Genes/Icons/RoundC 0 3 @@ -111,6 +90,7 @@
  • +
  • rjw_genes_homosexuality_trait_giver
  • rjw_genes_sexual_orientation
  • @@ -129,7 +109,7 @@ Reproduction Carriers of this Gene are Bisexual. - UI\Ideoligions\Universal\RoundC + Genes/Icons/RoundC 0 4 @@ -139,6 +119,7 @@
  • rjw_genes_sexual_orientation
  • +
  • rjw_genes_bisexuality_trait_giver
  • false @@ -200,4 +181,46 @@ + + rjw_genes_pregnancy_overwrite + + Reproduction + Carriers of this gene can 'overwrite' an existing pregnancy, keeping the + progress but effectively replacing the father. + Genes/Icons/pregnancy_overwrite + 120 + + 4 + -2 + + +
  • + 0.5 +
  • +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    + + + rjw_genes_blocked_masturbation + + Reproduction + Carriers of this gene are unable to masturbate - they need a partner or equipment. + Genes/Icons/blocked_masturbation + 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 189a6c8..1d44fe7 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml @@ -19,7 +19,7 @@ partially filled) 1 -2 - UI/Memes/FleshPurity + Genes/Icons/FleshPurity 1 @@ -30,7 +30,7 @@ (Partner stays adult) 2 -2 - UI/Ideoligions/FireLeaves + Genes/Icons/FireLeaves 2
  • @@ -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,119 @@ -1 + + rjw_genes_sexual_genetic_swap + + Carriers with this gene may switch a gene with their sex-partner. Switched Genes are always endogenes. + Genes/Icons/sexual_genetic_swap + 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. + Genes/Icons/sexual_genetic_thief + 21 + 5 + -2 + 1 + +
  • + 0.2 +
  • +
    +
    + + + rjw_genes_feminizer + + Carriers with this gene slowly turn male sexual partners into females. + Genes/Icons/feminizer + 31 + 4 + -1 + +
  • + +
  • rjw_genes_feminizer
  • + + +
  • + rjw_genes_feminization_progress + true + 0.01 + 1.00 + false + true + false +
  • +
  • + +
  • rjw_genes_female_only
  • +
  • rjw_genes_no_penis
  • +
  • rjw_genes_minor_vulnerability
  • + + +
  • rjw_genes_small_male_genitalia
  • +
  • rjw_genes_big_breasts
  • +
  • Beard_NoBeardOnly
  • +
  • Hair_LongOnly
  • +
    + 0.25 + 0.1 + +
    +
    + + + rjw_genes_twinkifier + + Carriers with this gene slowly turn male sexual partners into breedabel cute twinks. + Genes/Icons/twinkifier + 50 + 4 + -1 + +
  • + +
  • rjw_genes_twinkifier
  • + + +
  • + rjw_genes_twinkification_progress + true + 0.01 + 1.00 + false + true + false +
  • +
  • + +
  • rjw_genes_fertile_anus
  • +
  • Beauty_Pretty
  • +
  • Delicate
  • +
  • rjw_genes_minor_vulnerability
  • +
  • rjw_genes_infectious_homosexuality
  • + + +
  • rjw_genes_small_male_genitalia
  • +
  • Beard_NoBeardOnly
  • +
  • Body_Thin
  • +
  • rjw_genes_homosexual
  • +
    + 0.25 + 0.1 + +
    +
    + \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml b/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml index 12ba760..82a302c 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml @@ -65,10 +65,10 @@ Genes/Icons/RJW_Genes_Endogene_Background Genes/Icons/RJW_Genes_Xenogene_Background -
  • +
  • - 120000 - 0.25 + 120000 + 0.25
  • diff --git a/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml b/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml index bc0c54b..f28f160 100644 --- a/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml +++ b/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml @@ -75,6 +75,7 @@
  • rjw_genes_hypersexual
  • +
  • rjw_genes_bisexual
  • rjw_genes_male_only
  • rjw_genes_lifeforce
  • rjw_genes_lifeforce_drain
  • diff --git a/Common/Defs/HediffDefs/Hediffs_Fertilin.xml b/Common/Defs/HediffDefs/Hediffs_Fertilin.xml index fdca8d4..5b56717 100644 --- a/Common/Defs/HediffDefs/Hediffs_Fertilin.xml +++ b/Common/Defs/HediffDefs/Hediffs_Fertilin.xml @@ -1,6 +1,6 @@ - + - + rjw_genes_fertilin_lost Hediff_HemogenCraving @@ -19,12 +19,13 @@ - + rjw_genes_succubus_drained HediffWithComps - The vitality of this pawn has been drained. Cannot be drained again until fully recovered. + The vitality of this pawn has been drained. Cannot be drained again until fully + recovered. (1,0,0.5) 1.0 1.0 @@ -74,13 +75,13 @@ -0.2 - 0.4 + 0.4 0.1 0.35 - + rjw_genes_fertilin_craving @@ -90,77 +91,78 @@ 1.0 0.01 -
  • - - 0.05 - -
  • - Consciousness - 0.9 -
  • - - -
  • - - 0.35 - 0.1 - -
  • - Consciousness - 0.8 -
  • - - -
  • - - 0.7 - 0.15 - -
  • - Consciousness - 0.5 -
  • - - +
  • + + 0.05 + +
  • + Consciousness + 0.9 +
  • + + +
  • + + 0.35 + 0.1 + +
  • + Consciousness + 0.8 +
  • + + +
  • + + 0.7 + 0.15 + +
  • + Consciousness + 0.5 +
  • + +
    -
  • - 0.05 - -0.1 -
  • +
  • + 0.05 + -0.1 +
  • - - rjw_genes_naked_prowess - - Driven by fertilin, this person has greatly increased strength and resilience. - HediffWithComps - -
  • - - - 0.5 - 0.5 - 0.5 - - - - 0.5 - 1.5 - -
  • -
    - -
  • - True - 5000 -
  • -
  • - - - false - + + rjw_genes_naked_prowess + (0.52, 1, 0.95) + + Driven by fertilin, this person has greatly increased strength and resilience. + HediffWithComps + +
  • + + + 0.5 + 0.5 + 0.5 + + + 0.5 + 1.5 + +
  • + + +
  • + True + 5000 +
  • +
  • + + + false + - + \ No newline at end of file diff --git a/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml b/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml new file mode 100644 index 0000000..45537fd --- /dev/null +++ b/Common/Defs/HediffDefs/Hediffs_InfectiveGenderChanges.xml @@ -0,0 +1,147 @@ + + + + + rjw_genes_feminization_progress + HediffWithComps + + Something is changing this pawn - there is a chance to develop female features + upon sex. + false + 1.0 + false + false + +
  • + -0.01 +
  • +
    + + +
  • + + false +
  • + +
  • + + 0.6 + true + +
  • + Consciousness + -0.5 +
  • + + + 0.25 + + + +
  • + + 0.8 + +
  • + Consciousness + -0.05 +
  • + + true + + 0.5 + 0.25 + + + +
  • + + 0.9 + +
  • + Consciousness + -0.1 +
  • + + true + + 1.0 + 0.5 + + +
    +
    + + + + rjw_genes_twinkification_progress + HediffWithComps + + Something is changing this pawn - there is a chance to turn into a cute, + breedable twink upon sex. + false + 1.0 + false + false + +
  • + -0.01 +
  • +
    + + +
  • + + false +
  • + +
  • + + 0.6 + true + +
  • + Consciousness + -0.05 +
  • + + + 0.25 + + + +
  • + + 0.8 + +
  • + Consciousness + -0.05 +
  • + + true + + 0.5 + 0.25 + + + +
  • + + 0.9 + +
  • + Consciousness + -0.1 +
  • + + true + + 1.5 + 0.5 + + +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/HediffDefs/Hediffs_Rut.xml b/Common/Defs/HediffDefs/Hediffs_Rut.xml new file mode 100644 index 0000000..6c6ac10 --- /dev/null +++ b/Common/Defs/HediffDefs/Hediffs_Rut.xml @@ -0,0 +1,51 @@ + + + + rjw_genes_genetic_rut + HediffWithComps + + Based on genetics, this pawn is in heat. + (240,200,110) + false + 1.0 + false + false + +
  • + -1.00 +
  • +
    + +
  • + + + 0.50 + + +
  • + BloodPumping + 0.1 +
  • + + +
  • + + 0.4 + + 2.00 + + +
  • + Moving + 0.1 +
  • +
  • + BloodPumping + 0.15 +
  • + + +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/HediffDefs/Scrambler.xml b/Common/Defs/HediffDefs/Scrambler.xml index a84299d..4ab6071 100644 --- a/Common/Defs/HediffDefs/Scrambler.xml +++ b/Common/Defs/HediffDefs/Scrambler.xml @@ -13,7 +13,7 @@
  • 0 - 0.40 + 0.40 3.0 diff --git a/Common/Defs/HistoryEventDefs/DiseaseHistoryEventDefs.xml b/Common/Defs/HistoryEventDefs/DiseaseHistoryEventDefs.xml new file mode 100644 index 0000000..488fa5f --- /dev/null +++ b/Common/Defs/HistoryEventDefs/DiseaseHistoryEventDefs.xml @@ -0,0 +1,18 @@ + + + + rjw_genes_GoodwillChangedReason_StoleGene + + + + + rjw_genes_GoodwillChangedReason_infected_with_disease + + + + + rjw_genes_GoodwillChangedReason_spread_genetic_disease + + + + \ No newline at end of file diff --git a/Common/Defs/HistoryEventDefs/SpecialHistoryEventDefs.xml b/Common/Defs/HistoryEventDefs/SpecialHistoryEventDefs.xml new file mode 100644 index 0000000..ded422c --- /dev/null +++ b/Common/Defs/HistoryEventDefs/SpecialHistoryEventDefs.xml @@ -0,0 +1,18 @@ + + + + rjw_genes_GoodwillChangedReason_aged_pawn_with_sex_gene + + + + + rjw_genes_GoodwillChangedReason_youthed_pawn_with_sex_gene + + + + + rjw_genes_GoodwillChangedReason_OverwritePregnancy + + + + \ No newline at end of file diff --git a/Common/Defs/ThoughtDefs/Thoughts_Disease.xml b/Common/Defs/ThoughtDefs/Thoughts_Disease.xml new file mode 100644 index 0000000..8997a52 --- /dev/null +++ b/Common/Defs/ThoughtDefs/Thoughts_Disease.xml @@ -0,0 +1,49 @@ + + + + + + rjw_genes_appealing_cock + Thought_SituationalSocial + RJW_Genes.ThoughtWorker_SizeBlinded_Social + true + + +
  • + + -10 +
  • +
  • + + 10 +
  • +
  • + + 20 +
  • + + + + + rjw_genes_has_more_diseases + Thought_SituationalSocial + RJW_Genes.ThoughtWorker_HasMoreDiseasesThanMe_Social + true + + +
  • + + -3 +
  • +
  • + + -8 +
  • +
  • + + -18 +
  • +
    +
    + + diff --git a/Common/Defs/TipSetDefs/Tips.xml b/Common/Defs/TipSetDefs/Tips.xml index 7147147..bc7aca3 100644 --- a/Common/Defs/TipSetDefs/Tips.xml +++ b/Common/Defs/TipSetDefs/Tips.xml @@ -23,6 +23,8 @@
  • The Settings for Animal-Gene Inheritance are distributed between RJW-Pregnancy-Settings and their own Mod-Options.
  • +
  • Children born by pawns with the `Fertile Anus` gene might be bullied at school, but they can still live a fulfilling and happy life.
  • + diff --git a/Common/Languages/English/Keyed/Mod_Settings.xml b/Common/Languages/English/Keyed/Mod_Settings.xml index d425cd5..cf320c9 100644 --- a/Common/Languages/English/Keyed/Mod_Settings.xml +++ b/Common/Languages/English/Keyed/Mod_Settings.xml @@ -21,10 +21,17 @@ Regret Stealing Love If off, pawns will not get bad thoughts for seduction. - Animal-Mating GenitalCheck If on, only animals that 'can rape' will be engaging in bestiality after being hit by a animal mating pulse. This usually means that only male animals will start breeding. + Genetic STDS + Genetic STD Spread + If checked, certain Genes will spread on sex. + Genetic STDs as Endogenes + If checked, genetic diseases will be added as Endogenes. Otherwise they are added as Xenogenes. + Genetic STDs on penetrative-sex only + If checked, genetic STDs are only spread on penetrative sex. Otherwise, any sextype is considered for spread. + generous-donor cheatmode When enabled, pawns with the 'generous donor' are not drained and not fertilin exhausted. Hence they can fuel succubi and incubi non-stop. This makes them drastically easier to keep, and you should not do it. diff --git a/Common/Languages/English/Keyed/StatsReports.xml b/Common/Languages/English/Keyed/StatsReports.xml new file mode 100644 index 0000000..715bccb --- /dev/null +++ b/Common/Languages/English/Keyed/StatsReports.xml @@ -0,0 +1,8 @@ + + + + Pawn doesn't have any children. + Pawn has a decent amount of children. + Pawn has a lot of children. + + diff --git a/Common/Patches/Xenotypes/PatchImphileeXeno.xml b/Common/Patches/Xenotypes/PatchImphileeXeno.xml new file mode 100644 index 0000000..4a8655f --- /dev/null +++ b/Common/Patches/Xenotypes/PatchImphileeXeno.xml @@ -0,0 +1,36 @@ + + + + +
  • + +
  • Imphilee Xeno
  • + + + Defs/XenotypeDef[defName="LD_Imphilee"]/genes + +
  • rjw_genes_tight_female_genitalia
  • +
  • rjw_genes_small_breasts
  • +
  • rjw_genes_elasticity
  • +
  • rjw_genes_demonic_genitalia
  • +
    +
    + +
  • + +
  • Imphilee Xeno
  • + + + Defs/XenotypeDef[defName="LD_Imphilee_Overlord"]/genes + +
  • rjw_genes_tight_female_genitalia
  • +
  • rjw_genes_small_breasts
  • +
  • rjw_genes_elasticity
  • +
  • rjw_genes_demonic_genitalia
  • +
  • rjw_genes_rapist
  • +
    +
    + +
    +
    +
    diff --git a/Common/Textures/Genes/Icons/Cumflation_Immunity.png b/Common/Textures/Genes/Icons/Cumflation_Immunity.png index 643e0bf..40b40ad 100644 Binary files a/Common/Textures/Genes/Icons/Cumflation_Immunity.png and b/Common/Textures/Genes/Icons/Cumflation_Immunity.png differ diff --git a/Common/Textures/Genes/Icons/FireLeaves.png b/Common/Textures/Genes/Icons/FireLeaves.png new file mode 100644 index 0000000..4f1b247 Binary files /dev/null and b/Common/Textures/Genes/Icons/FireLeaves.png differ diff --git a/Common/Textures/Genes/Icons/FleshPurity.png b/Common/Textures/Genes/Icons/FleshPurity.png new file mode 100644 index 0000000..0843812 Binary files /dev/null and b/Common/Textures/Genes/Icons/FleshPurity.png differ 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/Common/Textures/Genes/Icons/RoundC.png b/Common/Textures/Genes/Icons/RoundC.png new file mode 100644 index 0000000..e2288f5 Binary files /dev/null and b/Common/Textures/Genes/Icons/RoundC.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Cumflation_Immunity.psd b/Common/Textures/Genes/Icons/Samples/Cumflation_Immunity.psd new file mode 100644 index 0000000..06e07e4 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Cumflation_Immunity.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_Fertile.png b/Common/Textures/Genes/Icons/Samples/Gene_Fertile.png new file mode 100644 index 0000000..46abbae Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_Fertile.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_Inbred.png b/Common/Textures/Genes/Icons/Samples/Gene_Inbred.png new file mode 100644 index 0000000..3d8d705 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_Inbred.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_MaxTemperatureLargeIncrease.png b/Common/Textures/Genes/Icons/Samples/Gene_MaxTemperatureLargeIncrease.png new file mode 100644 index 0000000..b07b305 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_MaxTemperatureLargeIncrease.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_MaxTemperatureSmallIncrease копия.png b/Common/Textures/Genes/Icons/Samples/Gene_MaxTemperatureSmallIncrease копия.png new file mode 100644 index 0000000..25ad570 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_MaxTemperatureSmallIncrease копия.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_PsychicBonding.png b/Common/Textures/Genes/Icons/Samples/Gene_PsychicBonding.png new file mode 100644 index 0000000..a558928 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_PsychicBonding.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_PsychicallyDeaf.png b/Common/Textures/Genes/Icons/Samples/Gene_PsychicallyDeaf.png new file mode 100644 index 0000000..9a9eb8c Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_PsychicallyDeaf.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_TotalHealing.png b/Common/Textures/Genes/Icons/Samples/Gene_TotalHealing.png new file mode 100644 index 0000000..dda02fd Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_TotalHealing.png differ diff --git a/Common/Textures/Genes/Icons/Samples/Gene_TotalHealing.psd b/Common/Textures/Genes/Icons/Samples/Gene_TotalHealing.psd new file mode 100644 index 0000000..35dadab Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Gene_TotalHealing.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/Time.png b/Common/Textures/Genes/Icons/Samples/Time.png new file mode 100644 index 0000000..84cc532 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/Time.png differ diff --git a/Common/Textures/Genes/Icons/Samples/blocked_masturbation.psd b/Common/Textures/Genes/Icons/Samples/blocked_masturbation.psd new file mode 100644 index 0000000..79ca75b Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/blocked_masturbation.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/disease_immunity.psd b/Common/Textures/Genes/Icons/Samples/disease_immunity.psd new file mode 100644 index 0000000..f6a0ac3 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/disease_immunity.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/feminizer&twinkifier.psd b/Common/Textures/Genes/Icons/Samples/feminizer&twinkifier.psd new file mode 100644 index 0000000..cfda363 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/feminizer&twinkifier.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/hardwired_progenity.psd b/Common/Textures/Genes/Icons/Samples/hardwired_progenity.psd new file mode 100644 index 0000000..25721ce Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/hardwired_progenity.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/la-copa-menstrual-04.png b/Common/Textures/Genes/Icons/Samples/la-copa-menstrual-04.png new file mode 100644 index 0000000..fdb0ccd Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/la-copa-menstrual-04.png differ diff --git a/Common/Textures/Genes/Icons/Samples/living_cumbucket.psd b/Common/Textures/Genes/Icons/Samples/living_cumbucket.psd new file mode 100644 index 0000000..85796b3 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/living_cumbucket.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/low_fertility.psd b/Common/Textures/Genes/Icons/Samples/low_fertility.psd new file mode 100644 index 0000000..5f6af24 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/low_fertility.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/pregnancy_overwrite.psd b/Common/Textures/Genes/Icons/Samples/pregnancy_overwrite.psd new file mode 100644 index 0000000..eaf1210 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/pregnancy_overwrite.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/rut.psd b/Common/Textures/Genes/Icons/Samples/rut.psd new file mode 100644 index 0000000..b15bcc6 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/rut.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/sexual_genetic_swap.psd b/Common/Textures/Genes/Icons/Samples/sexual_genetic_swap.psd new file mode 100644 index 0000000..354b409 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/sexual_genetic_swap.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/sexual_genetic_thief.psd b/Common/Textures/Genes/Icons/Samples/sexual_genetic_thief.psd new file mode 100644 index 0000000..a2b92b2 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/sexual_genetic_thief.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/size_blinded&stretcher.psd b/Common/Textures/Genes/Icons/Samples/size_blinded&stretcher.psd new file mode 100644 index 0000000..41faa92 Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/size_blinded&stretcher.psd differ diff --git a/Common/Textures/Genes/Icons/Samples/vulnerability.psd b/Common/Textures/Genes/Icons/Samples/vulnerability.psd new file mode 100644 index 0000000..5fdc6aa Binary files /dev/null and b/Common/Textures/Genes/Icons/Samples/vulnerability.psd differ diff --git a/Common/Textures/Genes/Icons/TrialDefend.png b/Common/Textures/Genes/Icons/TrialDefend.png new file mode 100644 index 0000000..1275bf2 Binary files /dev/null and b/Common/Textures/Genes/Icons/TrialDefend.png differ diff --git a/Common/Textures/Genes/Icons/bisexuality.png b/Common/Textures/Genes/Icons/bisexuality.png new file mode 100644 index 0000000..e9356e8 Binary files /dev/null and b/Common/Textures/Genes/Icons/bisexuality.png differ diff --git a/Common/Textures/Genes/Icons/blocked_masturbation.png b/Common/Textures/Genes/Icons/blocked_masturbation.png new file mode 100644 index 0000000..f696996 Binary files /dev/null and b/Common/Textures/Genes/Icons/blocked_masturbation.png differ diff --git a/Common/Textures/Genes/Icons/disease_immunity.png b/Common/Textures/Genes/Icons/disease_immunity.png new file mode 100644 index 0000000..9567e1a Binary files /dev/null and b/Common/Textures/Genes/Icons/disease_immunity.png differ diff --git a/Common/Textures/Genes/Icons/feminizer.png b/Common/Textures/Genes/Icons/feminizer.png new file mode 100644 index 0000000..fafd7ed Binary files /dev/null and b/Common/Textures/Genes/Icons/feminizer.png differ diff --git a/Common/Textures/Genes/Icons/hardwired_progenity.png b/Common/Textures/Genes/Icons/hardwired_progenity.png new file mode 100644 index 0000000..97811e3 Binary files /dev/null and b/Common/Textures/Genes/Icons/hardwired_progenity.png differ diff --git a/Common/Textures/Genes/Icons/homosexuality.png b/Common/Textures/Genes/Icons/homosexuality.png new file mode 100644 index 0000000..cab42c7 Binary files /dev/null and b/Common/Textures/Genes/Icons/homosexuality.png differ diff --git a/Common/Textures/Genes/Icons/living_cumbucket.png b/Common/Textures/Genes/Icons/living_cumbucket.png new file mode 100644 index 0000000..b79f8cc Binary files /dev/null and b/Common/Textures/Genes/Icons/living_cumbucket.png differ diff --git a/Common/Textures/Genes/Icons/low_fertility.png b/Common/Textures/Genes/Icons/low_fertility.png new file mode 100644 index 0000000..0522d94 Binary files /dev/null and b/Common/Textures/Genes/Icons/low_fertility.png differ diff --git a/Common/Textures/Genes/Icons/major_vulnerability.png b/Common/Textures/Genes/Icons/major_vulnerability.png new file mode 100644 index 0000000..6e96a10 Binary files /dev/null and b/Common/Textures/Genes/Icons/major_vulnerability.png differ diff --git a/Common/Textures/Genes/Icons/minor_vulnerability.png b/Common/Textures/Genes/Icons/minor_vulnerability.png new file mode 100644 index 0000000..9a82f52 Binary files /dev/null and b/Common/Textures/Genes/Icons/minor_vulnerability.png differ diff --git a/Common/Textures/Genes/Icons/pregnancy_overwrite.png b/Common/Textures/Genes/Icons/pregnancy_overwrite.png new file mode 100644 index 0000000..9404a6c Binary files /dev/null and b/Common/Textures/Genes/Icons/pregnancy_overwrite.png differ diff --git a/Common/Textures/Genes/Icons/rut.png b/Common/Textures/Genes/Icons/rut.png new file mode 100644 index 0000000..05a0d23 Binary files /dev/null and b/Common/Textures/Genes/Icons/rut.png differ diff --git a/Common/Textures/Genes/Icons/sexual_genetic_swap.png b/Common/Textures/Genes/Icons/sexual_genetic_swap.png new file mode 100644 index 0000000..b0407c4 Binary files /dev/null and b/Common/Textures/Genes/Icons/sexual_genetic_swap.png differ diff --git a/Common/Textures/Genes/Icons/sexual_genetic_thief.png b/Common/Textures/Genes/Icons/sexual_genetic_thief.png new file mode 100644 index 0000000..d871b9f Binary files /dev/null and b/Common/Textures/Genes/Icons/sexual_genetic_thief.png differ diff --git a/Common/Textures/Genes/Icons/size_blinded.png b/Common/Textures/Genes/Icons/size_blinded.png new file mode 100644 index 0000000..824a00d Binary files /dev/null and b/Common/Textures/Genes/Icons/size_blinded.png differ diff --git a/Common/Textures/Genes/Icons/stretcher.png b/Common/Textures/Genes/Icons/stretcher.png new file mode 100644 index 0000000..4c25049 Binary files /dev/null and b/Common/Textures/Genes/Icons/stretcher.png differ diff --git a/Common/Textures/Genes/Icons/twinkifier.png b/Common/Textures/Genes/Icons/twinkifier.png new file mode 100644 index 0000000..3b92f1f Binary files /dev/null and b/Common/Textures/Genes/Icons/twinkifier.png differ diff --git a/LoadFolders.xml b/LoadFolders.xml index 8f11ba4..d3c2a27 100644 --- a/LoadFolders.xml +++ b/LoadFolders.xml @@ -16,5 +16,6 @@
  • Mods/Android
  • Mods/VE_Genetics
  • Mods/LicentiaLabs
  • +
  • Mods/Sexperience
  • \ No newline at end of file diff --git a/Mods/LicentiaLabs/Defs/GeneDefs/LicentiaLabs_GeneDefs.xml b/Mods/LicentiaLabs/Defs/GeneDefs/LicentiaLabs_GeneDefs.xml index 22fb911..a0a7eee 100644 --- a/Mods/LicentiaLabs/Defs/GeneDefs/LicentiaLabs_GeneDefs.xml +++ b/Mods/LicentiaLabs/Defs/GeneDefs/LicentiaLabs_GeneDefs.xml @@ -27,6 +27,8 @@ This Xenotype loves being cumflated. Genes/Icons/Cumflation 536 + -1 + 2
  • LikesCumflation @@ -71,6 +73,8 @@ Genes/Icons/Generous_Donor 538 + 2 + -1
  • Genes/Icons/RJW_Genes_Endogene_Background diff --git a/Common/Defs/HediffDefs/Hediffs_CounterCumflation.xml b/Mods/LicentiaLabs/Defs/HediffDefs/Hediffs_CounterCumflation.xml similarity index 95% rename from Common/Defs/HediffDefs/Hediffs_CounterCumflation.xml rename to Mods/LicentiaLabs/Defs/HediffDefs/Hediffs_CounterCumflation.xml index 1b30c82..282e54f 100644 --- a/Common/Defs/HediffDefs/Hediffs_CounterCumflation.xml +++ b/Mods/LicentiaLabs/Defs/HediffDefs/Hediffs_CounterCumflation.xml @@ -98,15 +98,6 @@
  • -0.75
  • -
  • - -
  • 0
  • -
  • 0
  • -
  • 0.75
  • -
  • 0.5
  • -
  • 0.2
  • - -
  • diff --git a/Mods/Sexperience/Defs/GeneDefs/Sexperience_GeneDefs.xml b/Mods/Sexperience/Defs/GeneDefs/Sexperience_GeneDefs.xml new file mode 100644 index 0000000..1d89b7e --- /dev/null +++ b/Mods/Sexperience/Defs/GeneDefs/Sexperience_GeneDefs.xml @@ -0,0 +1,21 @@ + + + + + rjw_genes_living_cumbucket + + rjw_genes_cum + When this Xenotype partakes in sexual activity, they store cum and produce it as an item. + Genes/Icons/living_cumbucket + 559 + 3 + -2 + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • + + + + \ No newline at end of file diff --git a/Mods/Sexperience/Defs/HediffDefs/Sexperience_HediffDefs.xml b/Mods/Sexperience/Defs/HediffDefs/Sexperience_HediffDefs.xml new file mode 100644 index 0000000..2c55a7a --- /dev/null +++ b/Mods/Sexperience/Defs/HediffDefs/Sexperience_HediffDefs.xml @@ -0,0 +1,94 @@ + + + + rjw_genes_filled_living_cumbucket + HediffWithComps + + This pawn is a (filled) living cum bucket. Thanks to a generous donation, this pawn will slowly generate cum for pickup. + (240,200,110) + false + + false + false + +
  • + -0.5 +
  • +
  • + +
  • 0
  • +
  • 0.5
  • +
  • 0.25
  • +
  • 0.1
  • +
  • 0.5
  • + + +
    + +
  • + + + -0.1 + +
  • +
  • + + 0.4 + 0.8 + + -0.25 + + +
  • + Moving + -0.05 +
  • + + +
  • + + 0.65 + 0.75 + + -0.25 + + +
  • + Moving + -0.1 +
  • + + +
  • + + 1.1 + 0.6 + + -0.5 + + +
  • + Moving + -0.15 +
  • + + +
  • + + 10.1 + 0.1 + + -1.5 + + +
  • + Moving + -0.55 +
  • + + +
    +
    + + +
    diff --git a/Mods/Sexperience/Defs/JobDefs/Sexperience_JobProcessCumbucket.xml b/Mods/Sexperience/Defs/JobDefs/Sexperience_JobProcessCumbucket.xml new file mode 100644 index 0000000..6cbb372 --- /dev/null +++ b/Mods/Sexperience/Defs/JobDefs/Sexperience_JobProcessCumbucket.xml @@ -0,0 +1,15 @@ + + + + + + + ProcessCumbucket + RJW_Genes.JobDriver_ProcessingCumbucket + false + false + processing internal cumbucket. + false + + + diff --git a/README.md b/README.md index 697bcdc..b9e5d14 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # RJW-Genes [NSFW] +[![BuyMeACoffee](https://raw.githubusercontent.com/pachadotdev/buymeacoffee-badges/main/bmc-white.svg)](https://buymeacoffee.com/vegapnk) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + This mod adds genes related and based on RJW to Rimworld. ## Current Features @@ -12,6 +15,7 @@ This mod adds genes related and based on RJW to Rimworld. - Sexual Vampires that need Cum, Cocks or some other sources. - Mech Breeding Additions & Orgasmic Mytosis - Human-Animal Gene Inheritance merged from [Shabakur](https://github.com/Shabakur/RJW_Animal_Gene_Inheritance) +- Genetic Diseases that spread on Intercourse - Patches for some popular / common Xenotypes from other Mods. *You might not see all of them. Many genes just show up if other mods are loaded*. 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/Common/Defs/HediffIncreaseOnSexExtension.cs b/Source/Common/Defs/HediffIncreaseOnSexExtension.cs new file mode 100644 index 0000000..c5f648f --- /dev/null +++ b/Source/Common/Defs/HediffIncreaseOnSexExtension.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class HediffIncreaseOnSexExtension: DefModExtension + { + public HediffDef hediffDef; + public float severityIncrease; + public float applicationChance; + + public bool canCreateHediff; + + public bool applicableForWomen; + public bool applicableForMen; + public bool requiresPenetrativeSex; + } + +} diff --git a/Source/Common/Defs/MultiplierExtension.cs b/Source/Common/Defs/MultiplierExtension.cs new file mode 100644 index 0000000..5be194e --- /dev/null +++ b/Source/Common/Defs/MultiplierExtension.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class MultiplierExtension : DefModExtension + { + public float multiplier; + } +} diff --git a/Source/Common/Defs/TickBasedChanceExtension.cs b/Source/Common/Defs/TickBasedChanceExtension.cs new file mode 100644 index 0000000..1a8feca --- /dev/null +++ b/Source/Common/Defs/TickBasedChanceExtension.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class TickBasedChanceExtension : TickIntervalExtension + { + /// + /// Set to 1 for "always", set to 0 for "never". + /// Everything else is a bit statistics, but e.g. when set to .5 the chances grow per day from [50%, 75%, 82.25%, ...] + /// + public float eventChance; + } +} diff --git a/Source/Common/Helpers/FactionUtility.cs b/Source/Common/Helpers/FactionUtility.cs new file mode 100644 index 0000000..10a4e7c --- /dev/null +++ b/Source/Common/Helpers/FactionUtility.cs @@ -0,0 +1,42 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class FactionUtility + { + + /// + /// Tries to change the goodwill between the factions of two pawns. + /// Exceptions when nothing happens: + /// - Pawns, or Pawns Factions, are null + /// - The `actors` Faction is not the players faction + /// - Both pawns have the same faction + /// - The Event is not found + /// + /// The pawn that initiated a faction-goodwill change by his actions + /// The pawn that was harmed/affected by the action + /// The event defname, for proper reporting + /// How much (positive or negative) the goodwill will change + public static void HandleFactionGoodWillPenalties(Pawn actor, Pawn target, string HistoryEventDefname, int goodWillChange, bool canSendHostileLetter=true) + { + if (actor == null) return; + if (target == null) return; + if ( + target.Faction != null && actor.Faction != null + && target.Faction != actor.Faction + && target.Faction != Faction.OfPlayer) + { + HistoryEventDef reason = DefDatabase.GetNamedSilentFail(HistoryEventDefname); + if (reason == null) return; + + target.Faction.TryAffectGoodwillWith(actor.Faction, goodWillChange, true, canSendHostileLetter, reason, target); + } + } + } +} diff --git a/Source/Common/ModLog.cs b/Source/Common/ModLog.cs index 407520a..b78e675 100644 --- a/Source/Common/ModLog.cs +++ b/Source/Common/ModLog.cs @@ -30,5 +30,12 @@ namespace RJW_Genes Log.Warning($"[{ModId}] {message}"); } + public static void Debug(string message) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + { + Log.Message($"[{ModId}][debug] {message}"); + } + } } } diff --git a/Source/Common/patches/Patch_HediffIncreaseOnSex.cs b/Source/Common/patches/Patch_HediffIncreaseOnSex.cs new file mode 100644 index 0000000..55e85a3 --- /dev/null +++ b/Source/Common/patches/Patch_HediffIncreaseOnSex.cs @@ -0,0 +1,80 @@ +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 "only" applies the hediff increase on sex. + /// It checks for the hediff, creates it if necessary and applicable, + /// and increases it based on the severity, chance and genders specified in the Extension. + /// + /// Some hediffs want follow up logic, e.g. the Feminization Gene, + /// which is handled in an extra patch (that requires the hediff to be present already). + /// + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public class Patch_HediffIncreaseOnSex + { + + public static void Postfix(SexProps props) + { + if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal() || props.pawn.IsAnimal()) + { + return; + } + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (pawn.genes == null || partner.genes == null) return; + + TryApplyHediffsOfSex(pawn, partner, props); + TryApplyHediffsOfSex(partner, pawn, props); + } + + /// + /// Checks for every gene in a pawn if it applies a hediff or the severity of an existing hediff in a sexual partner. + /// If the checks pass, the hediff is added or changed accordingly. + /// + /// Pawn that holds (one or many) genes that might apply a hediff change + /// Pawn that will receive or alter any hediffs, if applicable + /// The Sexprops, used for checking if sex is penetrative + static void TryApplyHediffsOfSex(Pawn pawn, Pawn partner, SexProps props) + { + var random = new Random(); + + foreach (Gene gene in pawn.genes.GenesListForReading) + { + HediffIncreaseOnSexExtension ext = gene.def.GetModExtension(); + if (ext == null) continue; + + if (DiseaseHelper.IsImmuneAgainstGeneticDisease(partner, gene.def)) continue; + if (ext.requiresPenetrativeSex && DiseaseHelper.IsPenetrativeSex(props)) continue; + if (!ext.applicableForMen && partner.gender == Gender.Male) continue; + if (!ext.applicableForWomen && partner.gender == Gender.Female) continue; + if (random.NextDouble() >= ext.applicationChance) continue; + + Hediff hediff = partner.health.hediffSet.GetFirstHediffOfDef(ext.hediffDef); + if (hediff == null) + { + if (!ext.canCreateHediff) continue; + hediff = partner.health.GetOrAddHediff(ext.hediffDef); + hediff.Severity = 0.01f; + ModLog.Debug($"{partner} got hediff {hediff.def.defName} from Patch_HediffIncreaseOnSex ({gene.def.defName}) upon sex with {pawn}"); + } + float initial_severity = hediff.Severity; + ModLog.Debug($"{partner}s hediff {hediff.def.defName} was changed by Patch_HediffIncreaseOnSex ({gene.def.defName}) upon sex with {pawn} [from {initial_severity} to {initial_severity + ext.severityIncrease}]"); + hediff.Severity += ext.severityIncrease; + + // DevNote: I also want to have "negative" hediff changes here, but I think its not necessary. Once the severity reaches 0, or below, the hediff should remove itself. + } + } + + } +} diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs index 6049b8b..c410aea 100644 --- a/Source/GeneDefOf.cs +++ b/Source/GeneDefOf.cs @@ -73,14 +73,18 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_fervent_ovipositor; public static readonly GeneDef rjw_genes_insectbreeder; public static readonly GeneDef rjw_genes_insectincubator; - - // Cum + public static readonly GeneDef rjw_genes_hardwired_progenity; + public static readonly GeneDef rjw_genes_blocked_masturbation; + public static readonly GeneDef rjw_genes_basic_rut; + + // 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; [MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_generous_donor; + [MayRequire("rjw.sexperience")] public static readonly GeneDef rjw_genes_living_cumbucket; // Reproduction @@ -104,12 +108,17 @@ 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; + public static readonly GeneDef rjw_genes_pregnancy_overwrite; + public static readonly GeneDef rjw_genes_feminizer; + public static readonly GeneDef rjw_genes_twinkifier; // Cosmetic public static readonly GeneDef rjw_genes_succubus_tail; public static readonly GeneDef rjw_genes_succubus_wings; - //life force + // Life force | Fertilin public static readonly GeneDef rjw_genes_lifeforce; public static readonly GeneDef rjw_genes_pussyhealing; public static readonly GeneDef rjw_genes_lifeforce_drain; @@ -121,6 +130,21 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_cockeater; public static readonly GeneDef rjw_genes_lifeforce_empath; + // Diseases + public static readonly GeneDef rjw_genes_genetic_disease_immunity; + public static readonly GeneDef rjw_genes_minor_vulnerability; + public static readonly GeneDef rjw_genes_major_vulnerability; + public static readonly GeneDef rjw_genes_fluctual_sexual_needs; + public static readonly GeneDef rjw_genes_size_blinded; + public static readonly GeneDef rjw_genes_infectious_low_fertility; + public static readonly GeneDef rjw_genes_infectious_increased_sex_need; + public static readonly GeneDef rjw_genes_infectious_bisexuality; + 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; + public static readonly GeneDef rjw_genes_infectious_rut; + //Other Defs public static readonly XenotypeDef rjw_genes_succubus; public static readonly DutyDef rjw_genes_flirt; diff --git a/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_ManyChildren.cs b/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_ManyChildren.cs new file mode 100644 index 0000000..c483eb3 --- /dev/null +++ b/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_ManyChildren.cs @@ -0,0 +1,38 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class ConditionalStatAffecter_ManyChildren : ConditionalStatAffecter + { + public override string Label => (string)"StatsReport_ManyChildren".Translate(); + + public const int THRESHOLD_FOR_CHILDREN = 3; + + public override bool Applies(StatRequest req) + { + if (req == null || req.Thing == null || !req.Thing.Spawned) return false; + + if (req.Thing is Pawn pawn) + { + // Do nothing if Pawn is Baby or Child (#25) + if (!pawn.ageTracker.Adult) + return false; + + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_hardwired_progenity)) + { + // This "middle" Conditional Stat Affecter only fires if the other one does not apply + return pawn.relations.ChildrenCount >= THRESHOLD_FOR_CHILDREN + && pawn.relations.ChildrenCount < ConditionalStatAffecter_VeryManyChildren.THRESHOLD_FOR_CHILDREN; + } + } + + return false; + } + } +} diff --git a/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_NoChildren.cs b/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_NoChildren.cs new file mode 100644 index 0000000..4f50994 --- /dev/null +++ b/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_NoChildren.cs @@ -0,0 +1,43 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + /// + /// This conditional stat affecter "fires" if the pawn has no children. + /// + /// DevNote: I salvaged this from 1.3.3 Halamyr Conditional Stat Affecters. + /// It seems that with RW 1.5 there was a change how these work, as the req.Pawn seems to be null. + /// Now, the pawn is in req.Thing. + /// + public class ConditionalStatAffecter_NoChildren : ConditionalStatAffecter + { + public override string Label => (string)"StatsReport_NoChildren".Translate(); + + public override bool Applies(StatRequest req) + { + if (req == null || req.Thing == null || !req.Thing.Spawned) return false; + + if (req.Thing is Pawn pawn) + { + // Do nothing if Pawn is Baby or Child (#25) + if (!pawn.ageTracker.Adult) + return false; + + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_hardwired_progenity)) + { + return pawn.relations.ChildrenCount == 0; + } + } + + return false; + } + + } + +} diff --git a/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_VeryManyChildren.cs b/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_VeryManyChildren.cs new file mode 100644 index 0000000..e14d4f1 --- /dev/null +++ b/Source/Genes/Breeding/ConditionalStatAffecters/ConditionalStatAffecter_VeryManyChildren.cs @@ -0,0 +1,36 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class ConditionalStatAffecter_VeryManyChildren : ConditionalStatAffecter + { + public override string Label => (string)"StatsReport_VeryManyChildren".Translate(); + + public const int THRESHOLD_FOR_CHILDREN = 8; + + public override bool Applies(StatRequest req) + { + if (req == null || req.Thing == null || !req.Thing.Spawned) return false; + + if (req.Thing is Pawn pawn) + { + // Do nothing if Pawn is Baby or Child (#25) + if (!pawn.ageTracker.Adult) + return false; + + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_hardwired_progenity)) + { + return pawn.relations.ChildrenCount >= THRESHOLD_FOR_CHILDREN; + } + } + + return false; + } + } +} diff --git a/Source/Genes/Breeding/Genes/Gene_Rut.cs b/Source/Genes/Breeding/Genes/Gene_Rut.cs new file mode 100644 index 0000000..9240dcd --- /dev/null +++ b/Source/Genes/Breeding/Genes/Gene_Rut.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class Gene_Rut : Gene + { + public override void Tick() + { + base.Tick(); + + if (pawn == null || pawn.genes == null) + return; + + var chanceExtension = this.def.GetModExtension(); + if (chanceExtension == null) return; + + if (pawn.IsHashIntervalTick(chanceExtension.tickInterval)){ + Random r = new Random(); + if (r.NextDouble() < chanceExtension.eventChance) + { + Hediff rut = pawn.health.GetOrAddHediff(HediffDefOf.rjw_genes_genetic_rut); + rut.Severity = 1; + ModLog.Debug($"Pawn {pawn} gained rjw_genes_genetic_rut based on chance."); + } + } + } + } +} 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/Cum/CumUtility.cs b/Source/Genes/Cum/CumUtility.cs index b483aed..dba96b1 100644 --- a/Source/Genes/Cum/CumUtility.cs +++ b/Source/Genes/Cum/CumUtility.cs @@ -34,8 +34,23 @@ namespace RJW_Genes } - //Get total fluidamount a person has. - public static float GetTotalFluidAmount(Pawn pawn, float multiplier = 1f) + /// + /// Looks up the "MultiplierExtensions" Value for a given Gene, with a fall back. + /// Returns the fallback if there is no Extension, or if the Multiplier is smaller than 0. + /// + + public static float LookupCumMultiplier(Gene gene, float FALLBACK = 3.0f) => LookupCumMultiplier(gene.def,FALLBACK); + public static float LookupCumMultiplier(GeneDef def, float FALLBACK = 3.0f) + { + MultiplierExtension multiplier = def.GetModExtension(); + if (multiplier == null || multiplier.multiplier < 0) + return FALLBACK; + else return multiplier.multiplier; + } + + + //Get total fluidamount a person has. + public static float GetTotalFluidAmount(Pawn pawn, float multiplier = 1f) { var partBPR = Genital_Helper.get_genitalsBPR(pawn); var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR); diff --git a/Source/Genes/Cum/Gene_NoCum.cs b/Source/Genes/Cum/Gene_NoCum.cs deleted file mode 100644 index 0c3e888..0000000 --- a/Source/Genes/Cum/Gene_NoCum.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace RJW_Genes -{ - public class Gene_NoCum : RJW_Gene - { - bool has_been_fired = false; - - - public override void PostMake() - { - base.PostMake(); - - CumUtility.MultiplyFluidAmountBy(pawn, 0f); - has_been_fired = true; - } - - public override void PostAdd() - { - base.PostAdd(); - if (!has_been_fired) { - CumUtility.MultiplyFluidAmountBy(pawn, 0f); - has_been_fired = true; - } - } - - - public override void PostRemove() - { - // Cum Removal does not do at the moment :/ I would need to safe the old cum amount but I don't want to at the moment - base.PostAdd(); - - } - - } -} diff --git a/Source/Genes/Cum/Gene_VeryMuchCum.cs b/Source/Genes/Cum/Gene_VeryMuchCum.cs deleted file mode 100644 index 21faecc..0000000 --- a/Source/Genes/Cum/Gene_VeryMuchCum.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RJW_Genes -{ - public class Gene_VeryMuchCum : RJW_Gene - { - bool has_been_fired = false; - - float multiplier_much_cum = 10f; - - public override void PostMake() - { - base.PostMake(); - - CumUtility.MultiplyFluidAmountBy(pawn, multiplier_much_cum); - has_been_fired = true; - } - - public override void PostAdd() - { - base.PostAdd(); - if (!has_been_fired) { - CumUtility.MultiplyFluidAmountBy(pawn, multiplier_much_cum); - has_been_fired = true; - } - } - - - public override void PostRemove() - { - base.PostAdd(); - - if (has_been_fired) - { - CumUtility.MultiplyFluidAmountBy(pawn, 1/multiplier_much_cum); - has_been_fired = false; - } - } - - } -} diff --git a/Source/Genes/Cum/Gene_MuchCum.cs b/Source/Genes/Cum/Genes/Gene_ChangeCumAmount.cs similarity index 51% rename from Source/Genes/Cum/Gene_MuchCum.cs rename to Source/Genes/Cum/Genes/Gene_ChangeCumAmount.cs index e88ac3f..dc10ba4 100644 --- a/Source/Genes/Cum/Gene_MuchCum.cs +++ b/Source/Genes/Cum/Genes/Gene_ChangeCumAmount.cs @@ -1,36 +1,38 @@ namespace RJW_Genes { - public class Gene_MuchCum : RJW_Gene + public class Gene_ChangeCumAmount : RJW_Gene { bool has_been_fired = false; - float multiplier_much_cum = 3f; public override void PostMake() { base.PostMake(); - CumUtility.MultiplyFluidAmountBy(pawn, multiplier_much_cum); + float multipier = CumUtility.LookupCumMultiplier(this); + CumUtility.MultiplyFluidAmountBy(pawn, multipier); has_been_fired = true; } public override void PostAdd() { base.PostAdd(); - if (!has_been_fired) { - CumUtility.MultiplyFluidAmountBy(pawn, multiplier_much_cum); + if (!has_been_fired) + { + float multipier = CumUtility.LookupCumMultiplier(this); + CumUtility.MultiplyFluidAmountBy(pawn, multipier); has_been_fired = true; } } - public override void PostRemove() { base.PostAdd(); if (has_been_fired) { - CumUtility.MultiplyFluidAmountBy(pawn, 1/multiplier_much_cum); + float multipier = CumUtility.LookupCumMultiplier(this); + CumUtility.MultiplyFluidAmountBy(pawn, 1/ multipier); has_been_fired = false; } } diff --git a/Source/Genes/Cum/HediffComp_ProcessCumbucket.cs b/Source/Genes/Cum/HediffComp_ProcessCumbucket.cs new file mode 100644 index 0000000..48708cb --- /dev/null +++ b/Source/Genes/Cum/HediffComp_ProcessCumbucket.cs @@ -0,0 +1,28 @@ + +using RimWorld; +using System; +using Verse; + +namespace RJW_Genes +{ + public class HediffComp_ProcessCumbucket : HediffComp + { + + public HediffsCompProperties_ProcessCumbucketMTB Props + { + get + { + return (HediffsCompProperties_ProcessCumbucketMTB)this.props; + } + } + + public override void CompPostTick(ref float severityAdjustment) + { + if (this.Props.mtbDaysPerStage[this.parent.CurStageIndex] > 0f && base.Pawn.IsHashIntervalTick(60) && Rand.MTBEventOccurs(this.Props.mtbDaysPerStage[this.parent.CurStageIndex], 60000f, 60f)) + { + ModLog.Debug($"Triggered HediffComp_ProcessCumbucket CompPostTick - Starting a JobDriver ProcessCumbucket for {this.parent.pawn}"); + this.Pawn.jobs.StartJob(JobMaker.MakeJob(DefDatabase.GetNamed("ProcessCumbucket")), lastJobEndCondition: Verse.AI.JobCondition.InterruptForced, resumeCurJobAfterwards: true); + } + } + } +} diff --git a/Source/Genes/Cum/HediffsCompProperties_ProcessCumbucketMTB.cs b/Source/Genes/Cum/HediffsCompProperties_ProcessCumbucketMTB.cs new file mode 100644 index 0000000..919b715 --- /dev/null +++ b/Source/Genes/Cum/HediffsCompProperties_ProcessCumbucketMTB.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class HediffsCompProperties_ProcessCumbucketMTB : HediffCompProperties + { + public HediffsCompProperties_ProcessCumbucketMTB() + { + this.compClass = typeof(HediffComp_ProcessCumbucket); + } + + public override IEnumerable ConfigErrors(HediffDef parentDef) + { + foreach (string text in base.ConfigErrors(parentDef)) + { + yield return text; + } + if (this.mtbDaysPerStage == null) + { + yield return "mtbDaysPerStage is not defined"; + } + else if (this.mtbDaysPerStage.Count != parentDef.stages.Count) + { + yield return "mtbDaysPerStage count doesn't match Hediffs number of stages"; + } + yield break; + } + + public List mtbDaysPerStage; + } +} diff --git a/Source/Genes/Cum/JobDriver_ProcessingCumbucket.cs b/Source/Genes/Cum/JobDriver_ProcessingCumbucket.cs new file mode 100644 index 0000000..b924a6d --- /dev/null +++ b/Source/Genes/Cum/JobDriver_ProcessingCumbucket.cs @@ -0,0 +1,132 @@ +using LicentiaLabs; +using System.Collections.Generic; +using Verse; +using Verse.AI; +using UnityEngine; +using System; +using rjw; +using RimWorld; + +namespace RJW_Genes +{ + /// + /// Shamelessly stolen from LicentaLabs + /// [Jaals Fork] https://gitgud.io/Jaaldabaoth/licentia-labs/-/blob/master/Source/LicentiaLabs/LicentiaLabs/JobDriver_VomitCum.cs + /// + class JobDriver_ProcessingCumbucket : JobDriver_Vomit + { + public override bool CanBeginNowWhileLyingDown() + { + return true; + } + + protected override IEnumerable MakeNewToils() + { + if (!ModsConfig.IsActive("rjw.sexperience")) + yield break; + + Toil toil = new Toil(); + toil.initAction = delegate () + { + this.ticksLeft = Rand.Range(150, 600); + int num = 0; + IntVec3 c; + for (; ; ) + { + c = this.pawn.Position + GenAdj.AdjacentCellsAndInside[Rand.Range(0, 9)]; + num++; + if (num > 12) + { + break; + } + if (c.InBounds(this.pawn.Map) && c.Standable(this.pawn.Map)) + { + // DevNote: I am not 100% what this all means, but IL_77 is a jump to the case below (it says IL_77). + // basically, this calls the next part of the function, but I am not super sure why this has to be like this. + // JobDrivers are scary. + goto IL_77; + } + } + c = this.pawn.Position; + IL_77: + this.job.targetA = c; + this.pawn.pather.StopDead(); + }; + toil.tickAction = delegate () + { + if (this.ticksLeft % 150 == 149) + { + if (!sourceName.NullOrEmpty()) + { + if (ModsConfig.IsActive("LustLicentia.RJWLabs")) + FilthMaker.TryMakeFilth(this.job.targetA.Cell, base.Map, Licentia.ThingDefs.FilthCum, sourceName); + SpawnCum(this.pawn, this.job.targetA.Cell, base.Map); + } + else + { + if (ModsConfig.IsActive("LustLicentia.RJWLabs")) + FilthMaker.TryMakeFilth(this.job.targetA.Cell, base.Map, Licentia.ThingDefs.FilthCum); + SpawnCum(this.pawn, this.job.targetA.Cell, base.Map); + } + } + this.ticksLeft--; + if (this.ticksLeft <= 0) + { + base.ReadyForNextToil(); + TaleRecorder.RecordTale(Licentia.TaleDefs.VomitedCum, new object[] + { + this.pawn + }); + } + }; + toil.defaultCompleteMode = ToilCompleteMode.Never; + toil.WithEffect(EffecterDefOf.Vomit, TargetIndex.A, new Color(100f, 100f, 100f, 0.5f)); + toil.PlaySustainerOrSound(() => SoundDefOf.Vomit, 1f); + yield return toil; + yield break; + } + + private void SpawnCum(Pawn pawn, IntVec3 cell, Map map) + { + ThingDef cumDef = DefDatabase.GetNamed("GatheredCum", true); + + Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_filled_living_cumbucket); + if (hediff == null) + { + ModLog.Warning($"{pawn} has the JobDriver_ProcessCumbucket but does not have the Hediff for filled cumbucket."); + return; + } + + // Case 1: "Normal Severity", just puke out a bit of cum here and there. + if (hediff.Severity <= 10) + { + Thing cum = ThingMaker.MakeThing(cumDef); + cum.Position = cell; + int stacks = Math.Max(1, (int)(hediff.Severity * 1.5)); + stacks = Math.Min(stacks, 75); // 75 is the default max stacksize ... + cum.stackCount = stacks; + cum.SpawnSetup(map, false); + hediff.Severity -= (stacks / 50); + } else + // Case 2: Reserviour mode, put out a lot of cum at once but less often. + { + int stacks = Math.Max(1, (int)(hediff.Severity * 1.5)); + + while (stacks > 0) + { + Thing cum = ThingMaker.MakeThing(cumDef); + cum.Position = cell; + var curStacks = Math.Min(stacks, 75); // 75 is the default max stacksize ... + cum.stackCount = stacks; + cum.SpawnSetup(map, false); + hediff.Severity -= (curStacks / 50); + stacks -= curStacks; + } + } + } + + private int ticksLeft; + + public string sourceName; + } +} diff --git a/Source/Genes/Cum/Patch_CumflationImmunity.cs b/Source/Genes/Cum/Patches/Patch_CumflationImmunity.cs similarity index 100% rename from Source/Genes/Cum/Patch_CumflationImmunity.cs rename to Source/Genes/Cum/Patches/Patch_CumflationImmunity.cs diff --git a/Source/Genes/Cum/Patch_LikesCumflation.cs b/Source/Genes/Cum/Patches/Patch_LikesCumflation.cs similarity index 100% rename from Source/Genes/Cum/Patch_LikesCumflation.cs rename to Source/Genes/Cum/Patches/Patch_LikesCumflation.cs diff --git a/Source/Genes/Cum/Patches/Patch_LivingCumbucket_StackHediff.cs b/Source/Genes/Cum/Patches/Patch_LivingCumbucket_StackHediff.cs new file mode 100644 index 0000000..67ec45e --- /dev/null +++ b/Source/Genes/Cum/Patches/Patch_LivingCumbucket_StackHediff.cs @@ -0,0 +1,64 @@ +using HarmonyLib; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using static System.Net.Mime.MediaTypeNames; + +namespace RJW_Genes +{ + + [HarmonyPatch(typeof(SexUtility), nameof(SexUtility.SatisfyPersonal))] + public class Patch_LivingCumbucket_StackHediff + { + + /// + /// This is the amount of fluid required if the pawn has a bodysize of 1, to reach a severity in the hediff of 1. + /// The hediff can still be increased over 1.0. + /// + const float fluid_amount_required_for_hediff_severity_ = 100.0f; + + public static void Postfix(SexProps props) + { + if (!ModsConfig.IsActive("rjw.sexperience")) + return; + + // ShortCuts: Exit Early if Pawn or Partner are null (can happen with Masturbation or other nieche-cases) + if (props == null || props.pawn == null || !props.hasPartner()) + return; + + Pawn pawnA = props.pawn; + Pawn pawnB = props.partner; + + if (pawnA.genes != null && pawnA.genes.HasActiveGene(GeneDefOf.rjw_genes_living_cumbucket) && CumUtility.GetTotalFluidAmount(pawnB) > 0) + { + ProcessLivingCumbucket(pawnA, CumUtility.GetTotalFluidAmount(pawnB)); + } + + if (pawnB.genes != null && pawnB.genes.HasActiveGene(GeneDefOf.rjw_genes_living_cumbucket) && CumUtility.GetTotalFluidAmount(pawnA) > 0) + { + ProcessLivingCumbucket(pawnB, CumUtility.GetTotalFluidAmount(pawnA)); + } + } + + public static void ProcessLivingCumbucket(Pawn pawn, float cumamount) + { + float bodysize = pawn.BodySize; + float result_severity_increase = cumamount / (fluid_amount_required_for_hediff_severity_ * bodysize); + + + Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_filled_living_cumbucket); + if (hediff == null) + { + hediff = pawn.health.GetOrAddHediff(HediffDefOf.rjw_genes_filled_living_cumbucket); + hediff.Severity = 0.01f; + } + + hediff.Severity += result_severity_increase; + ModLog.Debug($"Pumping the living cumbucket {pawn} (Bodysize {bodysize}) with {cumamount} cum, resulting in severity {hediff.Severity} (+{result_severity_increase})"); + } + } +} diff --git a/Source/Genes/Cum/Patch_TransferNutrition.cs b/Source/Genes/Cum/Patches/Patch_TransferNutrition.cs similarity index 100% rename from Source/Genes/Cum/Patch_TransferNutrition.cs rename to Source/Genes/Cum/Patches/Patch_TransferNutrition.cs diff --git a/Source/Genes/Diseases/Defs/GeneticDiseaseExtension.cs b/Source/Genes/Diseases/Defs/GeneticDiseaseExtension.cs new file mode 100644 index 0000000..e156195 --- /dev/null +++ b/Source/Genes/Diseases/Defs/GeneticDiseaseExtension.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class GeneticDiseaseExtension : DefModExtension + { + /// + /// The chance for this gene to spread upon (finished) sex. + /// + public float infectionChance; + } + +} diff --git a/Source/Genes/Diseases/Defs/GeneticInfectorExtension.cs b/Source/Genes/Diseases/Defs/GeneticInfectorExtension.cs new file mode 100644 index 0000000..2f00ce5 --- /dev/null +++ b/Source/Genes/Diseases/Defs/GeneticInfectorExtension.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class GeneticInfectorExtension : DefModExtension + { + public float infectionChance; + + public List infectionGenes; + } + +} diff --git a/Source/Genes/Diseases/Defs/ImmunityAgainstGenesExtension.cs b/Source/Genes/Diseases/Defs/ImmunityAgainstGenesExtension.cs new file mode 100644 index 0000000..18fe8e0 --- /dev/null +++ b/Source/Genes/Diseases/Defs/ImmunityAgainstGenesExtension.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class ImmunityAgainstGenesExtension : DefModExtension + { + /// + /// A list of the exact defnames of disease-genes that this extension will make immune against. + /// Must perfectly match! + /// + public List givesImmunityAgainst; + } + +} diff --git a/Source/Genes/Diseases/DiseaseHelper.cs b/Source/Genes/Diseases/DiseaseHelper.cs new file mode 100644 index 0000000..873a0e1 --- /dev/null +++ b/Source/Genes/Diseases/DiseaseHelper.cs @@ -0,0 +1,145 @@ +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public static class DiseaseHelper + { + + /// + /// Checks for a pawn if it is immune against a disease. + /// + /// The pawn for which immunity is checked + /// The genetic disease that is checked against + /// True if the pawn is immune, false if the pawn can be infected by it. + public static bool IsImmuneAgainstGeneticDisease(Pawn pawn, GeneDef disease) + { + // Case 1: Something is null / not working, return Immune (to have less follow up effects) + if (pawn == null || pawn.genes == null) return true; + if (disease == null) return true; + // Case 1.B: Dead people can spread, but not receive, diseases. + if (pawn.Dead) return true; + + // Case 2: The pawn has general genetic immunity to diseases + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_genetic_disease_immunity)) + return true; + + // Case 3: The pawn already has the genetic disease + if (GeneUtility.HasGeneNullCheck(pawn, disease)) + return true; + + // Case 4: Check all genes if one of them has the Immunity Extension that covers the GeneDef + List genes = pawn.genes.GenesListForReading; + genes = genes.Where(x => pawn.genes.HasActiveGene(x.def)).ToList(); + + foreach (Gene gene in genes) + { + ImmunityAgainstGenesExtension ext = gene.def.GetModExtension(); + if (ext != null) { + foreach (string defname in ext.givesImmunityAgainst) + if (disease.defName == defname) + return true; + } + } + + // Case 5: Nothing special happens, so return false (not immune) + return false; + } + + /// + /// Returns all active Genes with the `GeneticDiseaseExtension`. + /// + /// + /// List of all active Genes with the `GeneticDiseaseExtension` in pawn + public static List GetGeneticDiseaseGenes(Pawn pawn) + { + if (pawn != null && pawn.genes != null) + { + return pawn.genes + .GenesListForReading + .ConvertAll(gene => gene.def) + .Where(genedef => pawn.genes.HasActiveGene(genedef)) + .Where(IsGeneticDiseaseGene) + .ToList(); + } + + return new List() { }; + } + + public static List GetGeneticInfectorGenes(Pawn pawn) + { + if (pawn != null && pawn.genes != null) + { + return pawn.genes + .GenesListForReading + .ConvertAll(gene => gene.def) + .Where(genedef => pawn.genes.HasActiveGene(genedef)) + .Where(IsGeneticInfectorGene) + .ToList(); + } + + return new List() { }; + } + + public static List LookupInfectionGeneDefs(GeneticInfectorExtension infectorExt) + { + if (infectorExt == null) new List(); + + return RimWorld.GeneUtility + .GenesInOrder + .Where(genedef => infectorExt.infectionGenes.Contains(genedef.defName)) + .ToList(); + } + + /// + /// Checks if the performed sex was penetrative. + /// Condom check is not done here! + /// + /// The sexprops + /// + public static bool IsPenetrativeSex(SexProps props) + { + if (props == null) return false; + + return props.sexType == + xxx.rjwSextype.Vaginal + || props.sexType == xxx.rjwSextype.Anal + || props.sexType == xxx.rjwSextype.Oral + || props.sexType == xxx.rjwSextype.DoublePenetration + || props.sexType == xxx.rjwSextype.Fellatio + || props.sexType == xxx.rjwSextype.Sixtynine; + } + + public static bool IsGeneticDiseaseGene(GeneDef geneDef) + { + if (geneDef == null) return false; + GeneticDiseaseExtension diseaseExt = geneDef.GetModExtension(); + return diseaseExt != null; + } + + public static bool IsGeneticInfectorGene(GeneDef geneDef) + { + if (geneDef == null) return false; + GeneticInfectorExtension infectorExt = geneDef.GetModExtension(); + return infectorExt != null; + } + + public static float LookupDiseaseInfectionChance(GeneDef geneDef) + { + if (IsGeneticDiseaseGene(geneDef)) + { + GeneticDiseaseExtension diseaseExt = geneDef.GetModExtension(); + return diseaseExt != null ? diseaseExt.infectionChance : 0.0f; + } + else + return 0.0f; + } + + + } +} diff --git a/Source/Genes/Diseases/Genes/Gene_FluctualSexualNeed.cs b/Source/Genes/Diseases/Genes/Gene_FluctualSexualNeed.cs new file mode 100644 index 0000000..b25e812 --- /dev/null +++ b/Source/Genes/Diseases/Genes/Gene_FluctualSexualNeed.cs @@ -0,0 +1,57 @@ +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using static HarmonyLib.Code; +using static RimWorld.ColonistBar; + +namespace RJW_Genes +{ + public class Gene_FluctualSexualNeed : Gene + { + + int event_interval; + float event_chance; + + const float REST_INCREASE = 0.1f; + const float SET_SEXNEED_TO = 0.1f; + + public Gene_FluctualSexualNeed() : base() + { + TickBasedChanceExtension tickbasedChanceExt = GeneDefOf.rjw_genes_fluctual_sexual_needs.GetModExtension(); + event_interval = tickbasedChanceExt?.tickInterval ?? 30000; // 30K = 1/2 day + event_chance = tickbasedChanceExt?.eventChance ?? 0.1f; + } + + + public override void Tick() + { + base.Tick(); + + if (pawn.IsHashIntervalTick(event_interval) && (new Random()).NextDouble() < event_chance) + { + ModLog.Debug($"Firing Gene_FluctualSexualNeed for {pawn}"); + ApplyFluctualSexNeedEffect(pawn); + } + } + + public static void ApplyFluctualSexNeedEffect(Pawn pawn) + { + if (pawn == null || pawn.needs == null) return; + + var sexneed = pawn.needs.TryGetNeed(); + if (sexneed != null) + { + sexneed.CurLevelPercentage = SET_SEXNEED_TO; + } + + // Pump up Wake-Ness + if (pawn.needs.rest != null) + pawn.needs.rest.CurLevel += REST_INCREASE; + } + + } +} diff --git a/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs b/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs new file mode 100644 index 0000000..06b0998 --- /dev/null +++ b/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs @@ -0,0 +1,64 @@ +using HarmonyLib; +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Lifetime; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public class Patch_AfterSexUtility_ApplyGeneticInfectors + { + + const int FACTION_GOODWILL_CHANGE = -3; + + public static void Postfix(SexProps props) + { + if (props == null || props.pawn == null || props.partner == null) return; + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (pawn == partner) return; + if (pawn.IsAnimal() || partner.IsAnimal()) return; + if (pawn.genes == null || partner.genes == null) return; + // No Infections on Condom Use + if (props.usedCondom) return; + + // Exit early if settings require penetrative sex, but this is not penetrative sex + if (!DiseaseHelper.IsPenetrativeSex(props) && RJW_Genes_Settings.rjw_genes_genetic_disease_spread_only_on_penetrative_sex) return; + + TryApplyGeneticInfections(pawn, partner); + TryApplyGeneticInfections(partner, pawn); + } + + private static void TryApplyGeneticInfections(Pawn infector, Pawn partner) + { + foreach (GeneDef infectorGeneDef in DiseaseHelper.GetGeneticInfectorGenes(infector)) + { + GeneticInfectorExtension diseaseExt = infectorGeneDef.GetModExtension(); + if (diseaseExt == null) continue; + float application_chance = diseaseExt.infectionChance; + + foreach (GeneDef diseaseGeneDef in DiseaseHelper.LookupInfectionGeneDefs(diseaseExt)) + { + if (DiseaseHelper.IsImmuneAgainstGeneticDisease(partner, diseaseGeneDef)) + continue; + + if ((new Random()).NextDouble() < application_chance) + { + partner.genes.AddGene(diseaseGeneDef, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + FactionUtility.HandleFactionGoodWillPenalties(infector, partner, "rjw_genes_GoodwillChangedReason_infected_with_disease",FACTION_GOODWILL_CHANGE); + } + } + } + } + + } +} diff --git a/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs b/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs new file mode 100644 index 0000000..a00d40f --- /dev/null +++ b/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs @@ -0,0 +1,60 @@ +using HarmonyLib; +using RimWorld; +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_AftersexUtility_TransferGeneticDiseases + { + + public const int FACTION_GOODWILL_CHANGE = -2; + + public static void Postfix(SexProps props) + { + if (!RJW_Genes_Settings.rjw_genes_genetic_disease_spread) return; + + if (props == null || props.pawn == null || props.partner == null) return; + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (pawn == partner) return; + if (pawn.IsAnimal() || partner.IsAnimal()) return; + if (pawn.genes == null || partner.genes == null) return; + // No Infections on Condom Use + if (props.usedCondom) return; + + // Exit early if settings require penetrative sex, but this is not penetrative sex + if (!DiseaseHelper.IsPenetrativeSex(props) && RJW_Genes_Settings.rjw_genes_genetic_disease_spread_only_on_penetrative_sex) return; + + //ModLog.Debug($"Firing Patch_TransferGeneticDiseases for {pawn} and {partner}"); + TryTransferGeneticDiseases(pawn, partner, props); + TryTransferGeneticDiseases(partner, pawn, props); + } + + private static void TryTransferGeneticDiseases(Pawn infector, Pawn infected, SexProps props) + { + + foreach (GeneDef disease in DiseaseHelper.GetGeneticDiseaseGenes(infector)) { + ModLog.Debug($"Found genetic disease {disease} in {infector}, trying to infect {infected}"); + + if (DiseaseHelper.IsImmuneAgainstGeneticDisease(infected,disease)) + continue; + + if ((new Random()).NextDouble() <= DiseaseHelper.LookupDiseaseInfectionChance(disease)) + { + infected.genes.AddGene(disease, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes); + FactionUtility.HandleFactionGoodWillPenalties(infector, infected, "rjw_genes_GoodwillChangedReason_spread_genetic_disease", FACTION_GOODWILL_CHANGE); + } + } + } + + } +} diff --git a/Source/Genes/Diseases/Patches/Patch_SecondaryRomanceChanceFactor_Gene_SizeBlinded.cs b/Source/Genes/Diseases/Patches/Patch_SecondaryRomanceChanceFactor_Gene_SizeBlinded.cs new file mode 100644 index 0000000..fa36398 --- /dev/null +++ b/Source/Genes/Diseases/Patches/Patch_SecondaryRomanceChanceFactor_Gene_SizeBlinded.cs @@ -0,0 +1,56 @@ +using HarmonyLib; +using RimWorld; +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 helps with the gene `rjw_genes_size_blinded`. + /// Within RJW the CasualSexHelper utilizes the basefunction "pawn.relations.SecondaryRomanceChanceFactor" + /// https://gitgud.io/Ed86/rjw/-/blob/master/1.5/Source/Common/Helpers/CasualSex_Helper.cs + /// + /// We check on hookup for the other pawn if they have a penis. + /// If yes, we modulate the romance chance based on the following: + /// (Severity * BodySize - 0.5) * romance_multiplier + /// So pawns with a cock smaller than 0.5 will be penalized, while pawns with more than 0.5 will be preferred. + /// + [HarmonyPatch(typeof(Pawn_RelationsTracker), "SecondaryRomanceChanceFactor")] + public class Patch_SecondaryRomanceChanceFactor_Gene_SizeBlinded + { + + const float romance_multiplier = 2f; + + public static void Postfix( Pawn ___pawn, Pawn otherPawn, ref float __result) + { + if (otherPawn == null || ___pawn == null || ___pawn.genes == null || otherPawn.genes == null) + { + return; + } + if (___pawn.genes.HasActiveGene(GeneDefOf.rjw_genes_size_blinded) && Genital_Helper.has_penis_fertile(otherPawn) || (Genital_Helper.has_penis_infertile(otherPawn))) + { + Hediff biggest_cock = GenitaliaUtility.GetBiggestPenis(otherPawn); + if (biggest_cock != null) + { + float bodysize = GenitaliaUtility.GetBodySizeOfSexPart(biggest_cock); + // Bodysize can only be a bonus, not a minus. + bodysize = Math.Max(1.0f, bodysize); + + float attraction_bonus = (biggest_cock.Severity * bodysize - 0.5f) * romance_multiplier; + float result_backup = __result; + __result += attraction_bonus; + // Don't make it smaller than 0, to not get issues. + __result = __result < 0 ? 0.0f : __result; + + ModLog.Debug($"Gene_SizeBlind: Modulate Romance-Chance {___pawn}-->{otherPawn} from {result_backup} by {attraction_bonus} to {__result}"); + } + } + } + + } +} diff --git a/Source/Genes/Diseases/Thoughts/ThoughtWorker_HasMoreDiseasesThanMe_Social.cs b/Source/Genes/Diseases/Thoughts/ThoughtWorker_HasMoreDiseasesThanMe_Social.cs new file mode 100644 index 0000000..7a85eb3 --- /dev/null +++ b/Source/Genes/Diseases/Thoughts/ThoughtWorker_HasMoreDiseasesThanMe_Social.cs @@ -0,0 +1,59 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class ThoughtWorker_HasMoreDiseasesThanMe_Social : ThoughtWorker + { + protected override ThoughtState CurrentSocialStateInternal(Pawn pawn, Pawn other) + { + // Return for trivial errors + if (pawn == null || other == null || pawn == other) + return (ThoughtState)false; + // Check for position-existance + if (pawn.Position == null || other.Position == null || pawn.Map == null || other.Map == null) + return (ThoughtState)false; + // Do nothing if pawn is carried + if (pawn.CarriedBy != null) + return (ThoughtState)false; + // Do nothing if Pawn is Baby or Child (#25) + if (!pawn.ageTracker.Adult) + return (ThoughtState)false; + if (!other.ageTracker.Adult) + return (ThoughtState)false; + // Only check if they are spawned humans + if (!pawn.Spawned || !other.Spawned) + return (ThoughtState)false; + if (!pawn.RaceProps.Humanlike) + return (ThoughtState)false; + if (!other.RaceProps.Humanlike) + return (ThoughtState)false; + + // Pawns that have not "met" wont give each other Mali + // Known-Each-Other is a key-word for Rimworld that shows they have had any interaction and stored each other in relations. + if (!RelationsUtility.PawnsKnowEachOther(pawn, other)) + return (ThoughtState)false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!MapUtility.PawnIsOnHomeMap(pawn)) + return (ThoughtState)false; + + int pawn_diseases = DiseaseHelper.GetGeneticDiseaseGenes(pawn).Count(); + int other_diseases = DiseaseHelper.GetGeneticDiseaseGenes(other).Count(); + int disease_diff = other_diseases - pawn_diseases; + + if (disease_diff >= 5) + return ThoughtState.ActiveAtStage(2); + else if (disease_diff >= 2) + return ThoughtState.ActiveAtStage(1); + else if (disease_diff >= 1) + return ThoughtState.ActiveAtStage(0); + else + return (ThoughtState)false; + } + } +} diff --git a/Source/Genes/Diseases/Thoughts/ThoughtWorker_SizeBlinded_Social.cs b/Source/Genes/Diseases/Thoughts/ThoughtWorker_SizeBlinded_Social.cs new file mode 100644 index 0000000..61199a6 --- /dev/null +++ b/Source/Genes/Diseases/Thoughts/ThoughtWorker_SizeBlinded_Social.cs @@ -0,0 +1,69 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace RJW_Genes +{ + public class ThoughtWorker_SizeBlinded_Social : ThoughtWorker + { + protected override ThoughtState CurrentSocialStateInternal(Pawn pawn, Pawn other) + { + // Return for trivial errors + if (pawn == null || other == null || pawn == other) + return (ThoughtState)false; + // Check for position-existance + if (pawn.Position == null || other.Position == null || pawn.Map == null || other.Map == null) + return (ThoughtState)false; + // Do nothing if pawn is carried + if (pawn.CarriedBy != null) + return (ThoughtState)false; + // Do nothing if Pawn is Baby or Child (#25) + if (!pawn.ageTracker.Adult) + return (ThoughtState)false; + if (!other.ageTracker.Adult) + return (ThoughtState)false; + // Only check if they are spawned humans + if (!pawn.Spawned || !other.Spawned) + return (ThoughtState)false; + if (!pawn.RaceProps.Humanlike) + return (ThoughtState)false; + if (!other.RaceProps.Humanlike) + return (ThoughtState)false; + + // Pawns that have not "met" wont give each other Mali + // Known-Each-Other is a key-word for Rimworld that shows they have had any interaction and stored each other in relations. + if (!RelationsUtility.PawnsKnowEachOther(pawn, other)) + return (ThoughtState)false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!MapUtility.PawnIsOnHomeMap(pawn)) + return (ThoughtState)false; + + + // Do nothing if there is no size-blinded involved + if (!GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_size_blinded)) + return (ThoughtState)false; + else + ModLog.Debug($"{pawn} has the size blinded gene"); + + // Iff the pawn has a penis, retrieve it's size. + var penis = GenitaliaUtility.GetBiggestPenis(other); + // Do Nothing if the other pawn has no penis + if (penis == null) return (ThoughtState)false; + var bodysize = GenitaliaUtility.GetBodySizeOfSexPart(penis); + + if (penis.Severity + (bodysize) - 1.0 > 1.0) + return ThoughtState.ActiveAtStage(2); + else if (penis.Severity >= 0.8f) + return ThoughtState.ActiveAtStage(1); + else + return ThoughtState.ActiveAtStage(0); + + } + } +} diff --git a/Source/Genes/Gender/Defs/GenderFluidExtension.cs b/Source/Genes/Gender/Defs/GenderFluidExtension.cs deleted file mode 100644 index 332015f..0000000 --- a/Source/Genes/Gender/Defs/GenderFluidExtension.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Verse; - -namespace RJW_Genes -{ - public class GenderFluidExtension : DefModExtension - { - /// - /// Number of ticks until the change can be triggered. - /// Just being "triggered" does not mean changing, see the changeChance below. - /// - public int changeInterval; - - /// - /// How high is the chance to change gender? - /// Set to 1 for "always", set to 0 for "never". - /// Everything else is a bit statistics, but e.g. when set to .5 the chances grow per day from [50%, 75%, 82.25%, ...] - /// - public float changeChance; - } -} \ No newline at end of file diff --git a/Source/Genes/Gender/Gene_FemaleOnly.cs b/Source/Genes/Gender/Genes/Gene_FemaleOnly.cs similarity index 100% rename from Source/Genes/Gender/Gene_FemaleOnly.cs rename to Source/Genes/Gender/Genes/Gene_FemaleOnly.cs diff --git a/Source/Genes/Gender/Gene_GenderFluid.cs b/Source/Genes/Gender/Genes/Gene_GenderFluid.cs similarity index 96% rename from Source/Genes/Gender/Gene_GenderFluid.cs rename to Source/Genes/Gender/Genes/Gene_GenderFluid.cs index bdd5c00..fe75f5d 100644 --- a/Source/Genes/Gender/Gene_GenderFluid.cs +++ b/Source/Genes/Gender/Genes/Gene_GenderFluid.cs @@ -39,9 +39,9 @@ namespace RJW_Genes private bool sexChangeWasBlocked = false; public Gene_GenderFluid() : base() { - GenderFluidExtension genderFluidExt = GeneDefOf.rjw_genes_gender_fluid.GetModExtension(); - change_interval = genderFluidExt?.changeInterval ?? CHANGE_INTERVAL_FALLBACK; - switch_chance = genderFluidExt?.changeChance ?? SWITCH_CHANCE_FALLBACK; + TickBasedChanceExtension tickbasedChanceExt = GeneDefOf.rjw_genes_gender_fluid.GetModExtension(); + change_interval = tickbasedChanceExt?.tickInterval ?? CHANGE_INTERVAL_FALLBACK; + switch_chance = tickbasedChanceExt?.eventChance ?? SWITCH_CHANCE_FALLBACK; } public override void Tick() diff --git a/Source/Genes/Gender/Gene_MaleOnly.cs b/Source/Genes/Gender/Genes/Gene_MaleOnly.cs similarity index 100% rename from Source/Genes/Gender/Gene_MaleOnly.cs rename to Source/Genes/Gender/Genes/Gene_MaleOnly.cs diff --git a/Source/Genes/Genitalia/GenitaliaUtility.cs b/Source/Genes/Genitalia/GenitaliaUtility.cs index 6a6ba79..581ba64 100644 --- a/Source/Genes/Genitalia/GenitaliaUtility.cs +++ b/Source/Genes/Genitalia/GenitaliaUtility.cs @@ -73,5 +73,48 @@ namespace RJW_Genes { return candidate.def.defName.ToLower().Contains("breast"); } + + /// + /// Returns the biggest penis of a pawn. + /// In case of a identical severity, the highest body size is returned. + /// For women, or pawns without a penis, null is returned. + /// + /// + /// The biggest penis of a pawn. Null on women or error. + public static Hediff GetBiggestPenis(Pawn pawn) + { + Hediff best = null; + var parts = Genital_Helper.get_AllPartsHediffList(pawn); + + foreach (var part in parts) + { + if (Genital_Helper.is_sex_part(part) && Genital_Helper.is_penis(part)) + { + if (best == null) best = part; + + // On a draw of size, we check the body-size. + if (part.Severity == best.Severity) { + var partSize = part.TryGetComp(); + var bestSize = part.TryGetComp(); + if (partSize == null || bestSize == null) { continue; } + + best = partSize.SizeOwner > bestSize.SizeOwner ? part : best; + } else if (part.Severity > best.Severity) { + best = part; + } + } + } + + return best; + } + + public static float GetBodySizeOfSexPart(Hediff part) + { + if (part == null || part.TryGetComp() == null) + return 0.0f; + else + return part.TryGetComp().SizeOwner; + } } + } diff --git a/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs b/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs index adae607..b7de209 100644 --- a/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs +++ b/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs @@ -17,8 +17,6 @@ namespace RJW_Genes public abstract class Gene_GenitaliaResizingGene : RJW_Gene { - - /// /// Whether or not the gene was already applied. /// If not, it is checked on every birthday and will be applied accordingly. diff --git a/Source/Genes/Special/Defs/GeneAlteringExtension.cs b/Source/Genes/Special/Defs/GeneAlteringExtension.cs new file mode 100644 index 0000000..64b40d4 --- /dev/null +++ b/Source/Genes/Special/Defs/GeneAlteringExtension.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + public class GeneAlteringExtension : DefModExtension + { + public List minorGenes; + public List majorGenes; + + public float minorApplicationChance; + public float majorApplicationChance; + } +} diff --git a/Source/Genes/Special/Patches/Patch_AgeDrain.cs b/Source/Genes/Special/Patches/Patch_AgeDrain.cs index ab159b1..059baef 100644 --- a/Source/Genes/Special/Patches/Patch_AgeDrain.cs +++ b/Source/Genes/Special/Patches/Patch_AgeDrain.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using RimWorld; using rjw; using System; using System.Collections.Generic; @@ -24,6 +25,8 @@ namespace RJW_Genes.Genes.Special // 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1; + const int FACTION_GOODWILL_CHANGE = -1; + public static void Postfix(SexProps props) { if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal() ) @@ -80,6 +83,9 @@ namespace RJW_Genes.Genes.Special if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"[Sexual Age Drainer] {receiver} was too young ({receiver.ageTracker.AgeBiologicalYears}), and remains unchanged."); } + + FactionUtility.HandleFactionGoodWillPenalties(receiver, giver, "rjw_genes_GoodwillChangedReason_aged_pawn_with_sex_gene",FACTION_GOODWILL_CHANGE); } + } } diff --git a/Source/Genes/Special/Patches/Patch_Feminizer.cs b/Source/Genes/Special/Patches/Patch_Feminizer.cs new file mode 100644 index 0000000..4259654 --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_Feminizer.cs @@ -0,0 +1,113 @@ +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 + { + + static GeneAlteringExtension geneAlteringExtension = GeneDefOf.rjw_genes_feminizer.GetModExtension(); + + 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; + + if (geneAlteringExtension == null) + { + ModLog.Warning("Did not find a (well-formed) GeneAlteringExtension for Feminizer"); + 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() < geneAlteringExtension.majorApplicationChance) + MajorChange(pawn); + } break; + case float f when f > 0.6f: + { + if (Random.NextDouble() < geneAlteringExtension.minorApplicationChance) + 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 = geneAlteringExtension.minorGenes.ToList(); + 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 = geneAlteringExtension.majorGenes.ToList(); + 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_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..d61f0bd --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs @@ -0,0 +1,75 @@ +using HarmonyLib; +using RimWorld; +using RimWorld.Planet; +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 const int FACTION_GOODWILL_CHANGE = -10; + + 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); + + FactionUtility.HandleFactionGoodWillPenalties(stealer, victim, "rjw_genes_GoodwillChangedReason_StoleGene", FACTION_GOODWILL_CHANGE); + } + + } +} 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/Genes/Special/Patches/Patch_PregnancyOverwrite.cs b/Source/Genes/Special/Patches/Patch_PregnancyOverwrite.cs new file mode 100644 index 0000000..704a2bd --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_PregnancyOverwrite.cs @@ -0,0 +1,101 @@ +using HarmonyLib; +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using static HarmonyLib.Code; + +namespace RJW_Genes +{ + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public class Patch_PregnancyOverwrite + { + public const int FACTION_GOODWILL_CHANGE = -5; + + 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_pregnancy_overwrite) + && GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_pregnancy_overwrite)) + return; + + // If both are pregnant, we have some weird interaction. Exit Early + if (pawn.IsPregnant() && partner.IsPregnant()) + return; + // If neither are pregnant, nothing can happen. + if (!pawn.IsPregnant() && !partner.IsPregnant()) + return; + + if (pawn.IsPregnant() + && GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_pregnancy_overwrite)) + TryReplacePregnancy(partner, pawn); + + if (partner.IsPregnant() + && GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_pregnancy_overwrite)) + TryReplacePregnancy(pawn, partner); + } + + /// + /// Tries to replace an existing pregnancy with a new pregnancy at the same gestation process. + /// The new pregnancy will have the same mother, but a new father and a new set of genes. + /// + /// There is a check for pregnancy that checks for the general fertility (using Vanilla Functions) and multiplies it with a xml-configurable chance. + /// If anything is replaced, there will be a faction penalty applied. + /// + /// + /// + public static void TryReplacePregnancy(Pawn replacer, Pawn pregnant) + { + + // DevNote: + // There are some issues with just checking PregnancyUtility.PregnancyChanceForPartners or rjw.PregnancyHelper.CanImpregnate + // Both do give 0.0 chance when the pawn is already pregnant, which does not help me :/ + Hediff pregnancyHediff = PregnancyUtility.GetPregnancyHediff(pregnant); + if (pregnancyHediff == null) + return; + + if (DiseaseHelper.IsImmuneAgainstGeneticDisease(pregnant, GeneDefOf.rjw_genes_pregnancy_overwrite)) + { + ModLog.Debug($"{pregnant} is immune against rjw_genes_pregnancy_overwrite from {replacer}"); + return; + } + + ChanceExtension chanceExt = GeneDefOf.rjw_genes_pregnancy_overwrite.GetModExtension(); + float chance = chanceExt != null ? chanceExt.chance : 0.25f; + float replacerFert = replacer.GetStatValueForPawn(StatDefOf.Fertility, replacer); + chance *= replacerFert ; + double roll = (new Random()).NextDouble(); + if (roll < chance) + { + ModLog.Debug($"Pregnancy-Overwrite for {replacer} and {pregnant}."); + float gestationProgress = pregnancyHediff.Severity; + + PregnancyUtility.ForceEndPregnancy(pregnant); + + PregnancyHelper.StartVanillaPregnancy(pregnant, replacer); + Hediff replacementPregnancyHediff = PregnancyUtility.GetPregnancyHediff(pregnant); + replacementPregnancyHediff.Severity = gestationProgress; + + FactionUtility.HandleFactionGoodWillPenalties(replacer, pregnant, "rjw_genes_GoodwillChangedReason_OverwritePregnancy", FACTION_GOODWILL_CHANGE); + } else + { + ModLog.Debug($"Did not Pregnancy-Overwrite for {replacer} and {pregnant}. Failed: Rolled {roll} <({chanceExt.chance}[XML-Chance] x {replacerFert} [Fert:{replacer}])"); + } + } + + } +} diff --git a/Source/Genes/Special/Patches/Patch_Twinkifier.cs b/Source/Genes/Special/Patches/Patch_Twinkifier.cs new file mode 100644 index 0000000..b7205fb --- /dev/null +++ b/Source/Genes/Special/Patches/Patch_Twinkifier.cs @@ -0,0 +1,116 @@ +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_twinkifier`. + /// It requires the hediff `rjw_genes_twinkification_in_progress` which is managed separately, in `Patch_HediffIncreaseOnSex`. + /// + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + public static class Patch_Twinkifier + { + + static GeneAlteringExtension geneAlteringExtension = GeneDefOf.rjw_genes_twinkifier.GetModExtension(); + + 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; + + if (geneAlteringExtension == null) + { + ModLog.Warning("Did not find a (well-formed) GeneAlteringExtension for Twinkifier"); + return; + } + + ApplyTwinkification(props.pawn); + ApplyTwinkification(props.partner); + } + + private static void ApplyTwinkification(Pawn pawn) + { + if (pawn == null) return; + Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_twinkification_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() < geneAlteringExtension.majorApplicationChance) + MajorChange(pawn); + } break; + case float f when f > 0.6f: + { + if (Random.NextDouble() < geneAlteringExtension.minorApplicationChance) + 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) + { + List possibleGenes = geneAlteringExtension.minorGenes.ToList(); + + 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) + { + List possibleGenes = geneAlteringExtension.majorGenes.ToList(); + + 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/Genes/Special/Patches/Patch_Youth_Fountain.cs b/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs index d810bc6..96ba204 100644 --- a/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs +++ b/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using RimWorld; using rjw; using System; using System.Collections.Generic; @@ -23,6 +24,8 @@ namespace RJW_Genes.Genes.Special // 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1; + const int FACTION_GOODWILL_CHANGE = 1; + public static void Postfix(SexProps props) { if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal()) @@ -39,10 +42,12 @@ namespace RJW_Genes.Genes.Special if (GeneUtility.IsYouthFountain(props.pawn)) { ChangeAgeForPawn(props.partner, props.pawn); + FactionUtility.HandleFactionGoodWillPenalties(props.pawn, props.partner, "rjw_genes_GoodwillChangedReason_youthed_pawn_with_sex_gene",+1); } if (GeneUtility.IsYouthFountain(props.partner)) { ChangeAgeForPawn(props.pawn,props.partner); + FactionUtility.HandleFactionGoodWillPenalties(props.pawn, props.partner, "rjw_genes_GoodwillChangedReason_youthed_pawn_with_sex_gene", +1); } } @@ -65,6 +70,7 @@ namespace RJW_Genes.Genes.Special ModLog.Message($"[Youth Fountain] {ToYouth} was too young ({ToYouth.ageTracker.AgeBiologicalYears}), and remains unchanged."); } + } } diff --git a/Source/Genes/Special/Thoughts/ThoughtWorker_Aphrodisiac_Pheromones_Social.cs b/Source/Genes/Special/Thoughts/ThoughtWorker_Aphrodisiac_Pheromones_Social.cs index b236fc9..6ae9fca 100644 --- a/Source/Genes/Special/Thoughts/ThoughtWorker_Aphrodisiac_Pheromones_Social.cs +++ b/Source/Genes/Special/Thoughts/ThoughtWorker_Aphrodisiac_Pheromones_Social.cs @@ -40,10 +40,20 @@ namespace RJW_Genes // If the pawn is not on Map (e.g. caravan), no mali if (!MapUtility.PawnIsOnHomeMap(pawn)) return (ThoughtState)false; - // Do nothing for pawns that also have pheromones - if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_aphrodisiac_pheromones)) + + // Do nothing if the pawn does not have the pheromones + if (!GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_aphrodisiac_pheromones)) return (ThoughtState)false; + // Do nothing for others that also have pheromones + if (GeneUtility.HasGeneNullCheck(other, GeneDefOf.rjw_genes_aphrodisiac_pheromones)) + return (ThoughtState)false; + + // Do nothing for pawns that wear Gas-Masks + if (other.apparel != null && other.apparel.AnyApparel) + if (other.apparel.WornApparel.Any(apparel => apparel.def == RimWorld.ThingDefOf.Apparel_GasMask)) + return (ThoughtState)false; + // Actual Logic: // Pawn qualifies in right distance and needs line of sight. var pos = other.Position; diff --git a/Source/HediffDefOf.cs b/Source/HediffDefOf.cs index d957096..e06d6fc 100644 --- a/Source/HediffDefOf.cs +++ b/Source/HediffDefOf.cs @@ -20,10 +20,18 @@ namespace RJW_Genes public static readonly HediffDef rjw_genes_orgasmic_mytosis_hediff; public static readonly HediffDef rjw_genes_mytosis_shock_hediff; + public static readonly HediffDef rjw_genes_twinkification_progress; + public static readonly HediffDef rjw_genes_feminization_progress; + + public static readonly HediffDef rjw_genes_genetic_rut; + + // Note: Counter does meant it counters it, not it's counting [MayRequire("LustLicentia.RJWLabs")] public static readonly HediffDef rjw_genes_cumstuffed_counter; [MayRequire("LustLicentia.RJWLabs")] public static readonly HediffDef rjw_genes_cumflation_counter; public static readonly HediffDef OvaryAgitator; public static readonly HediffDef Bioscaffold; + + [MayRequire("rjw.sexperience")] public static readonly HediffDef rjw_genes_filled_living_cumbucket; } } diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index dadf954..ddfa721 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -56,24 +56,49 @@ + + + + + + + + + - + + + + + + + + + + + + + + + + + @@ -86,16 +111,13 @@ - - + - - - - + + - + @@ -107,8 +129,8 @@ - - + + @@ -173,11 +195,17 @@ + + + + + + @@ -237,9 +265,7 @@ False - - - + diff --git a/Source/Settings/RJW_Genes_Settings.cs b/Source/Settings/RJW_Genes_Settings.cs index 49257a8..249aa5d 100644 --- a/Source/Settings/RJW_Genes_Settings.cs +++ b/Source/Settings/RJW_Genes_Settings.cs @@ -51,9 +51,19 @@ namespace RJW_Genes listing_Standard.Gap(4f); listing_Standard.CheckboxLabeled("rjw_genes_settings_animal_mating_needs_penis_key".Translate(), ref animalMatingPulseCheckForGenitals, "rjw_genes_settings_animal_mating_needs_penis_explanation".Translate()); - listing_Standard.Gap(5f); - listing_Standard.CheckboxLabeled("rjw_genes_settings_generous_donor_cheatmode_key".Translate(), ref rjw_genes_generous_donor_cheatmode, "rjw_genes_settings_generous_donor_cheatmode_explanation".Translate(), 0f, 1f); + listing_Standard.Gap(5f); + listing_Standard.Label("rjw_genes_genetic_disease_header_key".Translate()); + listing_Standard.Gap(4f); + listing_Standard.CheckboxLabeled("\t" + "rjw_genes_settings_genetic_disease_spread_key".Translate(), ref rjw_genes_genetic_disease_spread, "rjw_genes_settings_genetic_disease_spread_explanation".Translate(), 0f, 1f); + listing_Standard.Gap(4f); + listing_Standard.CheckboxLabeled("\t" + "rjw_genes_genetic_disease_as_endogenes_key".Translate(), ref rjw_genes_genetic_disease_as_endogenes, "rjw_genes_genetic_disease_as_endogenes_explanation".Translate(), 0f, 1f); + listing_Standard.Gap(4f); + listing_Standard.CheckboxLabeled("\t" + "rjw_genes_genetic_disease_spread_only_on_penetrative_sex_key".Translate(), ref rjw_genes_genetic_disease_spread_only_on_penetrative_sex, "rjw_genes_genetic_disease_spread_only_on_penetrative_sex_explanation".Translate(), 0f, 1f); + + + listing_Standard.Gap(10f); + listing_Standard.CheckboxLabeled("rjw_genes_settings_generous_donor_cheatmode_key".Translate(), ref rjw_genes_generous_donor_cheatmode, "rjw_genes_settings_generous_donor_cheatmode_explanation".Translate(), 0f, 1f); listing_Standard.Gap(5f); listing_Standard.CheckboxLabeled("rjw_genes_settings_detailed_debug_key".Translate(), ref rjw_genes_detailed_debug, "rjw_genes_settings_detailed_debug_explanation".Translate(), 0f, 1f); listing_Standard.End(); @@ -74,6 +84,11 @@ namespace RJW_Genes Scribe_Values.Look(ref RJW_Genes_Settings.rjw_genes_sexdemon_visit_groups, "rjw_genes_sexdemon_groups", RJW_Genes_Settings.rjw_genes_sexdemon_visit_groups, true); Scribe_Values.Look(ref RJW_Genes_Settings.rjw_genes_sexdemon_visit_succubi, "rjw_genes_sexdemon_succubi", RJW_Genes_Settings.rjw_genes_sexdemon_visit_succubi, true); Scribe_Values.Look(ref RJW_Genes_Settings.rjw_genes_sexdemon_visit_incubi, "rjw_genes_sexdemon_incubi", RJW_Genes_Settings.rjw_genes_sexdemon_visit_incubi, true); + + Scribe_Values.Look(ref RJW_Genes_Settings.rjw_genes_genetic_disease_spread, "rjw_genes_genetic_disease_spread", RJW_Genes_Settings.rjw_genes_genetic_disease_spread, true); + Scribe_Values.Look(ref RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes, "rjw_genes_genetic_disease_as_endogenes", RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes, true); + Scribe_Values.Look(ref RJW_Genes_Settings.rjw_genes_genetic_disease_spread_only_on_penetrative_sex, "rjw_genes_genetic_disease_spread_only_on_penetrative", RJW_Genes_Settings.rjw_genes_genetic_disease_spread_only_on_penetrative_sex, true); + } public static bool rjw_genes_detailed_debug = false; @@ -88,8 +103,9 @@ namespace RJW_Genes public static bool rjw_genes_sexdemon_visit_succubi = true; public static bool rjw_genes_sexdemon_visit_incubi = true; - - + public static bool rjw_genes_genetic_disease_spread = true; + public static bool rjw_genes_genetic_disease_as_endogenes = true; + public static bool rjw_genes_genetic_disease_spread_only_on_penetrative_sex = false; public static bool rjw_genes_generous_donor_cheatmode = false; } diff --git a/Source/ThoughtDefOf.cs b/Source/ThoughtDefOf.cs index f884d4a..596ecc0 100644 --- a/Source/ThoughtDefOf.cs +++ b/Source/ThoughtDefOf.cs @@ -15,6 +15,9 @@ namespace RJW_Genes public static readonly ThoughtDef rjw_genes_pheromone_carrier_nearby; + public static readonly ThoughtDef rjw_genes_appealing_cock; + public static readonly ThoughtDef rjw_genes_has_more_diseases; + //Others with same names but other defs than in genedefof public static readonly InteractionDef rjw_genes_flirt; } diff --git a/TODOS.md b/TODOS.md deleted file mode 100644 index 25f5045..0000000 --- a/TODOS.md +++ /dev/null @@ -1,29 +0,0 @@ -# ToDos and Planned Genes - -Any help is very appreciated, even if it is just pointing me to existing similar projects. - -## Planned / Wanted Genes - -**Adjustable Cock-Size** like e.g. artificial genitalia have - -**Infectious Hypersexuality Gene** (Maybe?) add Hypersexuality Gene through sex with a certain chance. - -**Cum Addiction** add Cum-Addiction from Sexperience, slowly loose conciousness while addiction is not attended. - -**Cum-Drugs** eating cum has an effect similar to Go-Juice (including (separate?) addiction) - -**Death-Rest** until the pawn is cumflated. I would have liked - -**STD Immunity** & maybe a potential to be carrier, but not suffer effects. I just don't play with STDs - -## Genes with Abilities and more Effects - -There were some suggestions on the Discord I saved them somewhere else. I am far away from making that work, but to have them here: - -- Genitalia deal damage as per size (on normal sex-use) - This started in the branch `GenitaliaDamage` but prooves a bit overboarding! -- Genitalia can cause Terror (as ability) -- Cumshot Sniper Abilities. Scale damage with body size and genitalia size, scale distance by cum-amount (relative to the damage - high damage projectiles need more cum per meter). - -## Cleanups: - -- Change Project structure to the 1.3, 1.4 Structure of other mods