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_anus54
@@ -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_ChangeCumAmount53301
+
+
+ 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_ChangeCumAmount5341
- -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_ChangeCumAmount5351
- -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_damageThis 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/TrialDefend2-11
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
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+ 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 @@
ReproductionThis Gene makes you gay.
- UI\Ideoligions\Universal\RoundC
+ Genes/Icons/RoundC03
@@ -111,6 +90,7 @@
+
rjw_genes_homosexuality_trait_giver
rjw_genes_sexual_orientation
@@ -129,7 +109,7 @@
ReproductionCarriers of this Gene are Bisexual.
- UI\Ideoligions\Universal\RoundC
+ Genes/Icons/RoundC04
@@ -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
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
\ 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/FleshPurity1
@@ -30,7 +30,7 @@
(Partner stays adult)
2-2
- UI/Ideoligions/FireLeaves
+ Genes/Icons/FireLeaves2
@@ -140,7 +140,7 @@
rjw_genes_sex_tamer
-
+
sextamerBestiality 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
+
+
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_lostHediff_HemogenCraving
@@ -19,12 +19,13 @@
-
+
rjw_genes_succubus_drainedHediffWithComps
- 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.01.0
@@ -74,13 +75,13 @@
-0.2
- 0.4
+ 0.40.10.35
-
+
rjw_genes_fertilin_craving
@@ -90,77 +91,78 @@
1.00.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.403.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
+
+
+
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 LoveIf off, pawns will not get bad thoughts for seduction.
-
Animal-Mating GenitalCheckIf 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 cheatmodeWhen 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 @@
+
+
+
+
+
+
+
+
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/Cumflation536
+ -1
+ 2
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
+
+
+
+
+
+
\ 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]
+[](https://buymeacoffee.com/vegapnk)
+[](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