diff --git a/About/About.xml b/About/About.xml index a2eca98..de6326a 100644 --- a/About/About.xml +++ b/About/About.xml @@ -8,6 +8,10 @@ Adds Genes for RJW Content https://steamcommunity.com/id/Vegapnk/myworkshopfiles/?appid=294100 +
  • + Ludeon.RimWorld.Biotech + Biotech +
  • rim.job.world RimJobWorld @@ -27,11 +31,17 @@
  • +
  • Ludeon.RimWorld
  • +
  • Ludeon.RimWorld.Royalty
  • +
  • Ludeon.RimWorld.Ideology
  • +
  • Ludeon.RimWorld.Biotech
  • rim.job.world
  • brrainz.harmony
  • - +
  • OskarPotocki.VanillaFactionsExpanded.Core
  • +
  • sarg.alphaanimals
  • + +
  • Sl4vP0weR.DominantGene
  • +
  • rjw.sexperience.cumgenes
  • \ No newline at end of file diff --git a/About/Manifest.xml b/About/Manifest.xml index b99a84a..5030d54 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,15 +1,18 @@ RJW-Genes - 1.1.0 + 1.2.1
  • RimJobWorld
  • HugsLib
  • - + +
  • Male- and Female- Only Genes
  • +
  • RimJobWorld
  • HugsLib
  • +
  • RJWSexperience_CumGenes
  • RJW-LicentiaLabs
  • diff --git a/About/Preview.png b/About/Preview.png index 315ad3c..fdcd074 100644 Binary files a/About/Preview.png and b/About/Preview.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 660c671..7ce1000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,83 @@ -<<<<<<< HEAD +# 1.2.1 + +**Fixes**: + +- Issue with RJW Changes for Orgasms, #52. Methods were renamed. +- Notes on the Gene Inheritance #51 + +# 1.2 (11-06-2023) + +**Changes:** + +- Cocoon Weaver Gene +- Spawn Spelopede Gene (Can be changed to spawn megascarabs or other insects via xml) +- Queens & Caste logic (see below) +- Addition to InsectIncubator: Now fertilizes eggs once placed inside a host, and breeds out eggs roughly twice as fast. +- Many new icons +- Custom background icons when Vanilla-Expanded-Framework is loaded +- Sexual Age Drainer & Youth Fountain now change age as configured in XML +- Draft for a Hive-Start Scenario +- Added Orgasmic Mytosis Gene: On Multiple Orgasms, spawn an identical copy of a pawn. Items and Implants are not copied. +- Patches for Alpha Genes Xenotypes and LTS Xenotech +- New Simple Genitalia Patches for other popular Xenotypes (Thanks @Pali42K) + +**Internal:** + +- Renamed abilities to have _ability_ in their name, to not exactly match the gene-defnames. +- Moved Insect-Incubator & Insect-Breeder to hive category and folders (from breeding) +- Some exclusion-tags for Alpha Genes +- Removed Patches for conditional Genes, and moved them to `mayRequire` in the XenotypeDefs + +**Fixes:** + +- Cockeater Ability has now Icon of Cockeater Gene +- Cockeater now leaves a bite wound! +- Pythokin-Patch checks for Licentialabs (#30) +- Removed Sex-Change thoughts for pawns born or spawned with a gender-altering gene (Issue #32, PR #33 by @callavico) +- More consistent behavior for genitalia resizing over multiple game-starts (Issue #34) + +**Queen & Caste Logic** + +There are 3 genes revolting around a new, hopefully flexible insect-caste system. Queens, Drones and Workers. These reproduce either through normal sex, or can utilize the insect birth once [this PR](https://gitgud.io/Ed86/rjw/-/merge_requests/266) has been merged in. +Update: It has been merged into [RJW 5.3.5](https://gitgud.io/Ed86/rjw/-/tags/5.3.5), make sure you update! + +In general, the logic is the following: + +- A queen can have sex with anyone. If the partner was a drone, there is chance for the baby to become a queen, drone or worker. +- If the partner of the queen was not a drone, the baby will be a worker. +- If the drone didn't mate with a queen but someone else, normal inheritance happens +- The assignment is done by xenotypes for queen and drones. The baby will get all xenogenes of their parents chosen xenotypes. +- For workers, every queen can have a set of genes for their workers defined in [a special def](./Common/Defs/QueenWorkerMappingDefs/QueenWorkerMappingDefs_base.xml). These will be added as endogenes, so that pawns can still become xenotypes. +- There is a default gene-set for workers, making dumb, sterile and servile pawns. +- Chances for Offsprings (Drone, Queen, Worker) is defined in an [XML-Def](./Common/Defs/HiveOffspringChanceDef/HiveOffspringChanceDefs.xml). They are set per Queen. +- Birthlogic should apply for normal pregnancies, and for RJW-Insect Eggs. Other Pregnancies (from mods) are not supported. + +I am not sure if I want to have a specific mapping defining that queen can only mate with certain drones, let me know how you feel about it. +*Queens can be male*. I just used the female-term, but implementation is gender-neutral. + +**On Alpha Genes** + +Alpha genes might have colliding features, but I need some reports to find out about it. +I disabled the specific gender and the oviparious reproduction (when you have rjw-ovipos). +I recommend using alpha genes for the Hive-Playthroughs, as otherwise the Halamyr look a bit ... boring? +But i don't want to add a bunch of cosmetic genes on top of things. + +*And what the fuck is a halamyr?* Well I had to name my little ants somehow. But I didn't want to call them `myr` as I maybe want to make some [TiTs](https://www.fenoxo.com/play-games/) xenotypes separately. +And I am aware that the TiTs-Myr work different than the things I made now. + + +**Changes Since beta-1**: + +- Fix of icon-names (#36) +- Changes to the scenario (more building items, throne for start). Wealth is now at 12k, which is the same as crashlanded and lost tribe. +- Added the Orgasmic Mytosis Draft +- Many touches on the Halamyr Hive Logic and Fertilizitation (#37,#38) + +**Changes Since beta-2**: + +- Mostly Patches and Changes to the Halamyr Defs +- Some re-arranging and mayRequires for other mods + # 1.1.4 Fixes: diff --git a/Common/Assemblies/Rjw-Genes.dll b/Common/Assemblies/Rjw-Genes.dll index 219605f..a45e15c 100644 Binary files a/Common/Assemblies/Rjw-Genes.dll and b/Common/Assemblies/Rjw-Genes.dll differ diff --git a/Common/Defs/AbilityDefs/Ability_CockEater.xml b/Common/Defs/AbilityDefs/Ability_CockEater.xml index d333c1d..4a8f2e3 100644 --- a/Common/Defs/AbilityDefs/Ability_CockEater.xml +++ b/Common/Defs/AbilityDefs/Ability_CockEater.xml @@ -1,10 +1,10 @@ - rjw_genes_cockeater + rjw_genes_ability_cockeater Eat the cock of another pawn, restoring fertilin based on the size of the cock. - Things/Mote/Heart + Genes/Icons/cockeater true true false @@ -27,8 +27,7 @@ -
  • -
  • +
  • \ No newline at end of file diff --git a/Common/Defs/AbilityDefs/Ability_CocoonWeaver.xml b/Common/Defs/AbilityDefs/Ability_CocoonWeaver.xml new file mode 100644 index 0000000..2a1577a --- /dev/null +++ b/Common/Defs/AbilityDefs/Ability_CocoonWeaver.xml @@ -0,0 +1,34 @@ + + + + rjw_genes_ability_cocoonweaver + + Weaves the victim into a (self-sustaining) cocoon. The victim cannot move, but can be bred. + Genes/Icons/Cocoon + true + true + false + Mote_CocoonStencil + CocoonWeave + CastAbilityOnThingMelee + 404 + + 30000 + + Verb_CastAbilityTouch + false + -1 + 15 + + true + false + false + false + true + + + +
  • + + + \ No newline at end of file diff --git a/Common/Defs/AbilityDefs/Ability_Flight.xml b/Common/Defs/AbilityDefs/Ability_Flight.xml index 82e6537..d643940 100644 --- a/Common/Defs/AbilityDefs/Ability_Flight.xml +++ b/Common/Defs/AbilityDefs/Ability_Flight.xml @@ -1,7 +1,7 @@ - rjw_genes_flight + rjw_genes_ability_flight Fly to a short location using your wings. Genes/Icons/Succubus_Wings diff --git a/Common/Defs/AbilityDefs/Ability_NakedProwess.xml b/Common/Defs/AbilityDefs/Ability_NakedProwess.xml index 82d5bd8..778f4d9 100644 --- a/Common/Defs/AbilityDefs/Ability_NakedProwess.xml +++ b/Common/Defs/AbilityDefs/Ability_NakedProwess.xml @@ -1,12 +1,12 @@ - rjw_genes_naked_prowess + rjw_genes_ability_naked_prowess Enhance the strength and resilience of your naked body with fertilin. Genes/Icons/rjw_naked_prowess Things/Mote/Heart - CastAbilityOnThing + CastAbilityOnThing False False True diff --git a/Common/Defs/AbilityDefs/Ability_ParalysingKiss.xml b/Common/Defs/AbilityDefs/Ability_ParalysingKiss.xml index 8fd3eec..0d8959d 100644 --- a/Common/Defs/AbilityDefs/Ability_ParalysingKiss.xml +++ b/Common/Defs/AbilityDefs/Ability_ParalysingKiss.xml @@ -1,14 +1,14 @@ - rjw_genes_paralysingkiss + rjw_genes_ability_paralysingkiss Paralyse someone briefly with a kiss. Genes/Icons/rjw_genes_lips true true false - + 5 Mote_CoagulateStencil diff --git a/Common/Defs/AbilityDefs/Ability_PussyHeal.xml b/Common/Defs/AbilityDefs/Ability_PussyHeal.xml index 8f97b60..4445bf2 100644 --- a/Common/Defs/AbilityDefs/Ability_PussyHeal.xml +++ b/Common/Defs/AbilityDefs/Ability_PussyHeal.xml @@ -1,7 +1,7 @@ - rjw_genes_pussyheal + rjw_genes_ability_pussyheal Rape another pawn, so you can heal them with your vagina's special healing power. Things/Mote/Heart diff --git a/Common/Defs/AbilityDefs/Ability_Seduce.xml b/Common/Defs/AbilityDefs/Ability_Seduce.xml index 3310595..595c348 100644 --- a/Common/Defs/AbilityDefs/Ability_Seduce.xml +++ b/Common/Defs/AbilityDefs/Ability_Seduce.xml @@ -1,7 +1,7 @@ - rjw_genes_seduce + rjw_genes_ability_seduce Seduce the target to approach the caster. Genes/Icons/seduce @@ -9,7 +9,7 @@ true true false - + 10 Mote_CoagulateStencil diff --git a/Common/Defs/AbilityDefs/Ability_SpawnSpelopede.xml b/Common/Defs/AbilityDefs/Ability_SpawnSpelopede.xml new file mode 100644 index 0000000..7279149 --- /dev/null +++ b/Common/Defs/AbilityDefs/Ability_SpawnSpelopede.xml @@ -0,0 +1,36 @@ + + + + rjw_genes_ability_spawn_spelopede + + Generates a tame spelopede, ready to serve their master. + Genes/Icons/Spelopede_Dispenser + true + false + + + Verb_CastAbility + 3 + False + False + 2 + + False + True + + + + False + 1800000 + + +
  • + RJW_Genes.CompAbilityEffect_SpawnSpelopede + Spelopede + true + 1.00 +
  • +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/Effects/cocoonweave.xml b/Common/Defs/Effects/cocoonweave.xml new file mode 100644 index 0000000..945e631 --- /dev/null +++ b/Common/Defs/Effects/cocoonweave.xml @@ -0,0 +1,37 @@ + + + + + CocoonWeave + +
  • + SubEffecter_SprayerChance + BloodSplash + 0.15 + 2~3 + 0.75~1.5 + (244, 244, 244) + RandomDrawPosOnTarget + true +
  • +
    +
    + + + Mote_CocoonStencil + MoteAttached + Terrain + + 0.1 + 0.4 + 999999 + True + + + Graphic_PawnBodySilhouette + PawnSilhouetteStencil + Things/Mote/Transparent + + + +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneCategories.xml b/Common/Defs/GeneDefs/GeneCategories.xml index 06b31cc..8106c8e 100644 --- a/Common/Defs/GeneDefs/GeneCategories.xml +++ b/Common/Defs/GeneDefs/GeneCategories.xml @@ -67,6 +67,11 @@ 8 + + rjw_genes_hive + + 7 + \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml index a2d7d7e..aadecc9 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml @@ -11,42 +11,34 @@ rjw_genes_breeding 1 -1 - - - - rjw_genes_insectincubator - - Pawns with this gene are able to hold more insect eggs. - Genes/Icons/More_Egg_Space - 52 - rjw_genes_breeding - 1 - -1 - - - rjw_genes_insectbreeder - - Pawns with this gene are able to fertilize eggs with any fertile penis. - World/WorldObjects/Expanding/Insects - 53 - rjw_genes_breeding - 1 - -1 + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    - - rjw_genes_zoophile - - rjw_genes_breeding - Xenotypes with this Gene are Zoophile. - Genes/Icons/Zoophile - 54 - -
  • - Zoophile -
  • -
    -
    + + rjw_genes_zoophile + + rjw_genes_breeding + Xenotypes with this Gene are Zoophile. + Genes/Icons/Zoophile + 54 + +
  • + Zoophile +
  • +
    + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Cosmetic.xml b/Common/Defs/GeneDefs/GeneDefs_Cosmetic.xml index a5cd0ca..8723630 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Cosmetic.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Cosmetic.xml @@ -19,10 +19,10 @@ (0.75, 0.75, 0.75) 1000 -
  • rjw_genes_flight
  • +
  • rjw_genes_ability_flight
  • - rjw_genes_flight + rjw_genes_ability_flight 1 -1 @@ -34,6 +34,13 @@ (0.0, 0.0, -0.1) (0.1, 0.0, 0.0) + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -64,6 +71,13 @@ (0, -0.1, 0.1) (0.2, 0.2, 0.1) - true + true + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Cum.xml b/Common/Defs/GeneDefs/GeneDefs_Cum.xml index d410319..28b841a 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Cum.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Cum.xml @@ -1,10 +1,17 @@ - rjw_genes_cum - -
  • CumAmount
  • -
    + rjw_genes_cum + +
  • CumAmount
  • +
    + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -23,7 +30,7 @@ rjw_genes_much_cum Males of this species produce a lot of fluid. - Genes/Icons/Bonus_Cum + Genes/Icons/Much_Cum RJW_Genes.Gene_MuchCum 534 1 @@ -34,7 +41,7 @@ rjw_genes_very_much_cum Males of this species produce a whole lot of fluid. They are like fountains basically. - Genes/Icons/Much_Bonus_Cum + Genes/Icons/Very_Much_Cum RJW_Genes.Gene_VeryMuchCum 535 1 @@ -55,7 +62,14 @@
  • NotCumflatable
  • -
    + + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -67,7 +81,14 @@ 537
  • NotCumflatable
  • -
    + + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -78,6 +99,13 @@ When this Xenotype transfers nutrition via cumshot, the giver will not get hungry. (Licentia Configuration for Transfer Nutrition must be enabled). Genes/Icons/Generous_Donor 538 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Damage.xml b/Common/Defs/GeneDefs/GeneDefs_Damage.xml index f2b0e07..97aba0e 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Damage.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Damage.xml @@ -11,6 +11,13 @@ -1 1 1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -27,6 +34,13 @@
  • FeelingBroken
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_ExtraGenitalia.xml b/Common/Defs/GeneDefs/GeneDefs_ExtraGenitalia.xml index 22764ea..294dc66 100644 --- a/Common/Defs/GeneDefs/GeneDefs_ExtraGenitalia.xml +++ b/Common/Defs/GeneDefs/GeneDefs_ExtraGenitalia.xml @@ -1,9 +1,15 @@ - + rjw_genes_genitalia_extras - + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    rjw_genes_extra_penis @@ -34,7 +40,7 @@ rjw_genes_extra_vagina Females of this species grow an additional vagina . - Genes/Icons/extra_female + Genes/Icons/Extra_Vagina RJW_Genes.Gene_ExtraVagina 703 @@ -46,7 +52,7 @@ rjw_genes_no_vagina Females of this do not have a vagina. - Genes/Icons/No_Female_Genitalia + Genes/Icons/No_Vagina RJW_Genes.Gene_NoVagina 704 @@ -127,5 +133,19 @@
  • BreastAmount
  • - +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_GenitaliaSizes.xml b/Common/Defs/GeneDefs/GeneDefs_GenitaliaSizes.xml index c5d8826..5c43285 100644 --- a/Common/Defs/GeneDefs/GeneDefs_GenitaliaSizes.xml +++ b/Common/Defs/GeneDefs/GeneDefs_GenitaliaSizes.xml @@ -2,7 +2,14 @@ rjw_genes_genitalia_size - + + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -35,7 +42,7 @@ rjw_genes_loose_female_genitalia Vaginas of this Xenotype are quite spacy. (Resizing takes place at 20th Birthday) - Genes/Icons/Loose_Female_Genitalia + Genes/Icons/Loose_Vagina RJW_Genes.Gene_LooseFemaleGenitalia 754 @@ -47,7 +54,7 @@ rjw_genes_tight_female_genitalia Vaginas of this Xenotype are pretty tight.(Resizing takes place at 20th Birthday) - Genes/Icons/Tight_Female_Genitalia + Genes/Icons/Tight_Vagina RJW_Genes.Gene_TightFemaleGenitalia 756 diff --git a/Common/Defs/GeneDefs/GeneDefs_GenitaliaTypes.xml b/Common/Defs/GeneDefs/GeneDefs_GenitaliaTypes.xml index 7333a5e..4c27701 100644 --- a/Common/Defs/GeneDefs/GeneDefs_GenitaliaTypes.xml +++ b/Common/Defs/GeneDefs/GeneDefs_GenitaliaTypes.xml @@ -7,6 +7,13 @@
  • GenitalType
  • 0 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -58,7 +65,7 @@ rjw_genes_slime_genitalia Carriers of this gene have slime genitalia. - Genes/Icons/Genitalia_Slime + Genes/Icons/Slime_Genitalia RJW_Genes.Gene_SlimeGenitalia 807 @@ -67,9 +74,16 @@ rjw_genes_ovipositor_genitalia Carriers of this gene have ovipositors similar to insects. - Genes/Icons/Genitalia_Insect + Genes/Icons/Ovipositor_Genitalia RJW_Genes.Gene_OvipositorGenitalia 808 + + +
  • Egglaying
  • +
  • AG_Egglaying
  • +
    + +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Hive.xml b/Common/Defs/GeneDefs/GeneDefs_Hive.xml new file mode 100644 index 0000000..e4a747d --- /dev/null +++ b/Common/Defs/GeneDefs/GeneDefs_Hive.xml @@ -0,0 +1,214 @@ + + + + + rjw_genes_hive + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    + + + rjw_genes_queen + + queen + This gene represents the royal caste amongst its xenotype. Children of a queen are usually born as sterile workers, unless the father was a drone. Having multiple (adult) queens leads to intense rivalry and can throw the whole colony into chaos! + Genes/Icons/Queen + 1 + + + 0.5 + 0.25 + + + + +
  • + + 0.7 + + + -0.5 + +
  • +
  • + + 0.4 + 0.2 + +
  • +
    + + +
  • rjw_genes_hive_caste
  • +
  • rjw_genes_swearing_loyalty
  • +
    + + 7 + -3 +
    + + + rjw_genes_drone + + drone + This gene represents the drone caste amongst its xenotype. Drones are highly specialised experts that ensure the hives functioning. Other than that, drones are the only xenotypes capable of producing fertile offspring with a queen. + Genes/Icons/Drone + 2 + + +
  • rjw_genes_hive_caste
  • +
    + + +
  • + + 0.9 + + + -0.1 + +
  • +
    + + 4 + -2 +
    + + + + rjw_genes_worker + + worker + This gene marks the lowest caste of a hive, the workers. Usually sterile, they are despised by higher castes and only live to serve with labour. + Genes/Icons/Worker + 3 + + +
  • rjw_genes_hive_caste
  • +
    + + +
  • + + 0.7 + + + -0.5 + +
  • +
  • + + 0.7 + + + -0.5 + +
  • +
  • + + 1.2 + 1.2 + +
  • +
    + + 1 + 0 +
    + + + rjw_genes_zealous_loyalty + + loyalty + Carriers of this gene are genetically wired to worship carriers of the 'Queen'-gene. They receive a massive relation-ship bonus towards the queen and a slight mood bonus. Having multiple queens in the colony causes severe distress. + Genes/Icons/Loyalty + 10 + + +
  • rjw_genes_swearing_loyalty
  • +
    + + 1 + -1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    + + + rjw_genes_cocoonweaver + + cocooner + Carriers of this gene can produce a cocoon to prepare helpless (or willing) victims for breeding. + Genes/Icons/Cocoon + 11 + +
  • rjw_genes_ability_cocoonweaver
  • +
    + + rjw_genes_ability_cocoonweaver + + 1 + -1 +
    + + + rjw_genes_spawn_spelopede + + spelopede + Carriers of this gene can generate tame spelopedes. Higher psychic-sensitivity will spawn more spelopedes. + Genes/Icons/Spelopede_Dispenser + 12 + +
  • rjw_genes_ability_spawn_spelopede
  • +
    + + rjw_genes_ability_spawn_spelopede + + 1 + -1 +
    + + + + rjw_genes_insectincubator + + RJW_Genes.Gene_InsectIncubator + Pawns with this gene are able to hold more insect eggs. + Genes/Icons/Egg + 52 + 1 + -1 + + + + rjw_genes_insectbreeder + + Pawns with this gene are able to fertilize eggs with any fertile penis. + Genes/Icons/Insect_Breeder + 53 + 1 + -1 + + + + rjw_genes_fervent_ovipositor + + RJW_Genes.Gene_FerventOvipositor + Pawns that have a female (egg producing) ovipositor produce eggs at drastically increased speed. + Genes/Icons/Fervent_Ovipositor + 55 + 1 + -1 + + +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_LifeForce.xml b/Common/Defs/GeneDefs/GeneDefs_LifeForce.xml index e8987d0..67f0994 100644 --- a/Common/Defs/GeneDefs/GeneDefs_LifeForce.xml +++ b/Common/Defs/GeneDefs/GeneDefs_LifeForce.xml @@ -31,6 +31,13 @@ 0.05 1 1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -48,6 +55,13 @@ -1 1 6 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -60,10 +74,10 @@ 9 rjw_genes_fertilin -
  • rjw_genes_pussyheal
  • +
  • rjw_genes_ability_pussyheal
  • - rjw_genes_pussyheal + rjw_genes_ability_pussyheal 1 -1 @@ -74,6 +88,13 @@
  • heal
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -86,10 +107,10 @@ 11 rjw_genes_fertilin -
  • rjw_genes_cockeater
  • +
  • rjw_genes_ability_cockeater
  • - rjw_genes_cockeater + rjw_genes_ability_cockeater 1 -1 @@ -100,6 +121,13 @@
  • eat
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -107,15 +135,15 @@ paralysing kiss Carriers of this gene are able to briefly stun an enemy with a kiss. - Genes/Icons/rjw_genes_lips + Genes/Icons/Paralysing_Kiss rjw_genes_lifeforce 12 rjw_genes_fertilin -
  • rjw_genes_paralysingkiss
  • +
  • rjw_genes_ability_paralysingkiss
  • - rjw_genes_paralysingkiss + rjw_genes_ability_paralysingkiss 1 -1 @@ -125,6 +153,13 @@
  • kiss
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -137,10 +172,10 @@ 13 rjw_genes_fertilin -
  • rjw_genes_seduce
  • +
  • rjw_genes_ability_seduce
  • - rjw_genes_seduce + rjw_genes_ability_seduce 1 -1 @@ -151,6 +186,13 @@
  • kiss
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -162,13 +204,20 @@ 13 rjw_genes_fertilin -
  • rjw_genes_naked_prowess
  • +
  • rjw_genes_ability_naked_prowess
  • - rjw_genes_naked_prowess + rjw_genes_ability_naked_prowess 1 -1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -180,6 +229,13 @@ 1 rjw_genes_fertilin 1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -191,17 +247,31 @@ 2 rjw_genes_fertilin 1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    rjw_genes_drainer Carriers of this gene are able to absorb a great amount of fertilin by draining the vitality of the partner. This is done passively through having sex with a non-drained pawn that does not have this gene. - Things/Mote/Heart + Genes/Icons/Vitality_Drainer rjw_genes_lifeforce 4 rjw_genes_fertilin 1 -1 + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml b/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml index 97fb937..7c888cd 100644 --- a/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml +++ b/Common/Defs/GeneDefs/GeneDefs_Reproduction.xml @@ -13,6 +13,13 @@ Nymphomaniac + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -28,6 +35,13 @@ Rapist + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -46,6 +60,13 @@
  • rjw_genes_sexual_orientation
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -64,6 +85,13 @@
  • rjw_genes_sexual_orientation
  • + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml index 1e0e8c9..af6c34f 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml @@ -1,48 +1,81 @@ - + + + rjw_genes_special + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    +
    + + rjw_genes_orgasm_rush - rjw_genes_special - On Orgasm, carriers of this gene get a boost in activity. (rest-need is partially filled) + On orgasm, carriers of this gene get a boost in activity. (rest-need is partially filled) 1 -2 UI/Memes/FleshPurity 1 - + rjw_genes_youth_fountain - rjw_genes_special Having sex with a carrier of this gene makes the partner slightly younger. (Partner stays adult) 2 -2 UI/Ideoligions/FireLeaves 2 + +
  • + + 60000 + 18 +
  • +
    - + rjw_genes_sex_age_drain - rjw_genes_special Having sex transfers some of the partners life-time to themselves. (Pawn stays adult) 2 -1 UI/Icons/ColonistBar/Idle 3 + +
  • + + 120000 + 18 +
  • +
    - + rjw_genes_aphrodisiac_pheromones - rjw_genes_special - RJW_Genes.Gene_Aphrodisiac_Pheromones + RJW_Genes.Gene_Aphrodisiac_Pheromones Pheremones of this pawn induce an incressed sexdrive to others nearby. - UI/Memes/FleshPurity + Genes/Icons/Pheromones 4 1 1 + + rjw_genes_sexual_mytosis + + + Carriers of this gene grow more unstable with ongoing multiple orgasms - climaxing in a process of mytosis. This will result in an (biologically) identical pawn and both twins are set in a regenerative state. Also, the pawn can have multiple orgasms: In a state of higher unstableness, they come quicker. + UI/Icons/Genes/Gene_PsychicBonding + 5 + 5 + -5 + +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml b/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml index e168411..fae1f90 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SpecifiedGender.xml @@ -9,6 +9,18 @@ Genes/Icons/Female_Only RJW_Genes.Gene_FemaleOnly 1 + + +
  • AG_Gender
  • +
  • Gender
  • +
    + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    @@ -20,6 +32,18 @@ Genes/Icons/Male_Only RJW_Genes.Gene_MaleOnly 2 + + +
  • AG_Gender
  • +
  • Gender
  • +
    + + +
  • + Genes/Icons/RJW_Genes_Endogene_Background + Genes/Icons/RJW_Genes_Xenogene_Background +
  • +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/Xenotype_Hive.xml b/Common/Defs/GeneDefs/Xenotype_Hive.xml new file mode 100644 index 0000000..bca30ab --- /dev/null +++ b/Common/Defs/GeneDefs/Xenotype_Hive.xml @@ -0,0 +1,124 @@ + + + + + + + rjw_genes_halamyr_queen_xenotype + + Genes/Icons/Xenotypes/Xenotype-Queen + false + false + + The Halamyr are a race of insect-xenotypes living in a caste-system. On top of the caste, the queens are the centerpiece of any hive. They are the only Halamyr that can produce drones, or mass-produce workers. A hive can virtually not live without a queen - without their royalty the drones and workers are irritated and receive sever penalties. Queens are very fragile and need to be kept safe and in best conditions. + The fragile queens of the Halamyr are the center of the hives reproduction. Multiple queens, or and absence of a queen, can cause to fall the best hive into disarray real quick. + + +
  • AG_LargerBodySize
  • +
  • AG_InsectBlood
  • +
  • AG_InsectJellyProduction
  • +
  • AG_SurvivalInstinct_Low
  • +
  • WoundHealing_Slow
  • +
  • PsychicAbility_Extreme
  • +
  • MoveSpeed_Slow
  • +
  • FireTerror
  • +
  • MeleeDamage_Weak
  • +
  • Sleepy
  • +
  • Delicate
  • +
  • rjw_genes_hypersexual
  • +
  • rjw_genes_bisexual
  • +
  • Libido_High
  • +
  • Beauty_Beautiful
  • +
  • AG_OutwardsAntennas
  • +
  • Skin_DeepRed
  • +
  • Learning_Fast
  • +
  • rjw_genes_fervent_ovipositor
  • +
  • AptitudeTerrible_Shooting
  • +
  • AptitudeTerrible_Melee
  • +
  • AptitudeRemarkable_Social
  • +
  • AptitudeRemarkable_Sex
  • +
  • rjw_genes_female_only
  • +
  • rjw_genes_ovipositor_genitalia
  • +
  • rjw_genes_aphrodisiac_pheromones
  • +
  • rjw_genes_queen
  • +
  • rjw_genes_cocoonweaver
  • +
  • rjw_genes_spawn_spelopede
  • +
    +
    + + + rjw_genes_halamyr_hiveguard_xenotype + + Genes/Icons/Xenotypes/Xenotype-Guard + + 1.5 + false + + The Halamyr hiveguards are the bastion to protect the hive. Next to the walls, these meele specialists form the ultimate guard for the queen, for which they'd give their lifes. Their tuned bodies come with a price, crippling them for social interactions and increased hunger. + Frontline of the Halamyr, guards of the hive, specialised in meele combat. Heavily handicapped without a queen. + + +
  • AG_InsectBlood
  • +
  • AG_EfficientMandibles
  • +
  • Immunity_Strong
  • +
  • WoundHealing_Fast
  • +
  • MoveSpeed_Quick
  • +
  • FireTerror
  • +
  • MeleeDamage_Strong
  • +
  • KillThirst
  • +
  • LowSleep
  • +
  • AG_WaspWings
  • +
  • Hair_ShortOnly
  • +
  • AG_DownwardsAntennas
  • +
  • Hair_DarkBlack
  • +
  • Skin_DeepRed
  • +
  • AG_FeraliskEyes
  • +
  • AptitudeTerrible_Shooting
  • +
  • AptitudeRemarkable_Melee
  • +
  • AptitudePoor_Construction
  • +
  • AptitudePoor_Cooking
  • +
  • AptitudePoor_Plants
  • +
  • AptitudePoor_Crafting
  • +
  • AptitudeTerrible_Artistic
  • +
  • AptitudeTerrible_Medicine
  • +
  • AptitudePoor_Social
  • +
  • rjw_genes_male_only
  • +
  • rjw_genes_ovipositor_genitalia
  • +
  • rjw_genes_drone
  • +
  • rjw_genes_zealous_loyalty
  • +
    +
    + + + rjw_genes_halamyr_breeder_xenotype + + Genes/Icons/Xenotypes/Xenotype-Breeder + false + false + 0.8 + + The Halamyr breeders are the backbone of the hive. Their special genes allow them to carry more eggs and hatch them faster, enabling a steady output of hivelings. To support their position in the hive, breeders spend most of their life in the queens cocoon, a task which they gladly accept. + Made for incubating Halamyr eggs, breeders spend most of their life in the queens cocoon. + + +
  • AG_Spinnerets
  • +
  • AG_InsectBlood
  • +
  • AG_InsectJellyProduction
  • +
  • AG_FormicAntennas
  • +
  • Fertile
  • +
  • AG_FastGestation
  • +
  • FireTerror
  • +
  • VerySleepy
  • +
  • rjw_genes_bisexual
  • +
  • Skin_DeepRed
  • +
  • AptitudeStrong_Social
  • +
  • rjw_genes_drone
  • +
  • rjw_genes_female_only
  • +
  • rjw_genes_zealous_loyalty
  • +
  • rjw_genes_insectincubator
  • +
  • rjw_genes_zoophile
  • +
  • rjw_genes_no_vagina
  • +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml b/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml index 38dfa28..608a2f4 100644 --- a/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml +++ b/Common/Defs/GeneDefs/Xenotype_Lifeforce.xml @@ -6,7 +6,7 @@ Succubi are strongly enhanced xenohumans. These overnaturally beautiful creatures strive parasitically on the Fertilin found in semen. Succubi are beautiful and extremely hungry Xenohumans. They strive on having sex and extracting their victims life-force through this. - UI/Icons/Xenotypes/Sanguophage + Genes/Icons/Xenotypes/Xenotype-Succubus PawnBecameSanguophage 0.5 0.1~140 @@ -35,7 +35,10 @@
  • rjw_genes_paralysingkiss
  • rjw_genes_seduce
  • +
  • AptitudeRemarkable_Sex
  • +
  • DominantGene
  • +
  • rjw_genes_elasticity
  • rjw_genes_succubus_wings
  • rjw_genes_succubus_tail
  • rjw_genes_aphrodisiac_pheromones
  • @@ -53,7 +56,7 @@ Incubi are strongly enhanced xenohumans. These overnaturally beautiful creatures strive parasitically on the Fertilin found in semen. Incubi are beautiful and extremely hungry Xenohumans. They strive on having sex and extracting their victims life-force through this. - UI/Icons/Xenotypes/Sanguophage + Genes/Icons/Xenotypes/Xenotype-Incubus PawnBecameSanguophage 0.5 0.1~140 @@ -77,6 +80,10 @@
  • rjw_genes_drainer
  • rjw_genes_demonic_genitalia
  • +
  • AptitudeRemarkable_Sex
  • + + +
  • DominantGene
  • rjw_genes_seduce
  • rjw_genes_succubus_wings
  • rjw_genes_succubus_tail
  • @@ -98,7 +105,7 @@ Cumazone are a female only xenotype that excel at meele combat. Originally created as bodyguards for glitterworld amazon communities, they spred to other systems by mere strength and providing for some fetishes. They can use Fertilin to enhance their skin to overpower any combatant in meele. Their only source for Fertilin is biting of male genitalia - so be sure to have a steady supply of victim males or prepare to raid unsuspecting men of the rim. Female only, strong meele fighters, that use Fertilin from bitten-off cocks for powerful buffs. - UI/Icons/Xenotypes/Neanderthal + Genes/Icons/Xenotypes/Xenotype-Cumazon 0.5 0.1~140 2.5 diff --git a/Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml b/Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml new file mode 100644 index 0000000..f26d1a9 --- /dev/null +++ b/Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml @@ -0,0 +1,136 @@ + + + + + rjw_genes_orgasmic_mytosis_hediff + HediffWithComps + + Xenotypes with this Gene grow more unstable on orgasm - upon reaching critical level they will initate a process of mytosis. + (240,200,110) + false + 1.0 + false + false + +
  • + -0.9 +
  • +
    + +
  • + + +
  • + Moving + 0.05 +
  • +
  • + Consciousness + 0.08 +
  • + + +
  • + + 0.4 + +
  • + Moving + 0.15 +
  • +
  • + Consciousness + 0.15 +
  • + + +
  • + + 0.7 + +
  • + Moving + -0.1 +
  • +
  • + Consciousness + -0.1 +
  • +
  • + BloodPumping + +0.2 +
  • + + + +
  • + + 0.9 + +
  • + Moving + -0.25 +
  • +
  • + Consciousness + -0.25 +
  • +
  • + BloodPumping + +0.5 +
  • + + +
    +
    + + + rjw_genes_mytosis_shock_hediff + HediffWithComps + + Recently underwent (successful) mytosis. As this is a taxing process, some time for regeneration is required. While regenerating, no new mytosis can be started. + (240,200,110) + false + 1.0 + true + false + +
  • + -0.20 +
  • +
    + +
  • + + +
  • + Moving + -0.25 +
  • +
  • + Consciousness + -0.25 +
  • + + +
  • + + 0.6 + +
  • + Moving + -0.50 +
  • +
  • + Consciousness + -0.7 +
  • + + +
    +
    + + + +
    + diff --git a/Common/Defs/HiveOffspringChanceDef/HiveOffspringChanceDefs.xml b/Common/Defs/HiveOffspringChanceDef/HiveOffspringChanceDefs.xml new file mode 100644 index 0000000..884bd6a --- /dev/null +++ b/Common/Defs/HiveOffspringChanceDef/HiveOffspringChanceDefs.xml @@ -0,0 +1,36 @@ + + + + + + + + + + rjw_genes_default_hive_offspring_chances + default + + 0.02 + 0.48 + 0.5 + + + + + rjw_genes_test_queen_offspring_chances + rjw_genes_test_queen_xenotype + + 0.02 + 0.28 + 0.7 + + + + \ No newline at end of file diff --git a/Common/Defs/QueenWorkerMappingDefs/QueenWorkerMappingDefs_base.xml b/Common/Defs/QueenWorkerMappingDefs/QueenWorkerMappingDefs_base.xml new file mode 100644 index 0000000..1ccfebd --- /dev/null +++ b/Common/Defs/QueenWorkerMappingDefs/QueenWorkerMappingDefs_base.xml @@ -0,0 +1,43 @@ + + + + + + + + rjw_genes_default_worker_genes + default + +
  • StrongStomach
  • +
  • AG_FasterAging
  • +
  • PsychicAbility_Dull
  • +
  • FireTerror
  • +
  • Sterile
  • +
  • AptitudeTerrible_Intellectual
  • +
  • rjw_genes_featureless_chest
  • +
  • rjw_genes_worker
  • +
  • rjw_genes_zealous_loyalty
  • +
    +
    + + + rjw_genes_halamyr_queen_worker_mapping + rjw_genes_halamyr_queen_xenotype + +
  • AG_SmallerBodySize
  • +
  • StrongStomach
  • +
  • AG_EfficientMandibles
  • +
  • AG_FasterAging
  • +
  • PsychicAbility_Dull
  • +
  • FireTerror
  • +
  • Sterile
  • +
  • AG_FormicAntennas
  • +
  • Skin_DeepRed
  • +
  • AptitudeTerrible_Intellectual
  • +
  • rjw_genes_featureless_chest
  • +
  • rjw_genes_worker
  • +
  • rjw_genes_zealous_loyalty
  • +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/Scenarios/Halamyr_Hive.xml b/Common/Defs/Scenarios/Halamyr_Hive.xml new file mode 100644 index 0000000..1673a15 --- /dev/null +++ b/Common/Defs/Scenarios/Halamyr_Hive.xml @@ -0,0 +1,158 @@ + + + + + rjw_genes_scenario_halamyr_hive + + A young queen set out to build a new hive. After a long path, a suitable place is found to generate new offspring. DEVNOTE: Try to choose a high-food biome to keep up with the Hive! + + A Halamyr queen set out to build a new hive. + + PlayerFaction + PlayerTribe + + + + + +
  • + ConfigurePawnsXenotypes + 4 + Start with a set of Halamyr Xenotypes and one other colonist of any age. + + +
  • + rjw_genes_halamyr_queen_xenotype + 1 + non-baby halamyr queen + true + Adult +
  • + +
  • + rjw_genes_halamyr_hiveguard_xenotype + 1 + non-baby halamyr hiveguard + true + Adult +
  • + +
  • + rjw_genes_halamyr_breeder_xenotype + 1 + adulthalamyr breeder + true + Adult +
  • + +
  • + Baseliner + 2 +
  • + + + + +
  • + PlayerPawnsArriveMethod + Standing +
  • + + +
  • + ForcedHediff + false + PlayerStarter + 0.5 + Malnutrition + 0.1~0.2 +
  • +
  • + SetNeedLevel + false + PlayerStarter + 1.0 + Food + 0.3~0.8 +
  • + + +
  • + StartingThing_Defined + Silver + 300 +
  • +
  • + StartingThing_Defined + Pemmican + 350 +
  • +
  • + StartingThing_Defined + InsectJelly + 300 +
  • +
  • + StartingThing_Defined + MedicineHerbal + 30 +
  • +
  • + StartingThing_Defined + MeleeWeapon_Club + WoodLog +
  • + +
  • + StartingAnimal + Spelopede + 2 +
  • +
  • + StartingAnimal + Megascarab + 3 + 1.0 +
  • + +
  • + StartingAnimal + Megaspider + 1 +
  • + + +
  • + ScatterThingsNearPlayerStart + WoodLog + 500 +
  • +
  • + ScatterThingsNearPlayerStart + Jade + 100 +
  • + +
  • + ScatterThingsNearPlayerStart + Pemmican + 150 +
  • +
  • + ScatterThingsNearPlayerStart + Steel + 200 +
  • + + +
  • + GameStartDialog + After a long journey, this is it: \n\nThis is the right place to start the new hive. Spin in your breeders, build your defenses and start mating.\n\nMake this a place worthy for a queen. + GameStartSting +
  • + +
    +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/ThoughtDefs/Thoughts_Hive.xml b/Common/Defs/ThoughtDefs/Thoughts_Hive.xml new file mode 100644 index 0000000..8a232b3 --- /dev/null +++ b/Common/Defs/ThoughtDefs/Thoughts_Hive.xml @@ -0,0 +1,102 @@ + + + + + + + rjw_genes_rival_queen_mood + RJW_Genes.Thoughtworker_RivalQueen_Mood + false + +
  • + + There is another queen nearby! + -70 +
  • +
    +
    + + + + rjw_genes_rival_queen_social + Thought_SituationalSocial + RJW_Genes.Thoughtworker_RivalQueen_Social + +
  • + + {0} threatens my dominion. {0} must be perished. + -130 +
  • +
    +
    + + + rjw_genes_queen_despises_workers_social + Thought_SituationalSocial + RJW_Genes.ThoughtWorker_WorkerDespised_Social + +
  • + + those workers are not even worth a glance. + -20 +
  • +
    +
    + + + + rjw_genes_multiple_queens_mood + RJW_Genes.Thoughtworker_MultipleQueens_Mood + false + +
  • + + I have too many queens around me! + -30 +
  • +
    +
    + + + + rjw_genes_queen_loyalty_social + Thought_SituationalSocial + RJW_Genes.Thoughtworker_QueenPresent_Social + +
  • + + {0} is my queen. My one and only reason to live. + +80 +
  • +
    +
    + + + + rjw_genes_no_queen_mood + RJW_Genes.Thoughtworker_QueenAbsent_Mood + false + +
  • + + We do not have a queen! How are we suppossed to face the cruelties of the world without a shepherd? + -20 +
  • +
    +
    + + + + rjw_genes_queen_present_mood + RJW_Genes.Thoughtworker_QueenPresent_Mood + false + +
  • + + Our queen is so wonderful. + +10 +
  • +
    +
    + +
    diff --git a/Common/Languages/English/Keyed/Dialog_StatsReport.xml b/Common/Languages/English/Keyed/Dialog_StatsReport.xml new file mode 100644 index 0000000..53837f8 --- /dev/null +++ b/Common/Languages/English/Keyed/Dialog_StatsReport.xml @@ -0,0 +1,9 @@ + + + + + queen in proximity + queen absent + multiple queens present + + \ No newline at end of file diff --git a/Common/Patches/Xenotypes/FromRJWGenes/PatchLicentiaLabs.xml b/Common/Patches/Xenotypes/FromRJWGenes/PatchLicentiaLabs.xml deleted file mode 100644 index 5c85681..0000000 --- a/Common/Patches/Xenotypes/FromRJWGenes/PatchLicentiaLabs.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - -
  • LustLicentia.RJWLabs
  • -
    - - Defs/XenotypeDef[defName="rjw_genes_succubus"]/genes - -
  • rjw_genes_elasticity
  • -
    -
    -
    -
    \ No newline at end of file diff --git a/Common/Patches/Xenotypes/FromRJWGenes/Patch_Sexperience_SexSkill.xml b/Common/Patches/Xenotypes/FromRJWGenes/Patch_Sexperience_SexSkill.xml deleted file mode 100644 index 419eeb2..0000000 --- a/Common/Patches/Xenotypes/FromRJWGenes/Patch_Sexperience_SexSkill.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - -
  • - -
  • RJW Sexperience
  • - - - Defs/XenotypeDef[defName="rjw_genes_succubus"]/genes - -
  • AptitudeRemarkable_Sex
  • -
    -
    - -
  • - -
  • RJW Sexperience
  • - - - Defs/XenotypeDef[defName="rjw_genes_incubus"]/genes - -
  • AptitudeRemarkable_Sex
  • -
    -
    - - -
    -
    -
    \ No newline at end of file diff --git a/Common/Patches/Xenotypes/FromOtherMods/GenitaliaUpdate.xml b/Common/Patches/Xenotypes/GenitaliaUpdate.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/GenitaliaUpdate.xml rename to Common/Patches/Xenotypes/GenitaliaUpdate.xml diff --git a/Common/Patches/Xenotypes/PatchAlphaGenes.xml b/Common/Patches/Xenotypes/PatchAlphaGenes.xml new file mode 100644 index 0000000..5550f25 --- /dev/null +++ b/Common/Patches/Xenotypes/PatchAlphaGenes.xml @@ -0,0 +1,86 @@ + + + + +
  • + +
  • Alpha Genes
  • + + + Defs/XenotypeDef[defName="AG_Fleetkind"]/genes + +
  • rjw_genes_slime_genitalia
  • +
  • rjw_genes_elasticity
  • +
    +
    + + +
  • + +
  • Alpha Genes
  • + + + Defs/XenotypeDef[defName="AG_Helixien"]/genes + +
  • rjw_genes_slime_genitalia
  • +
  • rjw_genes_elasticity
  • +
    +
    + + +
  • + +
  • Alpha Genes
  • + + + Defs/XenotypeDef[defName="AG_Taukai"]/genes + +
  • rjw_genes_sexual_mytosis
  • +
    +
    + + +
  • + +
  • Alpha Genes
  • + + + Defs/XenotypeDef[defName="AG_MindDevourer"]/genes + +
  • rjw_genes_demonic_genitalia
  • +
  • rjw_genes_sex_age_drain
  • +
    +
    + + +
  • + +
  • Alpha Genes
  • + + + Defs/XenotypeDef[defName="AG_Lapis"]/genes + +
  • rjw_genes_big_breasts
  • +
  • rjw_genes_no_cum
  • +
  • rjw_genes_big_male_genitalia
  • +
    +
    + + +
  • + +
  • Alpha Genes
  • + + + Defs/XenotypeDef[defName="AG_Efreet"]/genes + +
  • rjw_genes_demonic_genitalia
  • +
  • rjw_genes_small_breasts
  • +
  • rjw_genes_tight_female_genitalia
  • +
  • rjw_genes_tight_anus
  • +
    +
    + +
    +
    +
    diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchBiotechNyaron.xml b/Common/Patches/Xenotypes/PatchBiotechNyaron.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchBiotechNyaron.xml rename to Common/Patches/Xenotypes/PatchBiotechNyaron.xml diff --git a/Common/Patches/Xenotypes/PatchErinsAuronya.xml b/Common/Patches/Xenotypes/PatchErinsAuronya.xml new file mode 100644 index 0000000..44e49d9 --- /dev/null +++ b/Common/Patches/Xenotypes/PatchErinsAuronya.xml @@ -0,0 +1,14 @@ + + + + +
  • Erin's Auronya
  • +
    + + Defs/XenotypeDef[defName="ERN_Auronya"]/genes + +
  • rjw_genes_feline_genitalia
  • +
    +
    +
    +
    \ No newline at end of file diff --git a/Common/Patches/Xenotypes/PatchErinsShisune.xml b/Common/Patches/Xenotypes/PatchErinsShisune.xml new file mode 100644 index 0000000..75b41c6 --- /dev/null +++ b/Common/Patches/Xenotypes/PatchErinsShisune.xml @@ -0,0 +1,14 @@ + + + + +
  • Erin's Shisune
  • +
    + + Defs/XenotypeDef[defName="ERN_Shisune"]/genes + +
  • rjw_genes_canine_genitalia
  • +
    +
    +
    +
    \ No newline at end of file diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchKijinRace3.xml b/Common/Patches/Xenotypes/PatchKijinRace3.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchKijinRace3.xml rename to Common/Patches/Xenotypes/PatchKijinRace3.xml diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchNarai.xml b/Common/Patches/Xenotypes/PatchNarai.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchNarai.xml rename to Common/Patches/Xenotypes/PatchNarai.xml diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchNyaron.xml b/Common/Patches/Xenotypes/PatchNyaron.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchNyaron.xml rename to Common/Patches/Xenotypes/PatchNyaron.xml diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchPapou.xml b/Common/Patches/Xenotypes/PatchPapou.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchPapou.xml rename to Common/Patches/Xenotypes/PatchPapou.xml diff --git a/Common/Patches/Xenotypes/PatchRoosFaun.xml b/Common/Patches/Xenotypes/PatchRoosFaun.xml new file mode 100644 index 0000000..8f33932 --- /dev/null +++ b/Common/Patches/Xenotypes/PatchRoosFaun.xml @@ -0,0 +1,17 @@ + + + + +
  • Roo's Faun Xenotype
  • +
    + + Defs/XenotypeDef[defName="RBSF_Faun"]/genes + +
  • rjw_genes_tight_female_genitalia
  • +
  • rjw_genes_small_male_genitalia
  • +
  • rjw_genes_small_breasts
  • +
  • rjw_genes_tight_anus
  • +
    +
    +
    +
    diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchRoosMinotaur.xml b/Common/Patches/Xenotypes/PatchRoosMinotaur.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchRoosMinotaur.xml rename to Common/Patches/Xenotypes/PatchRoosMinotaur.xml diff --git a/Common/Patches/Xenotypes/PatchRoosSatyr.xml b/Common/Patches/Xenotypes/PatchRoosSatyr.xml new file mode 100644 index 0000000..bfada1f --- /dev/null +++ b/Common/Patches/Xenotypes/PatchRoosSatyr.xml @@ -0,0 +1,15 @@ + + + + +
  • Roo's Satyr Xenotype
  • +
    + + Defs/XenotypeDef[defName="RBSF_Satyr"]/genes + +
  • rjw_genes_aphrodisiac_pheromones
  • +
  • rjw_genes_much_cum
  • +
    +
    +
    +
    diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchSaurid.xml b/Common/Patches/Xenotypes/PatchSaurid.xml similarity index 100% rename from Common/Patches/Xenotypes/FromOtherMods/PatchSaurid.xml rename to Common/Patches/Xenotypes/PatchSaurid.xml diff --git a/Common/Patches/Xenotypes/FromOtherMods/PatchVREPhytokin.xml b/Common/Patches/Xenotypes/PatchVREPhytokin.xml similarity index 86% rename from Common/Patches/Xenotypes/FromOtherMods/PatchVREPhytokin.xml rename to Common/Patches/Xenotypes/PatchVREPhytokin.xml index af7d43c..2c349ec 100644 --- a/Common/Patches/Xenotypes/FromOtherMods/PatchVREPhytokin.xml +++ b/Common/Patches/Xenotypes/PatchVREPhytokin.xml @@ -11,7 +11,7 @@
  • rjw_genes_tight_female_genitalia
  • rjw_genes_tight_anus
  • -
  • rjw_genes_elasticity
  • +
  • rjw_genes_elasticity
  • rjw_genes_bisexual
  • @@ -25,7 +25,7 @@
  • rjw_genes_tight_female_genitalia
  • rjw_genes_tight_anus
  • -
  • rjw_genes_elasticity
  • +
  • rjw_genes_elasticity
  • rjw_genes_bisexual
  • @@ -40,11 +40,11 @@
  • rjw_genes_tight_female_genitalia
  • rjw_genes_tight_anus
  • -
  • rjw_genes_elasticity
  • +
  • rjw_genes_elasticity
  • rjw_genes_bisexual
  • - \ No newline at end of file + diff --git a/Common/Patches/Xenotypes/FromRJWGenes/Patch_Dominant_Gene.xml b/Common/Patches/Xenotypes/PatchVRESanguophage.xml similarity index 56% rename from Common/Patches/Xenotypes/FromRJWGenes/Patch_Dominant_Gene.xml rename to Common/Patches/Xenotypes/PatchVRESanguophage.xml index 15b6f3f..03e3ba6 100644 --- a/Common/Patches/Xenotypes/FromRJWGenes/Patch_Dominant_Gene.xml +++ b/Common/Patches/Xenotypes/PatchVRESanguophage.xml @@ -4,38 +4,38 @@
  • -
  • Dominant Gene
  • +
  • Vanilla Races Expanded - Sanguophage
  • - Defs/XenotypeDef[defName="rjw_genes_succubus"]/genes + Defs/XenotypeDef[defName="VRE_Bruxa"]/genes -
  • DominantGene
  • +
  • rjw_genes_demonic_genitalia
  • -
  • Dominant Gene
  • +
  • Vanilla Races Expanded - Sanguophage
  • - Defs/XenotypeDef[defName="rjw_genes_incubus"]/genes + Defs/XenotypeDef[defName="VRE_Ekkimian"]/genes -
  • DominantGene
  • +
  • rjw_genes_demonic_genitalia
  • -
  • Dominant Gene
  • +
  • Vanilla Races Expanded - Sanguophage
  • - Defs/XenotypeDef[defName="rjw_genes_cumazone"]/genes + Defs/XenotypeDef[defName="VRE_Strigoi"]/genes -
  • DominantGene
  • +
  • rjw_genes_demonic_genitalia
  • - \ No newline at end of file + diff --git a/Common/Patches/Xenotypes/PatchXenotech.xml b/Common/Patches/Xenotypes/PatchXenotech.xml new file mode 100644 index 0000000..8ed3deb --- /dev/null +++ b/Common/Patches/Xenotypes/PatchXenotech.xml @@ -0,0 +1,69 @@ + + + + +
  • + +
  • [LTS]Xenotech
  • + + + Defs/XenotypeDef[defName="LTS_Nyankind"]/genes + +
  • rjw_genes_feline_genitalia
  • +
    +
    + +
  • + +
  • [LTS]Xenotech
  • + + + Defs/XenotypeDef[defName="LTS_Growler"]/genes + +
  • rjw_genes_canine_genitalia
  • +
    +
    + + +
  • + +
  • [LTS]Xenotech
  • + + + Defs/XenotypeDef[defName="LTS_Elfin"]/genes + +
  • rjw_genes_small_male_genitalia
  • +
  • rjw_genes_tight_female_genitalia
  • +
    +
    + + +
  • + +
  • [LTS]Xenotech
  • + + + Defs/XenotypeDef[defName="LTS_Ork"]/genes + +
  • rjw_genes_big_male_genitalia
  • +
  • rjw_genes_loose_female_genitalia
  • +
    +
    + + +
  • + +
  • [LTS]Xenotech
  • + + + Defs/XenotypeDef[defName="LTS_Lilime"]/genes + +
  • rjw_genes_demonic_genitalia
  • +
  • rjw_genes_elasticity
  • +
  • AptitudeRemarkable_Sex
  • +
    +
    + +
    +
    +
    diff --git a/Common/Textures/Genes/Icons/Bonus_Cum.png b/Common/Textures/Genes/Icons/Bonus_Cum.png deleted file mode 100644 index e6c51a4..0000000 Binary files a/Common/Textures/Genes/Icons/Bonus_Cum.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Cocoon.png b/Common/Textures/Genes/Icons/Cocoon.png new file mode 100644 index 0000000..4e62420 Binary files /dev/null and b/Common/Textures/Genes/Icons/Cocoon.png differ diff --git a/Common/Textures/Genes/Icons/Cum-Base.png b/Common/Textures/Genes/Icons/Cum-Base.png new file mode 100644 index 0000000..05ec22a Binary files /dev/null and b/Common/Textures/Genes/Icons/Cum-Base.png differ diff --git a/Common/Textures/Genes/Icons/Drone.png b/Common/Textures/Genes/Icons/Drone.png new file mode 100644 index 0000000..a631565 Binary files /dev/null and b/Common/Textures/Genes/Icons/Drone.png differ diff --git a/Common/Textures/Genes/Icons/Egg.png b/Common/Textures/Genes/Icons/Egg.png new file mode 100644 index 0000000..81b16bd Binary files /dev/null and b/Common/Textures/Genes/Icons/Egg.png differ diff --git a/Common/Textures/Genes/Icons/Extra_Vagina.png b/Common/Textures/Genes/Icons/Extra_Vagina.png new file mode 100644 index 0000000..12bb91a Binary files /dev/null and b/Common/Textures/Genes/Icons/Extra_Vagina.png differ diff --git a/Common/Textures/Genes/Icons/female_only.png b/Common/Textures/Genes/Icons/Female_Only.png similarity index 100% rename from Common/Textures/Genes/Icons/female_only.png rename to Common/Textures/Genes/Icons/Female_Only.png diff --git a/Common/Textures/Genes/Icons/Fervent_Ovipositor.png b/Common/Textures/Genes/Icons/Fervent_Ovipositor.png new file mode 100644 index 0000000..b9cc33e Binary files /dev/null and b/Common/Textures/Genes/Icons/Fervent_Ovipositor.png differ diff --git a/Common/Textures/Genes/Icons/Genitalia_Insect.png b/Common/Textures/Genes/Icons/Genitalia_Insect.png deleted file mode 100644 index e71cabe..0000000 Binary files a/Common/Textures/Genes/Icons/Genitalia_Insect.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Genitalia_Slime.png b/Common/Textures/Genes/Icons/Genitalia_Slime.png deleted file mode 100644 index ee7ae69..0000000 Binary files a/Common/Textures/Genes/Icons/Genitalia_Slime.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Insect_Breeder.png b/Common/Textures/Genes/Icons/Insect_Breeder.png new file mode 100644 index 0000000..5315179 Binary files /dev/null and b/Common/Textures/Genes/Icons/Insect_Breeder.png differ diff --git a/Common/Textures/Genes/Icons/Loose_Female_Genitalia.png b/Common/Textures/Genes/Icons/Loose_Female_Genitalia.png deleted file mode 100644 index 63b6a9c..0000000 Binary files a/Common/Textures/Genes/Icons/Loose_Female_Genitalia.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Loose_Vagina.png b/Common/Textures/Genes/Icons/Loose_Vagina.png new file mode 100644 index 0000000..57a4706 Binary files /dev/null and b/Common/Textures/Genes/Icons/Loose_Vagina.png differ diff --git a/Common/Textures/Genes/Icons/Loyalty.png b/Common/Textures/Genes/Icons/Loyalty.png new file mode 100644 index 0000000..8ac3c4c Binary files /dev/null and b/Common/Textures/Genes/Icons/Loyalty.png differ diff --git a/Common/Textures/Genes/Icons/male_only.png b/Common/Textures/Genes/Icons/Male_Only.png similarity index 100% rename from Common/Textures/Genes/Icons/male_only.png rename to Common/Textures/Genes/Icons/Male_Only.png diff --git a/Common/Textures/Genes/Icons/More_Egg_Space.png b/Common/Textures/Genes/Icons/More_Egg_Space.png deleted file mode 100644 index 35fbcb3..0000000 Binary files a/Common/Textures/Genes/Icons/More_Egg_Space.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Much_Bonus_Cum.png b/Common/Textures/Genes/Icons/Much_Bonus_Cum.png deleted file mode 100644 index d512725..0000000 Binary files a/Common/Textures/Genes/Icons/Much_Bonus_Cum.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Much_Cum.png b/Common/Textures/Genes/Icons/Much_Cum.png new file mode 100644 index 0000000..21a9a17 Binary files /dev/null and b/Common/Textures/Genes/Icons/Much_Cum.png differ diff --git a/Common/Textures/Genes/Icons/No_Cum.png b/Common/Textures/Genes/Icons/No_Cum.png index 2084b5e..a7964f0 100644 Binary files a/Common/Textures/Genes/Icons/No_Cum.png and b/Common/Textures/Genes/Icons/No_Cum.png differ diff --git a/Common/Textures/Genes/Icons/No_Female_Genitalia.png b/Common/Textures/Genes/Icons/No_Female_Genitalia.png deleted file mode 100644 index 9405ce7..0000000 Binary files a/Common/Textures/Genes/Icons/No_Female_Genitalia.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/No_Vagina.png b/Common/Textures/Genes/Icons/No_Vagina.png new file mode 100644 index 0000000..a4f47ee Binary files /dev/null and b/Common/Textures/Genes/Icons/No_Vagina.png differ diff --git a/Common/Textures/Genes/Icons/Ovipositor_Genitalia.png b/Common/Textures/Genes/Icons/Ovipositor_Genitalia.png new file mode 100644 index 0000000..97421e1 Binary files /dev/null and b/Common/Textures/Genes/Icons/Ovipositor_Genitalia.png differ diff --git a/Common/Textures/Genes/Icons/Paralysing_Kiss.png b/Common/Textures/Genes/Icons/Paralysing_Kiss.png new file mode 100644 index 0000000..20c4fd5 Binary files /dev/null and b/Common/Textures/Genes/Icons/Paralysing_Kiss.png differ diff --git a/Common/Textures/Genes/Icons/Pheromone.png b/Common/Textures/Genes/Icons/Pheromone.png new file mode 100644 index 0000000..342f695 Binary files /dev/null and b/Common/Textures/Genes/Icons/Pheromone.png differ diff --git a/Common/Textures/Genes/Icons/Pheromones.png b/Common/Textures/Genes/Icons/Pheromones.png new file mode 100644 index 0000000..88a6c53 Binary files /dev/null and b/Common/Textures/Genes/Icons/Pheromones.png differ diff --git a/Common/Textures/Genes/Icons/Queen.png b/Common/Textures/Genes/Icons/Queen.png new file mode 100644 index 0000000..b087f03 Binary files /dev/null and b/Common/Textures/Genes/Icons/Queen.png differ diff --git a/Common/Textures/Genes/Icons/RJW-Genes_Endogene_Background (Not in use now).png b/Common/Textures/Genes/Icons/RJW_Genes_Endogene_Background.png similarity index 100% rename from Common/Textures/Genes/Icons/RJW-Genes_Endogene_Background (Not in use now).png rename to Common/Textures/Genes/Icons/RJW_Genes_Endogene_Background.png diff --git a/Common/Textures/Genes/Icons/RJW-Genes_Xenogene_Background (Not in use now).png b/Common/Textures/Genes/Icons/RJW_Genes_Xenogene_Background.png similarity index 100% rename from Common/Textures/Genes/Icons/RJW-Genes_Xenogene_Background (Not in use now).png rename to Common/Textures/Genes/Icons/RJW_Genes_Xenogene_Background.png diff --git a/Common/Textures/Genes/Icons/Slime_Genitalia.png b/Common/Textures/Genes/Icons/Slime_Genitalia.png new file mode 100644 index 0000000..91e6cd0 Binary files /dev/null and b/Common/Textures/Genes/Icons/Slime_Genitalia.png differ diff --git a/Common/Textures/Genes/Icons/Spelopede_Dispenser.png b/Common/Textures/Genes/Icons/Spelopede_Dispenser.png new file mode 100644 index 0000000..4308892 Binary files /dev/null and b/Common/Textures/Genes/Icons/Spelopede_Dispenser.png differ diff --git a/Common/Textures/Genes/Icons/Tight_Female_Genitalia.png b/Common/Textures/Genes/Icons/Tight_Female_Genitalia.png deleted file mode 100644 index d0931fa..0000000 Binary files a/Common/Textures/Genes/Icons/Tight_Female_Genitalia.png and /dev/null differ diff --git a/Common/Textures/Genes/Icons/Tight_Vagina.png b/Common/Textures/Genes/Icons/Tight_Vagina.png new file mode 100644 index 0000000..eab0606 Binary files /dev/null and b/Common/Textures/Genes/Icons/Tight_Vagina.png differ diff --git a/Common/Textures/Genes/Icons/Very_Much_Cum.png b/Common/Textures/Genes/Icons/Very_Much_Cum.png new file mode 100644 index 0000000..f2fedc1 Binary files /dev/null and b/Common/Textures/Genes/Icons/Very_Much_Cum.png differ diff --git a/Common/Textures/Genes/Icons/Vitality_Drainer.png b/Common/Textures/Genes/Icons/Vitality_Drainer.png new file mode 100644 index 0000000..1de65a9 Binary files /dev/null and b/Common/Textures/Genes/Icons/Vitality_Drainer.png differ diff --git a/Common/Textures/Genes/Icons/Worker.png b/Common/Textures/Genes/Icons/Worker.png new file mode 100644 index 0000000..1f4e0c8 Binary files /dev/null and b/Common/Textures/Genes/Icons/Worker.png differ diff --git a/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Breeder.png b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Breeder.png new file mode 100644 index 0000000..9ffab2c Binary files /dev/null and b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Breeder.png differ diff --git a/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Cumazon.png b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Cumazon.png new file mode 100644 index 0000000..8d285e5 Binary files /dev/null and b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Cumazon.png differ diff --git a/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Guard.png b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Guard.png new file mode 100644 index 0000000..e831799 Binary files /dev/null and b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Guard.png differ diff --git a/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Incubus.png b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Incubus.png new file mode 100644 index 0000000..14d6685 Binary files /dev/null and b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Incubus.png differ diff --git a/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Queen.png b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Queen.png new file mode 100644 index 0000000..9b0f425 Binary files /dev/null and b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Queen.png differ diff --git a/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Succubus.png b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Succubus.png new file mode 100644 index 0000000..dddb34d Binary files /dev/null and b/Common/Textures/Genes/Icons/Xenotypes/Xenotype-Succubus.png differ diff --git a/Common/Textures/Genes/Icons/extra_female.png b/Common/Textures/Genes/Icons/extra_female.png deleted file mode 100644 index 1a6ae6e..0000000 Binary files a/Common/Textures/Genes/Icons/extra_female.png and /dev/null differ diff --git a/Common/Textures/Things/Mote/Cocoon/WeaveA.psd b/Common/Textures/Things/Mote/Cocoon/WeaveA.psd new file mode 100644 index 0000000..2328868 Binary files /dev/null and b/Common/Textures/Things/Mote/Cocoon/WeaveA.psd differ diff --git a/Common/Textures/Things/Mote/Cocoon/WeaveB.psd b/Common/Textures/Things/Mote/Cocoon/WeaveB.psd new file mode 100644 index 0000000..c1a852e Binary files /dev/null and b/Common/Textures/Things/Mote/Cocoon/WeaveB.psd differ diff --git a/KNOWN_BUGS.md b/KNOWN_BUGS.md index f9bc556..b836d4e 100644 --- a/KNOWN_BUGS.md +++ b/KNOWN_BUGS.md @@ -2,6 +2,20 @@ Collection of Known Bugs and reasons for their origin. +## My Youth Fountain / Age Drainer Pawns do not alter Ages!!! + +Issue: You had a pawn with Youth Fountain have Sex with another Pawn, and the other pawn did not get younger. + +Please Check: + +- Are both pawns in OK Age? +- Did they maybe change age but you didn't notice? Default settings only change by days. +- Did they finish sex? If they are interrupted, nothing happens + +Otherwise: + +Enable the Debug-Settings and provide me with a log. + ## I changed Parts of a pawn and my genes do not apply! Issue: You had a pawn with "huge genitalia" and add a horse-cock with licentia or surgery. This new genitalia is not huge. diff --git a/README.md b/README.md index f0a12ac..6c427df 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,16 @@ This mod adds genes related and based on RJW to Rimworld. - Extra Genitalia (and a Futa Attempt) - Most RJW Traits, Cumflation Immunity, Elasticity - Cum-Amount Changes, Transfer Nutrition Boosts -- Mech Breeding / Insect Breeding Additions +- Mech Breeding / Insect Breeding Additions & Orgasmic Mytosis - Human-Animal Gene Inheritance merged from [Shabakur](https://github.com/Shabakur/RJW_Animal_Gene_Inheritance) - Succubi, Incubi & Cumazones that utilize Fertilin, similar to Hemogen +- Insect-Caste Mechanics, with Queens, Drones and Workers and a conditional reproduction +- Patches for some popular / common Xenotypes from other Mods. See [planned things](TODOS.md) and feel free to contribute. With the Human-Animal-Gene Inheritance we have a lot of XML that you can contribute! We have a [template](./Common/Defs/RaceGeneDefs/RaceGeneDefs_template.xml) and you can add animals and/or genes from mods there (Racegroups are base-rjw). +If you want to make your own Hive-Xenotypes, please see the required XMLs at [Changelog - 1.2](./CHANGELOG.md). ## Bugs? @@ -38,4 +41,7 @@ Please load this after any mod adding genes, and after the used RJW-Mods (Licent **Conflicts:** 1. Should not be used with the original RJW_Animal_Gene_Inheritance anymore. 2. There was an issue with other "Male-Only / Female-Only" Mods --- for which we provide our own Genes now. -3. CAI5000 will not crash, but will make *Seduce*-Ability fail. I think same goes for Combat Extended. \ No newline at end of file +3. CAI5000 will not crash, but will make *Seduce*-Ability fail. I think same goes for Combat Extended. +4. Alpha Genes "Female / Male Only" Genes might overwrite later Genitalia-Changes and should be avoided in combination with RJW-Genes features. +5. rjw.sexperience.cumgenes removes fertilin-gain from Cum item - I hope I addressed this by adding a load order but keep me posted (Issue #41) +6. [Consistent Gene Inheritance](https://steamcommunity.com/sharedfiles/filedetails/?id=2881479142&searchtext=Consistent+Gene+Inheritance) alters inheritance - it messes a bit with the Insect-Caste Logic. Your game will not crash, but the insect xenotypes will be a bit messed up. \ No newline at end of file diff --git a/Source/Animal_Inheritance/Harmony_Init.cs b/Source/Animal_Inheritance/Harmony_Init.cs deleted file mode 100644 index 1852e9b..0000000 --- a/Source/Animal_Inheritance/Harmony_Init.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using Verse; - -namespace RJW_BGS -{ - [StaticConstructorOnStartup] - internal static class HarmonyInit - { - // Token: 0x0600001F RID: 31 RVA: 0x000029A4 File Offset: 0x00000BA4 - static HarmonyInit() - { - Harmony harmony = new Harmony("RJW_BGS"); - harmony.PatchAll(); - } - } -} diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs index e4af81f..1bc9770 100644 --- a/Source/GeneDefOf.cs +++ b/Source/GeneDefOf.cs @@ -76,9 +76,10 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_youth_fountain; public static readonly GeneDef rjw_genes_sex_age_drain; public static readonly GeneDef rjw_genes_aphrodisiac_pheromones; + public static readonly GeneDef rjw_genes_sexual_mytosis; - // LifeForce - public static readonly GeneDef rjw_genes_lifeforce; + // LifeForce + public static readonly GeneDef rjw_genes_lifeforce; public static readonly GeneDef rjw_genes_pussyhealing; public static readonly GeneDef rjw_genes_lifeforce_drain; public static readonly GeneDef rjw_genes_cum_eater; @@ -92,6 +93,15 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_succubus_tail; public static readonly GeneDef rjw_genes_succubus_wings; + // Hive + public static readonly GeneDef rjw_genes_queen; + public static readonly GeneDef rjw_genes_drone; + public static readonly GeneDef rjw_genes_worker; + public static readonly GeneDef rjw_genes_zealous_loyalty; + public static readonly GeneDef rjw_genes_cocoonweaver; + public static readonly GeneDef rjw_genes_spawn_spelopede; + + //Other Defs public static readonly XenotypeDef rjw_genes_succubus; public static readonly DutyDef rjw_genes_flirt; diff --git a/Source/Genes/ExtraGenitalia/Gene_FeaturelessChest.cs b/Source/Genes/ExtraGenitalia/Gene_FeaturelessChest.cs index 8a93c51..00b4c82 100644 --- a/Source/Genes/ExtraGenitalia/Gene_FeaturelessChest.cs +++ b/Source/Genes/ExtraGenitalia/Gene_FeaturelessChest.cs @@ -1,6 +1,5 @@ using Verse; using rjw; -using RimWorld; namespace RJW_Genes { @@ -54,7 +53,7 @@ namespace RJW_Genes internal void AddFeaturelessBreast() { var partBPR = Genital_Helper.get_breastsBPR(pawn); - this.added_nipples = pawn.health.AddHediff(Genital_Helper.featureless_chest, partBPR); + added_nipples = pawn.health.AddHediff(Genital_Helper.featureless_chest, partBPR); } } diff --git a/Source/Genes/ExtraGenitalia/Gene_NoAnus.cs b/Source/Genes/ExtraGenitalia/Gene_NoAnus.cs index d23b2df..8aad9ab 100644 --- a/Source/Genes/ExtraGenitalia/Gene_NoAnus.cs +++ b/Source/Genes/ExtraGenitalia/Gene_NoAnus.cs @@ -9,9 +9,6 @@ namespace RJW_Genes internal Hediff removed_anus; - // TODO: This gene only works if another Gene was set specifying the genitalia. - // If it is added later, it still works, but on creation it needs a different - // TODO: If all Genitalia are removed by genes, RJW adds some to the pawns at spawn public override void PostMake() { base.PostMake(); diff --git a/Source/Genes/ExtraGenitalia/Gene_NoBreasts.cs b/Source/Genes/ExtraGenitalia/Gene_NoBreasts.cs index 874ff5f..caa0a5c 100644 --- a/Source/Genes/ExtraGenitalia/Gene_NoBreasts.cs +++ b/Source/Genes/ExtraGenitalia/Gene_NoBreasts.cs @@ -52,15 +52,5 @@ namespace RJW_Genes } } - /* - /// - /// Adds a "rjw.featurelesschest", which means nipples but nothing else (like male human pawns do). - /// - internal void AddFeaturelessBreast() - { - var partBPR = Genital_Helper.get_breastsBPR(pawn); - //this.added_nipples = pawn.health.AddHediff(Genital_Helper.featureless_chest, partBPR); - } - */ } } diff --git a/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs b/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs index be67ef4..b107a5a 100644 --- a/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs +++ b/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs @@ -9,9 +9,6 @@ namespace RJW_Genes internal Hediff removed_penis; - // TODO: This gene only works if another Gene was set specifying the genitalia. - // If it is added later, it still works, but on creation it needs a different - // TODO: If all Genitalia are removed by genes, RJW adds some to the pawns at spawn public override void PostMake() { base.PostMake(); diff --git a/Source/Genes/ExtraGenitalia/Gene_NoVagina.cs b/Source/Genes/ExtraGenitalia/Gene_NoVagina.cs index 8083f58..438d76e 100644 --- a/Source/Genes/ExtraGenitalia/Gene_NoVagina.cs +++ b/Source/Genes/ExtraGenitalia/Gene_NoVagina.cs @@ -8,10 +8,7 @@ namespace RJW_Genes { internal Hediff removed_vagina; - - // TODO: This gene only works if another Gene was set specifying the genitalia. - // If it is added later, it still works, but on creation it needs a different - // TODO: If all Genitalia are removed by genes, RJW adds some to the pawns at spawn + public override void PostMake() { base.PostMake(); diff --git a/Source/Genes/ExtraGenitalia/Gene_UdderBreasts.cs b/Source/Genes/ExtraGenitalia/Gene_UdderBreasts.cs new file mode 100644 index 0000000..e098a8c --- /dev/null +++ b/Source/Genes/ExtraGenitalia/Gene_UdderBreasts.cs @@ -0,0 +1,78 @@ +using rjw; +using Verse; + +namespace RJW_Genes +{ + + /// + /// Removes breasts for female (and trap, futa) pawns and adds Udders. + /// Wished for in Issue #27. + /// + /// TODO: Currently, the sexualizer over-writes the added udders and just adds another pair of breasts! + /// I commented out the gene in .xml for now. + /// + public class Gene_UdderBreasts : RJW_Gene + { + + Hediff removed_breasts; + Hediff added_udders; + + public override void PostMake() + { + base.PostMake(); + + // Breasts are replaced for female,trap and futa pawns + if ( removed_breasts == null + && (GenderUtility.IsFemale(pawn) || GenderHelper.GetSex(pawn) == GenderHelper.Sex.futa || GenderHelper.GetSex(pawn) == GenderHelper.Sex.trap) + ) + { + RemoveButStoreBreasts(); + AddUdders(); + } + + } + + public override void PostAdd() + { + base.PostAdd(); + + // Breasts are replaced for female,trap and futa pawns + if (removed_breasts == null + && (GenderUtility.IsFemale(pawn) || GenderHelper.GetSex(pawn) == GenderHelper.Sex.futa || GenderHelper.GetSex(pawn) == GenderHelper.Sex.trap) + ) + { + RemoveButStoreBreasts(); + AddUdders(); + } + } + + public override void PostRemove() + { + base.PostRemove(); + // Re-Add the old breasts + if (removed_breasts != null) + pawn.health.AddHediff(removed_breasts); + if (added_udders != null) + pawn.health.RemoveHediff(added_udders); + } + + internal void RemoveButStoreBreasts() + { + var partBPR = Genital_Helper.get_breastsBPR(pawn); + Hediff breastsToRemove = Genital_Helper.get_AllPartsHediffList(pawn).FindLast(x => GenitaliaUtility.IsBreasts(x)); + + if (breastsToRemove != null) + { + removed_breasts = breastsToRemove; + pawn.health.RemoveHediff(breastsToRemove); + } + } + + internal void AddUdders() + { + BodyPartRecord bpr = Genital_Helper.get_uddersBPR(pawn); + added_udders = pawn.health.AddHediff(Genital_Helper.udder_breasts, bpr); + } + } + +} \ No newline at end of file diff --git a/Source/Genes/Gender/GenderUtility.cs b/Source/Genes/Gender/GenderUtility.cs index ea0e1d6..10b811d 100644 --- a/Source/Genes/Gender/GenderUtility.cs +++ b/Source/Genes/Gender/GenderUtility.cs @@ -1,9 +1,10 @@ using Verse; using rjw; using RimWorld; -using System.Collections; using System.Linq; using System; +using System.Collections.Generic; +using HarmonyLib; namespace RJW_Genes { @@ -69,5 +70,36 @@ namespace RJW_Genes // Force Redraw at the spot pawn.Drawer.renderer.graphics.SetAllGraphicsDirty(); } + + // Fetch these once at load time because they don't change inside RJW + private static readonly List wasSexThoughts = Traverse.Create(typeof(GenderHelper)).Field("old_sex_list").GetValue>(); + private static readonly List sexChangeThoughts = Traverse.Create(typeof(GenderHelper)).Field("SexChangeThoughts").GetValue>(); + + /// + /// This method removes all RJW-Sexchange-Hediffs from the pawn. + /// It used with the RJW_Gene.Notify_OnPawnGeneration() to check for pawns on spawn. + /// + /// Fixes Issue #32, where pawns that spawn fresh with a "all female" gene may have m2f thoughts. + /// + /// The pawn that needs to have SexChange-Thoughts removed. + public static void RemoveAllSexChangeThoughts(Pawn pawn) + { + // Shouldn't ever be true in the normal case, but this stops someone from calling this with an incorrect setup + if (pawn?.health == null) + return; + + if(wasSexThoughts == null || sexChangeThoughts == null || !wasSexThoughts.Any() || !sexChangeThoughts.Any()) + { + Log.Warning($"Couldn't get values from RJW.\nold_sex_list: {wasSexThoughts.ToStringSafeEnumerable()}\nSexChangeThoughts: {sexChangeThoughts.ToStringSafeEnumerable()}"); + return; + } + + foreach(var def in wasSexThoughts.Concat(sexChangeThoughts)) + { + var hediff = pawn.health.hediffSet.GetFirstHediffOfDef(def); + if (hediff != null) + pawn.health.RemoveHediff(hediff); + } + } } } diff --git a/Source/Genes/Gender/Gene_FemaleOnly.cs b/Source/Genes/Gender/Gene_FemaleOnly.cs index 0cfbe0d..97c4365 100644 --- a/Source/Genes/Gender/Gene_FemaleOnly.cs +++ b/Source/Genes/Gender/Gene_FemaleOnly.cs @@ -4,7 +4,7 @@ using rjw; namespace RJW_Genes { - public class Gene_FemaleOnly : Gene + public class Gene_FemaleOnly : RJW_Gene { public override void PostMake() { @@ -38,5 +38,11 @@ namespace RJW_Genes } } + public override void Notify_OnPawnGeneration() + { + base.Notify_OnPawnGeneration(); + // If this is Pawn generation, then we can assume that the pawn was never any gender other than female, so they shouldn't have sex change thoughts. (Issue #32) + GenderUtility.RemoveAllSexChangeThoughts(pawn); + } } } diff --git a/Source/Genes/Gender/Gene_MaleOnly.cs b/Source/Genes/Gender/Gene_MaleOnly.cs index 51806cf..e081700 100644 --- a/Source/Genes/Gender/Gene_MaleOnly.cs +++ b/Source/Genes/Gender/Gene_MaleOnly.cs @@ -4,7 +4,7 @@ using rjw; namespace RJW_Genes { - public class Gene_MaleOnly : Gene + public class Gene_MaleOnly : RJW_Gene { public override void PostMake() { @@ -38,5 +38,11 @@ namespace RJW_Genes } } + public override void Notify_OnPawnGeneration() + { + base.Notify_OnPawnGeneration(); + // If this is Pawn generation, then we can assume that the pawn was never any gender other than male, so they shouldn't have sex change thoughts. (Issue #32) + GenderUtility.RemoveAllSexChangeThoughts(pawn); + } } } diff --git a/Source/Genes/GeneUtility.cs b/Source/Genes/GeneUtility.cs index a6361aa..c46e6e1 100644 --- a/Source/Genes/GeneUtility.cs +++ b/Source/Genes/GeneUtility.cs @@ -17,23 +17,29 @@ namespace RJW_Genes public static void OffsetLifeForce(IGeneResourceDrain drain, float offset) { - float old_value = drain.Resource.Value; - drain.Resource.Value += offset; - PostOffSetLifeForce(drain, old_value); + if (drain.Resource != null && drain.Resource.Active) { + float old_value = drain.Resource.Value; + drain.Resource.Value += offset; + PostOffSetLifeForce(drain, old_value); + } } public static void PostOffSetLifeForce(IGeneResourceDrain drain, float old_value) { - if (old_value > 0.2f && drain.Resource.Value <= 0.2f) - { - //TODO: Mood debuff - } - else if (old_value > 0f && drain.Resource.Value <= 0f) + + if (drain.Resource != null && drain.Resource.Active) { - Pawn pawn = drain.Pawn; - if (!drain.Pawn.health.hediffSet.HasHediff(HediffDefOf.rjw_genes_fertilin_craving)) + if (old_value > 0.2f && drain.Resource.Value <= 0.2f) { - drain.Pawn.health.AddHediff(HediffDefOf.rjw_genes_fertilin_craving); + //TODO: Mood debuff + } + else if (old_value > 0f && drain.Resource.Value <= 0f) + { + Pawn pawn = drain.Pawn; + if (!drain.Pawn.health.hediffSet.HasHediff(HediffDefOf.rjw_genes_fertilin_craving)) + { + drain.Pawn.health.AddHediff(HediffDefOf.rjw_genes_fertilin_craving); + } } } } @@ -127,26 +133,3 @@ namespace RJW_Genes } } - -/* -Exception in Verse.AI.ThinkNode_Priority TryIssueJobPackage: System.NullReferenceException: Object reference not set to an instance of an object - at RJW_Genes.GeneUtility.HasLowLifeForce (Verse.Pawn pawn) [0x00014] in < 881b7541af8144a78a14c9dad08e43c7 >:0 - at RJW_Genes.ThinkNode_ConditionalLowLifeForce.Satisfied(Verse.Pawn p) [0x00000] in < 881b7541af8144a78a14c9dad08e43c7 >:0 - at Verse.AI.ThinkNode_Conditional.TryIssueJobPackage(Verse.Pawn pawn, Verse.AI.JobIssueParams jobParams) [0x00000] in < 38562b1a2ab64eacb931fb5df05ca994 >:0 - at Verse.AI.ThinkNode_Priority.TryIssueJobPackage(Verse.Pawn pawn, Verse.AI.JobIssueParams jobParams) [0x00022] in < 38562b1a2ab64eacb931fb5df05ca994 >:0 -UnityEngine.StackTraceUtility:ExtractStackTrace() -Verse.Log:Error(string) -Verse.AI.ThinkNode_Priority:TryIssueJobPackage(Verse.Pawn, Verse.AI.JobIssueParams) -Verse.AI.ThinkNode_SubtreesByTag:TryIssueJobPackage(Verse.Pawn, Verse.AI.JobIssueParams) -Verse.AI.ThinkNode_Priority:TryIssueJobPackage(Verse.Pawn, Verse.AI.JobIssueParams) -Verse.AI.Pawn_JobTracker:DetermineNextJob(Verse.ThinkTreeDef &) -Verse.AI.Pawn_JobTracker:TryFindAndStartJob() -Verse.AI.Pawn_JobTracker:EndCurrentJob(Verse.AI.JobCondition, bool, bool) -Verse.AI.Pawn_JobTracker:JobTrackerTick() -Verse.Pawn:Tick() -Verse.TickList:Tick() -(wrapper dynamic - method) Verse.TickManager:Verse.TickManager.DoSingleTick_Patch2(Verse.TickManager) -Verse.TickManager:TickManagerUpdate() -Verse.Game:UpdatePlay() -Verse.Root_Play:Update() -*/ \ No newline at end of file diff --git a/Source/Genes/Genitalia/GenitaliaUtility.cs b/Source/Genes/Genitalia/GenitaliaUtility.cs index 4dc289a..c762071 100644 --- a/Source/Genes/Genitalia/GenitaliaUtility.cs +++ b/Source/Genes/Genitalia/GenitaliaUtility.cs @@ -99,6 +99,7 @@ namespace RJW_Genes case "rjw_genes_demonic_genitalia": return Genital_Helper.average_breasts; case "rjw_genes_dragon_genitalia": return Genital_Helper.average_breasts; case "rjw_genes_slime_genitalia": return Genital_Helper.slime_breasts; + case "rjw_genes_udder_breasts": return Genital_Helper.udder_breasts; case "rjw_genes_ovipositor_genitalia": return Genital_Helper.average_breasts; default: return Genital_Helper.generic_breasts; diff --git a/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs b/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs index ee24126..1a9cc73 100644 --- a/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs +++ b/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs @@ -1,16 +1,34 @@ -namespace RJW_Genes +using Verse; + +namespace RJW_Genes { /// /// Parent Gene for Genitalia Resizing. All Resizing genes should inherit for this class. + /// There is a companion-patch `Patch_ResizingOnAdulthood`. /// /// This helps with some functions (e.g. "hasGenitaliaResizingGenes(pawn)") but also to fire genitalia resizing later in life for Pawns. /// (No Children with huge ding dongs, and I don't want kids with tight anuses I am not that degenerate) + /// + /// + /// There was an Issue (#34) that re-sized the genitalia over multiple birthdays. + /// Before the addition of `ExposeData`, it lost track whether the resizing was already run, + /// leading to a change with every birthday over multiple game starts. /// public abstract class Gene_GenitaliaResizingGene : RJW_Gene { - public const int RESIZING_AGE = 20; - public bool WasApplied { get; set; } + /// + /// The age (in years) at which the Pawns Genes will take effect, resizing their genitalia. + /// + public const int RESIZING_AGE = 20; + + /// + /// Whether or not the gene was already applied. + /// If not, it is checked on every birthday and will be applied accordingly. + /// + private bool resizingWasApplied = false; + public bool ResizingWasApplied { get => resizingWasApplied; set => resizingWasApplied = value; } + public override void PostMake() { @@ -18,7 +36,7 @@ if (pawn.ageTracker.AgeBiologicalYears >= RESIZING_AGE) { Resize(); - WasApplied = true; + ResizingWasApplied = true; } } @@ -28,19 +46,25 @@ if (pawn.ageTracker.AgeBiologicalYears >= RESIZING_AGE) { Resize(); - WasApplied = true; + ResizingWasApplied = true; } } + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref resizingWasApplied, "wasApplied"); + } + /// /// Used to resize the pawns genitalia. /// All Logic should be put here: /// 1. Filters for Gender - /// 2. Filters for Genitalia Existance + /// 2. Filters for Genitalia Existence /// 3. Selection of right Genitalia /// 4. Adjustment of Size /// - /// I kept it intentionally broad, so that e.g. the Penis Resize can resize multiple penises and also for futas, + /// I kept it intentionally broad, so that e.g. the Penis Resize can resize multiple penises and or futas, /// while the breast-gene is female only. /// public abstract void Resize(); diff --git a/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs b/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs index b8542a0..4fa1904 100644 --- a/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs +++ b/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs @@ -7,6 +7,8 @@ namespace RJW_Genes /// This Patch adds behavior to all resizing genes: /// At Age RESIZING_MIN_AGE the Pawns Resizing Genes will trigger again, if not already triggered somewhere else. /// This is meant to allow kids to grow up without resized genitals, and resize later (Fixing #11). + /// + /// See `Gene_GenitaliaResizingGene` for a short summary of Issue #34. /// [HarmonyPatch(typeof(Pawn_AgeTracker), "BirthdayBiological")] public class Patch_ResizingOnAdulthood @@ -18,10 +20,10 @@ namespace RJW_Genes { foreach(Gene_GenitaliaResizingGene gene in GeneUtility.GetGenitaliaResizingGenes(___pawn)) { - if (!gene.WasApplied) + if (!gene.ResizingWasApplied) { gene.Resize(); - gene.WasApplied = true; + gene.ResizingWasApplied = true; } } } diff --git a/Source/Genes/Hive/Abilities/CompAbilityEffect_CocoonWeaver.cs b/Source/Genes/Hive/Abilities/CompAbilityEffect_CocoonWeaver.cs new file mode 100644 index 0000000..af362aa --- /dev/null +++ b/Source/Genes/Hive/Abilities/CompAbilityEffect_CocoonWeaver.cs @@ -0,0 +1,81 @@ +using Verse; +using RimWorld; +using rjw; + +namespace RJW_Genes +{ + /// + /// The CocoonWeaver Ability applies the RJW-Cocoon to a pawn. + /// Friendly Pawns can always be cocooned, neutral and hostile pawns must be downed. + /// + public class CompAbilityEffect_CocoonWeaver : CompAbilityEffect + { + private new CompProperties_AbilityCocoonWeaver Props + { + get + { + return (CompProperties_AbilityCocoonWeaver)this.props; + } + } + + + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) + { + base.Apply(target, dest); + + Pawn CocooningPawn = this.parent.pawn; + Pawn PawnToCocoon = target.Pawn; + + // Error Case - Null Pawn + if (PawnToCocoon == null) + { + return; + } + + PawnToCocoon.health.AddHediff(HediffDef.Named("RJW_Cocoon")); + + } + + /// + /// For validity, there are a few checks: + /// 0. Target is not already cocooned + /// 1. Target is either Colonist / Prisoner + /// 2. If the Target is an enemy or neutral, it must be downed. + /// + public override bool Valid(LocalTargetInfo target, bool throwMessages = false) + { + Pawn cocoonTarget = target.Pawn; + if (cocoonTarget != null) + { + bool CocoonTargetIsColonistOrPrisoner = cocoonTarget.Faction == this.parent.pawn.Faction || cocoonTarget.IsPrisonerOfColony; + bool CocoonTargetIsHostile = cocoonTarget.HostileTo(this.parent.pawn); + bool CocoonTargetIsDowned = cocoonTarget.Downed; + + if (cocoonTarget.health.hediffSet.hediffs.Any(t => t.def.defName == "RJW_Cocoon")) + { + if (throwMessages) + Messages.Message(cocoonTarget.Name + " is already cocooned.", cocoonTarget, MessageTypeDefOf.RejectInput, false); + return false; + } + + if (!CocoonTargetIsColonistOrPrisoner && !(CocoonTargetIsHostile && CocoonTargetIsDowned)) + { + if (throwMessages) + { + if(CocoonTargetIsHostile && !CocoonTargetIsDowned) + { + Messages.Message(cocoonTarget.Name + " is hostile, but not downed.", cocoonTarget, MessageTypeDefOf.RejectInput, false); + } + else if (!CocoonTargetIsColonistOrPrisoner) + { + Messages.Message(cocoonTarget.Name + " is not a part of the colony or hostile.", cocoonTarget, MessageTypeDefOf.RejectInput, false); + } + } + return false; + } + } + return base.Valid(target, throwMessages); + } + + } +} diff --git a/Source/Genes/Hive/Abilities/CompAbilityEffect_SpawnSpelopede.cs b/Source/Genes/Hive/Abilities/CompAbilityEffect_SpawnSpelopede.cs new file mode 100644 index 0000000..4932949 --- /dev/null +++ b/Source/Genes/Hive/Abilities/CompAbilityEffect_SpawnSpelopede.cs @@ -0,0 +1,80 @@ +using Verse; +using RimWorld; +using rjw; +using RimWorld.Planet; +using System; + +namespace RJW_Genes +{ + /// + /// Spawns tame spelopedes at the caster. + /// + /// TODO: Play some sound? I think this can be done with some CompProperties. + /// + public class CompAbilityEffect_SpawnSpelopede : CompAbilityEffect + { + public CompProperties_AbilitySpawnSpelopede Props => (CompProperties_AbilitySpawnSpelopede) this.props; + + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) + { + base.Apply(target, dest); + + + int spelopedesToSpawn = CalculateSpelopedeAmount(); + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Using Spelopede Spawn, spawning {spelopedesToSpawn}"); + + for (int i = 0; i < spelopedesToSpawn; i++) { + var request = new PawnGenerationRequest( + this.Props.pawnKindDef, + faction: this.parent.pawn.Faction, + forceGenerateNewPawn: true, + fixedBiologicalAge: 0.0f, + fixedChronologicalAge: 0.0f, + canGeneratePawnRelations: false, + colonistRelationChanceFactor: 0.0f + ); + + + Pawn insect = PawnGenerator.GeneratePawn(request); + PawnUtility.TrySpawnHatchedOrBornPawn(insect, this.parent.pawn); + + if (Props.tamed) + { + insect.training.Train(TrainableDefOf.Tameness, this.parent.pawn, true); + insect.training.Train(TrainableDefOf.Obedience, this.parent.pawn, true); + insect.training.Train(TrainableDefOf.Release, this.parent.pawn, true); + + // I could do bonding here, but I think it's nicer if the queen is not "bonded" to their offspring. + } + } + + MakeDirt(1); + + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message("Finished Spelopede Spawn"); + + } + + private int CalculateSpelopedeAmount() + { + Pawn caster = this.parent.pawn; + float spelopedes = Props.sensitivityMultiplier * caster.psychicEntropy.PsychicSensitivity; + return (spelopedes > 1.49f) ? (int)Math.Round(spelopedes) : 1; + } + + private void MakeDirt(int multiplier = 1) + { + Pawn caster = this.parent.pawn; + + FilthMaker.TryMakeFilth(caster.Position, caster.Map, ThingDefOf.Filth_AmnioticFluid, caster.LabelIndefinite(), count: Rand.Range(5,5*multiplier)); + } + + public override bool Valid(LocalTargetInfo target, bool throwMessages = false) + { + if (!target.Cell.Filled(this.parent.pawn.Map) && (target.Cell.GetEdifice(this.parent.pawn.Map) == null)) + return true; + if (throwMessages) + Messages.Message((string)("CannotUseAbility".Translate((NamedArgument)this.parent.def.label) + ": " + "AbilityOccupiedCells".Translate()), (LookTargets)target.ToTargetInfo(this.parent.pawn.Map), MessageTypeDefOf.RejectInput, false); + return false; + } + } +} diff --git a/Source/Genes/Hive/Abilities/CompProperties_AbilityCocoonWeaver.cs b/Source/Genes/Hive/Abilities/CompProperties_AbilityCocoonWeaver.cs new file mode 100644 index 0000000..e73d22d --- /dev/null +++ b/Source/Genes/Hive/Abilities/CompProperties_AbilityCocoonWeaver.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; + +namespace RJW_Genes +{ + public class CompProperties_AbilityCocoonWeaver : CompProperties_AbilityEffect + { + public CompProperties_AbilityCocoonWeaver() + { + this.compClass = typeof(CompAbilityEffect_CocoonWeaver); + } + } +} diff --git a/Source/Genes/Hive/Abilities/CompProperties_AbilitySpawnSpelopede.cs b/Source/Genes/Hive/Abilities/CompProperties_AbilitySpawnSpelopede.cs new file mode 100644 index 0000000..1bf71df --- /dev/null +++ b/Source/Genes/Hive/Abilities/CompProperties_AbilitySpawnSpelopede.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; + +namespace RJW_Genes +{ + public class CompProperties_AbilitySpawnSpelopede : CompProperties_AbilityEffect + { + public PawnKindDef pawnKindDef; + public float sensitivityMultiplier; + public bool tamed; + public CompProperties_AbilitySpawnSpelopede() + { + this.compClass = typeof(CompAbilityEffect_SpawnSpelopede); + } + } +} diff --git a/Source/Genes/Hive/Defs/HiveOffspringChanceDef.cs b/Source/Genes/Hive/Defs/HiveOffspringChanceDef.cs new file mode 100644 index 0000000..77a4c28 --- /dev/null +++ b/Source/Genes/Hive/Defs/HiveOffspringChanceDef.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 HiveOffspringChanceDef : Def + { + + public string queenXenotype; + + // Chance of the below should be 1 when summed up! + // Otherwise the roll-logic fails. + + public double queenChance; + public double droneChance; + public double workerChance; + + } +} diff --git a/Source/Genes/Hive/Defs/QueenWorkerMappingDef.cs b/Source/Genes/Hive/Defs/QueenWorkerMappingDef.cs new file mode 100644 index 0000000..b825c7c --- /dev/null +++ b/Source/Genes/Hive/Defs/QueenWorkerMappingDef.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + /// + /// This def covers the birth of workers for each queen-xenotype. + /// + /// It is used when a baby is born to a pawn with the queen-xenotype; + /// There is a random check for the type of the baby, and if the baby is born to be a worker, + /// additional genes are looked up here. + /// + public class QueenWorkerMappingDef : Def + { + public string queenXenotype; + public List workerGenes; + } +} diff --git a/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_MultipleQueens.cs b/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_MultipleQueens.cs new file mode 100644 index 0000000..22f0ba1 --- /dev/null +++ b/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_MultipleQueens.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using RimWorld; +using Verse; + +namespace RJW_Genes +{ + + /// + /// Checks if there are multiple queens on the map. + /// + public class ConditionalStatAffecter_MultipleQueens : ConditionalStatAffecter + { + public override string Label => (string)"StatsReport_MultipleQueens".Translate(); + + public override bool Applies(StatRequest req) + { + if (req.Pawn == null || !req.Pawn.Spawned) + return false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(req.Pawn)) + return false; + + if (GeneUtility.HasGeneNullCheck(req.Pawn, GeneDefOf.rjw_genes_zealous_loyalty)) + { + return HiveUtility.QueensOnMap() >= 2; + } + + return false; + } + } +} diff --git a/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_QueenAbsent.cs b/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_QueenAbsent.cs new file mode 100644 index 0000000..9a468df --- /dev/null +++ b/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_QueenAbsent.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using RimWorld; +using Verse; + +namespace RJW_Genes +{ + + /// + /// Checks if there is no queen on the map. + /// + public class ConditionalStatAffecter_QueenAbsent : ConditionalStatAffecter + { + public override string Label => (string)"StatsReport_QueenAbsent".Translate(); + + public override bool Applies(StatRequest req) + { + if (req.Pawn == null || !req.Pawn.Spawned) + return false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(req.Pawn)) + return false; + + if (GeneUtility.HasGeneNullCheck(req.Pawn, GeneDefOf.rjw_genes_zealous_loyalty)) + { + return HiveUtility.QueensOnMap() == 0; + } + + return false; + } + } +} diff --git a/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_QueenCloseBy.cs b/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_QueenCloseBy.cs new file mode 100644 index 0000000..e604b54 --- /dev/null +++ b/Source/Genes/Hive/Genes/ConditionalStatAffecters/ConditionalStatAffecter_QueenCloseBy.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using RimWorld; +using Verse; + +namespace RJW_Genes +{ + + /// + /// Checks if there is (exactly) one queen nearby. + /// If the pawn is a queen itself, it's checked if there are OTHER queens nearby. + /// While this is used for mostly positive things for workers and drones, for queens it checks if there is a rival nearby. + /// + public class ConditionalStatAffecter_QueenCloseBy : ConditionalStatAffecter + { + + const float EFFECT_DISTANCE = 10.0f; + + public override string Label => (string)"StatsReport_QueenCloseBy".Translate(); + + public override bool Applies(StatRequest req) + { + if (req.Pawn == null || !req.Pawn.Spawned) + return false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(req.Pawn)) + return false; + + // Case A: Check for Loyal Pawns if their One Queen is nearby + if (GeneUtility.HasGeneNullCheck(req.Pawn, GeneDefOf.rjw_genes_zealous_loyalty) && HiveUtility.QueensOnMap() == 1) + { + Pawn queen = HiveUtility.GetQueensOnMap()[0]; + + return req.Pawn.Position.DistanceTo(queen.Position) <= EFFECT_DISTANCE; + } + + // Case A: Check for Queen if another Queen is nearby + if (GeneUtility.HasGeneNullCheck(req.Pawn, GeneDefOf.rjw_genes_zealous_loyalty) && HiveUtility.QueensOnMap() >= 2) + { + foreach (Pawn queen in HiveUtility.GetQueensOnMap()) + { + if (queen != req.Pawn && req.Pawn.Position.DistanceTo(queen.Position) <= EFFECT_DISTANCE) + return true; + } + } + + + return false; + } + } +} diff --git a/Source/Genes/Hive/Genes/Gene_FerventOvipositor.cs b/Source/Genes/Hive/Genes/Gene_FerventOvipositor.cs new file mode 100644 index 0000000..353148a --- /dev/null +++ b/Source/Genes/Hive/Genes/Gene_FerventOvipositor.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Verse; +using rjw; + +namespace RJW_Genes +{ + + /// + /// Manages the rjw_genes_fervent_ovipositor to grow eggs much faster. + /// + /// TODO: Move the Multiplier into XML + /// TODO: This gene only works after the first egg, the first egg for two new pawns spawns at the same time (strange). + /// + public class Gene_FerventOvipositor : Gene + { + + const int MULTIPLIER = 3; // Tick 3 times as much, making a pawn with this Gene Produce Eggs 4 times as fast as the normal. + + public override void Tick() + { + base.Tick(); + + if (pawn == null) return; + + Hediff_PartBaseNatural OvipositorF = (Hediff_PartBaseNatural) pawn.health.hediffSet.GetFirstHediffOfDef(rjw.Genital_Helper.ovipositorF); + + if (OvipositorF == null) return; + + OvipositorF.nextEggTick = Math.Max(OvipositorF.nextEggTick - MULTIPLIER, -1); + + // DevNote: I first had a for-loop calling OviPositorF.tick(), but I fear that would be a performance sink. + // Also, it would double other aspects as well, such as bleeding out through your insect-PP or dropping out the eggs. + } + + + } +} diff --git a/Source/Genes/Hive/Genes/Gene_InsectIncubator.cs b/Source/Genes/Hive/Genes/Gene_InsectIncubator.cs new file mode 100644 index 0000000..5173dd0 --- /dev/null +++ b/Source/Genes/Hive/Genes/Gene_InsectIncubator.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 Verse; + +namespace RJW_Genes +{ + + /// + /// This Gene checks for all parasitic Insect-Eggs in a Pawn: + /// 1. Is it fertilized ? => tick it down "extra". + /// 2. Is it not fertilized? => fertilize it with the Incubator as parent + /// + /// To save performance, this gene fires (default) every 0.5h, which also means a slight delay until fertilization happens. + /// + /// Important: The other half of the behavior for the gene (more egg-capacity) is in `Patch_InsectINcubator_PregnancyHelper`. + /// + public class Gene_InsectIncubator : Gene + { + + const int TICK_INTERVAL = 60000 / 48; // 60k = 1 day, we want 0.5h which is 1/48th of 1 day. + + public override void Tick() + { + base.Tick(); + + // Don't check too often, only in the HashTickInterval to safe some computing power + if (this.pawn.IsHashIntervalTick(TICK_INTERVAL) && this.pawn.Map != null) + { + List eggs = new List(); + pawn.health.hediffSet.GetHediffs(ref eggs); + // This part works as intended and shows Non-Human Eggs too + //if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Gene_InsectIncubator: Found {eggs.Count} Hediff_InsectEgg in {pawn}"); + + + foreach (Hediff_InsectEgg egg in eggs) + { + // The implanter check checks if the egg is still in an ovipositor. + if (egg.implanter == null || egg.implanter == pawn) + continue; + + if (!egg.fertilized && egg.implanter != null) { + egg.Fertilize(pawn); + // DevNote Issue 38: Sometimes Eggs are not fertilized here, because the normal Fertilize Function is called which has an upper Limit on Gestation. + // I will not do anything about it here, maybe upstream, but I print here. + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + { + if (egg.fertilized) + ModLog.Message($"Gene_InsectIncubator: fertilized egg {egg} in {pawn}"); + else if (egg.GestationProgress > 0.5) + ModLog.Message($"Gene_InsectIncubator: Failed to fertilize {egg} in {pawn} due to high gestation progress"); + else + ModLog.Message($"Gene_InsectIncubator: failed to fertiliz egg {egg} in {pawn}"); + } + } + // DevNote: There is an issue with Eggs reaching too much gestation progress (>100%), which causes DownStream bugs. To avoid this, there are some extra checks in place. + else if (egg.fertilized && egg.GestationProgress <= .93) + { + egg.lastTick += TICK_INTERVAL; + } + } + } + } + } +} diff --git a/Source/Genes/Hive/Helpers/HiveBirthLogic.cs b/Source/Genes/Hive/Helpers/HiveBirthLogic.cs new file mode 100644 index 0000000..8bb1600 --- /dev/null +++ b/Source/Genes/Hive/Helpers/HiveBirthLogic.cs @@ -0,0 +1,152 @@ +using RimWorld; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + /// + /// DevNote: Issue #37 came along because I checked for getMother() and getFather(), but it can happen that a pawn has two mothers. + /// They are called Mother if they have a ParentRelation and are female. + /// New behaviour iterates over all parents and returns the first queen/drone or null. + /// + public class HiveBirthLogic + { + /// + /// Central function for the Hive-Birth logic used in Patches. + /// *Only* run this, if the pawn has a queen parent (either as mother/father, or as implanter in case of egg-logic). + /// Covers the following behavior: + /// 1. look up the Defs for the mother and HiveOffspringChances (or defaults) + /// 2. If there is no drone involved, default to worker + /// 3. Roll a random dice + /// 3.1 Make a queen + /// 3.2 Make a drone + /// 3.3 Make a worker + /// + /// The pawn born, that maybe becomes a hive-xenotype. + /// whether there was a drone parent involved + public static void ManageHiveBirth(Pawn pawn, bool hasDroneParent = false, XenotypeDef fallbackQueenDef = null, XenotypeDef fallbackDroneDef = null) + { + XenotypeDef queenDef = TryFindParentQueenXenotype(pawn); + if (queenDef == null) queenDef = fallbackQueenDef; + HiveOffspringChanceDef hiveOffspringChanceDef = HiveUtility.LookupHiveInheritanceChances(queenDef); + + // Case 1: Mother is Queen, Father is something else. Produce Worker. + if (!hasDroneParent) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawn} was born as a worker, as it did not have Drone Father ({100}% chance)"); + MakeWorker(pawn, queenDef); + } + // Case 2: Mother is Queen, Father is drone. Apply xenotype as per chance. + else + { + double roll = (new Random()).NextDouble(); + // Case 2.a: New Queen born + if (roll < hiveOffspringChanceDef.queenChance) + { + pawn.genes.SetXenotype(queenDef); + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawn} born as a new queen with xenotype {queenDef.defName} ({hiveOffspringChanceDef.queenChance * 100}% chance,rolled {roll})"); + MakeQueenBornLetter(pawn); + } + // Case 2.b: New Drone born + else if (roll < hiveOffspringChanceDef.droneChance + hiveOffspringChanceDef.queenChance) + { + XenotypeDef droneDef = TryFindParentDroneXenotype(pawn); + if (droneDef == null) droneDef = fallbackDroneDef; + pawn.genes.SetXenotype(droneDef); + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawn} born as a new drone with xenotype {droneDef.defName} ({(hiveOffspringChanceDef.droneChance + hiveOffspringChanceDef.queenChance) * 100}% chance,rolled {roll}))"); + } + // Case 2.c: Worker + else + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawn} born as a worker ({(hiveOffspringChanceDef.workerChance) * 100}% chance,rolled {roll}))"); + MakeWorker(pawn, queenDef); + } + } + } + + + /// + /// Turns a given pawn into a worker, by looking up the relevant genes as per queen. + /// + /// If the queen xenotype has no mapping, the "rjw_genes_default_worker_xenotype" are used instead. + /// The genes are added as endogenes, so the worker can still become a xenotype. + /// + /// The pawn for which the genes are added. + /// The xenotype of the queen, used for lookup. + private static void MakeWorker(Pawn pawnTobeWorker, XenotypeDef queenDef) + { + if (pawnTobeWorker == null) + return; + + var mappings = HiveUtility.GetQueenWorkerMappings(); + + var genes = mappings.TryGetValue(queenDef, HiveUtility.LookupDefaultWorkerGenes()); + + foreach (var gene in genes) + pawnTobeWorker.genes.AddGene(gene, false); + + pawnTobeWorker.genes.xenotypeName = "Worker"; + } + + /// + /// Looks up if there is a Xenotype with Drone-Gene for the pawns parents. + /// This is to account that maybe father or mother are the drone (instead of hardcoding things for father). + /// If both are drones, the mothers is returned. + /// + /// The pawn for whichs parent the xenotypes is looked up. + /// The Drone-Xenotype of a parent or null. If both are drones, mothers are preferred. + public static XenotypeDef TryFindParentDroneXenotype(Pawn pawn) + { + if (pawn == null) + return null; + + List parentRelations = pawn.relations.DirectRelations.FindAll(rel => rel.def.Equals(PawnRelationDefOf.Parent)); + foreach (DirectPawnRelation parent in parentRelations) + { + XenotypeDef xenotype = HiveUtility.TryGetDroneXenotype(parent.otherPawn); + if (xenotype != null) return xenotype; + } + + return null; + } + + public static void MakeQueenBornLetter(Pawn bornQueen) + { + if (bornQueen == null) return; + + var letter= LetterMaker.MakeLetter( + "New Queen", "A new Queen was born! Make sure to adress inheritance before the new queen reaches adolesence.", LetterDefOf.NeutralEvent, bornQueen + ); + //letter.Start(); + Find.LetterStack.ReceiveLetter(letter); + } + + /// + /// Looks up if there is a Xenotype with Queen-Gene for the pawns parents. + /// This is to account that maybe father or mother are the queen (instead of hardcoding things for father). + /// If both are queens, the first is returned. + /// + /// The pawn for whichs parent the xenotypes is looked up. + /// The Queen-Xenotype of a parent or null. If both are queens, mothers are preferred. + public static XenotypeDef TryFindParentQueenXenotype(Pawn pawn) + { + if (pawn == null) + return null; + + List parentRelations = pawn.relations.DirectRelations.FindAll(rel => rel.def.Equals(PawnRelationDefOf.Parent)); + foreach (var parent in parentRelations) + { + XenotypeDef xenotype = HiveUtility.TryGetQueenXenotype(parent.otherPawn); + if (xenotype != null) return xenotype; + } + + return null; + } + } +} diff --git a/Source/Genes/Hive/Helpers/HiveUtility.cs b/Source/Genes/Hive/Helpers/HiveUtility.cs new file mode 100644 index 0000000..c7d262d --- /dev/null +++ b/Source/Genes/Hive/Helpers/HiveUtility.cs @@ -0,0 +1,229 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + internal class HiveUtility + { + + /// + /// Checks for existance of the RJW-Gene `queen`, if the pawn is spawned and if the pawn has reached adulthood. + /// Despite the naming, a Queen can also be male. + /// + /// The pawn that could be an Adult Queen + /// Whether the pawn is an adult queen. + public static bool IsAdultQueen(Pawn pawn) + { + + if (pawn == null || !pawn.Spawned) + return false; + + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_queen)) + { + return pawn.ageTracker.Adult; + } + + return false; + } + + public static int QueensOnMap() => GetQueensOnMap().Count; + + /// + /// Checks for all pawns on the Players Home Map if they are an adult queen. + /// Adultness is determined by Base-Game Logic, Queen is determined by the rjw_genes_queen GeneDefOf (Not Xenotype). + /// + /// A list of queens on the players HomeMap + public static List GetQueensOnMap() + { + Map map = Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).First(); + + if (map != null) + { + List playersPawns = map.mapPawns.SpawnedPawnsInFaction(Faction.OfPlayer); + return playersPawns.FindAll(pawn => pawn.Spawned && IsAdultQueen(pawn)); + } + // Fallback: Something is wrong with Map + return new List(); + } + + /// + /// Checks if the pawn is on the players home map. + /// + /// Reason is that drones should only be punished for absence of queen if they are on the map and there is no queen. + /// If they are on a mission, transport-pod etc. they should not get boni or mali. + /// + /// The pawn for which to check map-presence. + /// True if the pawn is on the home-map, False otherwise. + public static bool PawnIsOnHomeMap(Pawn pawn) + { + Map homeMap = Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).First(); + return + homeMap != null && pawn != null + && pawn.Spawned + && pawn.Map == homeMap; + } + + /// + /// Returns the Xenotype of a pawn if the pawn has a xenotype with the queen gene. + /// Null otherwise. + /// + /// + /// A xenotype with a queen gene, or null. + public static XenotypeDef TryGetQueenXenotype(Pawn pawn) + { + if (pawn == null) + return null; + + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_queen)) + { + var potentialXenotype = pawn.genes.Xenotype; + if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_queen)) + { + return potentialXenotype; + } + } + + return null; + } + + + /// + /// Returns the Xenotype of a pawn if the pawn has a xenotype with the drone gene. + /// Null otherwise. + /// + /// + /// A xenotype with a drone gene, or null. + public static XenotypeDef TryGetDroneXenotype(Pawn pawn) + { + if (pawn == null) + return null; + + if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_drone)) + { + var potentialXenotype = pawn.genes.Xenotype; + if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_drone)) + { + return potentialXenotype; + } + } + + return null; + } + + /// + /// Looks up the Queen-WorkerMappings and returns a cleaned / updated dictionary. + /// + /// This method takes care of genes maybe not existing (from other mods) or misspellings etc. + /// Prints a bigger piece of information when debug printing is enabled. + /// + /// A mapping which Queen-Xenotypes should produce which worker genes. + + public static Dictionary> GetQueenWorkerMappings() + { + Dictionary> dict = new Dictionary>(); + IEnumerable mappingDefs = DefDatabase.AllDefs; + + // Dev-Note: I first a nice lambda here, but I used nesting in favour of logging. + foreach (QueenWorkerMappingDef mappingDef in mappingDefs) + { + + if (mappingDef.defName == "rjw_genes_default_worker_genes") + { + // Do nothing, there is no lookup but this entry is fine and should not log a warning. + continue; + } + XenotypeDef queenDef = DefDatabase.GetNamed(mappingDef.queenXenotype); + if (queenDef != null) + { + List workerGenes = new List(); + foreach (string geneName in mappingDef.workerGenes) + { + GeneDef workerGene = DefDatabase.GetNamed(geneName); + if (workerGene != null) + workerGenes.Add(workerGene); + else if(RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Warning($"Could not look up Gene {geneName} for {mappingDef.queenXenotype}."); + } + dict.Add(queenDef, workerGenes); + } + else { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Warning($"Did not find a matching xenotype for {mappingDef.queenXenotype}! Defaulting to rjw_genes_default_worker_genes."); + } + } + + return dict; + } + + /// + /// Looks up the default genes for any queen offspring that has no other definition for it. + /// This is done by looking for the mapping with *exactly* defName rjw_genes_default_worker_genes. + /// + /// The idea is that players can edit the default types, but that this is a protected keyword. + /// + /// A list of genes for workers that do not have specific mappings defined. + public static List LookupDefaultWorkerGenes() + { + IEnumerable mappingDefs = DefDatabase.AllDefs; + + List workerGenes = new List(); + + var defaultMapping = mappingDefs.First(m => m.defName == "rjw_genes_default_worker_genes"); + if (defaultMapping == null) + { + ModLog.Error("Did not find default worker genes for queen-offspring! Please make sure you did not rename the 'rjw_genes_default_worker_genes'."); + return workerGenes; + } + + foreach (string geneName in defaultMapping.workerGenes) + { + GeneDef workerGene = DefDatabase.GetNamed(geneName); + if (workerGene != null) + workerGenes.Add(workerGene); + else if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Warning($"Could not look up gene {geneName} for rjw_genes_default_worker_genes."); + } + + return workerGenes; + } + + public static IEnumerable getQueenXenotypes() + { + return DefDatabase.AllDefs.Where(type => type.genes.Contains(GeneDefOf.rjw_genes_queen)); + } + + public static IEnumerable getDroneXenotypes() + { + return DefDatabase.AllDefs.Where(type => type.genes.Contains(GeneDefOf.rjw_genes_drone)); + } + + + public static HiveOffspringChanceDef LookupDefaultHiveInheritanceChances() + { + IEnumerable offspringChanceDefs = DefDatabase.AllDefs; + + List workerGenes = new List(); + + var defaultChance = offspringChanceDefs.First(m => m.defName == "rjw_genes_default_hive_offspring_chances"); + + if (defaultChance == null) + ModLog.Warning("Did not find `rjw_genes_default_hive_offspring_chances`. Someone likely changed the defname!"); + + return defaultChance; + } + + public static HiveOffspringChanceDef LookupHiveInheritanceChances(XenotypeDef queenDef) + { + IEnumerable offspringChanceDefs = DefDatabase.AllDefs; + + return offspringChanceDefs.FirstOrFallback(t => t.queenXenotype == queenDef.defName, LookupDefaultHiveInheritanceChances()); + } + + + } +} diff --git a/Source/Genes/Hive/Patches/Patch_BirthOutcome_SetHiveGenes.cs b/Source/Genes/Hive/Patches/Patch_BirthOutcome_SetHiveGenes.cs new file mode 100644 index 0000000..7bdf206 --- /dev/null +++ b/Source/Genes/Hive/Patches/Patch_BirthOutcome_SetHiveGenes.cs @@ -0,0 +1,53 @@ +using HarmonyLib; +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + /// + /// Patches the method `ApplyBirthOutcome` from `PregnancyUtility`. + /// + /// The 'ApplyBirthOutcome' returns the finished baby, for which we alter the pawn according to our xenotypes. + /// + + [HarmonyPatch(typeof(PregnancyUtility), nameof(PregnancyUtility.ApplyBirthOutcome))] + public class Patch_BirthOutcome_SetHiveGenes + { + + + [HarmonyPostfix] + static void HandleHiveBasedInheritance(ref Thing __result) + { + + // Check: Was the born thing a pawn? + if (__result == null || !(__result is Pawn)) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message("There was a birth of something non-human - not entering logic for queen-drone-xenotype inheritance."); + return; + } + + Pawn pawn = (Pawn)__result; + + // Important: Not all pawns have mother/father. Some Pawns are born in Growth-Vats or born from mod. + bool hasQueenParent = HiveBirthLogic.TryFindParentQueenXenotype(pawn) != null; + bool hasDroneParent = HiveBirthLogic.TryFindParentDroneXenotype(pawn) != null; + + if (hasQueenParent) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"PostFix PregnancyUtility::ApplyBirthOutcome - Checking Hive Inheritance because {pawn} has a queen parent."); + + HiveBirthLogic.ManageHiveBirth(pawn, hasDroneParent); + } + else + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Ignoring Postfix PregnancyUtility::ApplyBirthOutcome - No Quene Parent - Doing Nothing"); + } + } + + } +} diff --git a/Source/Genes/Breeding/Patch_EggFertilization.cs b/Source/Genes/Hive/Patches/Patch_InsectBreeder_EggFertilization.cs similarity index 97% rename from Source/Genes/Breeding/Patch_EggFertilization.cs rename to Source/Genes/Hive/Patches/Patch_InsectBreeder_EggFertilization.cs index d2f2dcf..6184b4a 100644 --- a/Source/Genes/Breeding/Patch_EggFertilization.cs +++ b/Source/Genes/Hive/Patches/Patch_InsectBreeder_EggFertilization.cs @@ -12,9 +12,10 @@ namespace RJW_Genes /// Patched Class is https://gitgud.io/Ed86/rjw/-/blob/master/1.4/Source/Common/Helpers/SexUtility.cs /// /// Normal Egg-Pregnancy logic is in https://gitgud.io/Ed86/rjw/-/blob/master/1.4/Source/Modules/Pregnancy/Pregnancy_Helper.cs + /// Gene: rjw_genes_insectbreeder /// [HarmonyPatch(typeof(SexUtility), "Aftersex")] - static class Patch_EggFertilization + static class Patch_InsectBreeder_EggFertilization { public static void Postfix(SexProps props) { diff --git a/Source/Genes/Hive/Patches/Patch_InsectEggs_BirthBaby_SetHiveGenes.cs b/Source/Genes/Hive/Patches/Patch_InsectEggs_BirthBaby_SetHiveGenes.cs new file mode 100644 index 0000000..fe9155e --- /dev/null +++ b/Source/Genes/Hive/Patches/Patch_InsectEggs_BirthBaby_SetHiveGenes.cs @@ -0,0 +1,103 @@ +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 +{ + /// + /// Patches the method `ProcessHumanLikeInsectEgg` from `Hediff_InsectEgg`. + /// + /// The 'ProcessHumanLikeInsectEgg' returns the finished baby, for which we alter the pawn according to our xenotypes. + /// Note: This covers Insect-Egg Pregnancies only, and there is a (very similar) class `Patch_BirthOutCome_SetHiveGenes.cs` that handles normal pregnancies + /// + + [HarmonyPatch(typeof(Hediff_InsectEgg), "ProcessHumanLikeInsectEgg")] + public class Patch_InsectEgg_BirthBaby_SetHiveGenes + { + + + [HarmonyPostfix] + static void HandleHiveBasedInheritance(ref Thing __result, ref Hediff_InsectEgg __instance) + { + // Check: Was the born thing a pawn? + if (__result == null || !(__result is Pawn)) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message("There was a birth of something non-human - not entering logic for queen-drone-xenotype inheritance."); + return; + } + + Pawn pawn = (Pawn)__result; + + XenotypeDef queenDef = HiveBirthLogic.TryFindParentQueenXenotype(pawn) ?? TryFindParentQueenXenotypeFromEgg(__instance); + XenotypeDef droneDef = HiveBirthLogic.TryFindParentDroneXenotype(pawn) ?? TryFindParentDroneXenotypeFromEgg(__instance); + + bool hasQueenParent = queenDef != null; + bool hasDroneParent = droneDef != null; + + if (hasQueenParent) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"PostFix Hediff_InsectEgg::ProcessHumanLikeInsectEgg - Checking Hive Inheritance because {pawn} has a queen parent."); + HiveBirthLogic.ManageHiveBirth(pawn, hasDroneParent, fallbackQueenDef: queenDef, fallbackDroneDef: droneDef); + } else + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Ignoring Postfix Hediff_InsectEgg::ProcessHumanLikeInsectEgg - No Queen Parent - No Action."); + } + } + + /// + /// Tries to retrieve a queen-xenotype-def from a given egg. + /// Checking priority goes: Implanter > Fertilizer > Null Otherwise. + /// + /// This is meant to be a fallback to the parent-relations which were not present in RJW 5.3.1. + /// Some comments and thoughts are captured in Issue #37. + /// + /// An Egg for which queens are looked up for + /// The relevant xenotypedef of a queen, or null. + public static XenotypeDef TryFindParentQueenXenotypeFromEgg(Hediff_InsectEgg egg) + { + XenotypeDef queenDef = null; + if (egg == null) + return null; + + if (egg.implanter != null) + queenDef = HiveUtility.TryGetQueenXenotype(egg.implanter); + + if (queenDef == null && egg.father != null) + queenDef = HiveUtility.TryGetQueenXenotype(egg.implanter); + + return queenDef; + } + + + + /// + /// Tries to retrieve a drone-xenotype-def from a given egg. + /// Checking priority goes: Implanter > Fertilizer > Null Otherwise. + /// + /// This is meant to be a fallback to the parent-relations which were not present in RJW 5.3.1. + /// Some comments and thoughts are captured in Issue #37. + /// + /// An Egg for which drones are looked up for + /// The relevant xenotypedef of a drone, or null. + public static XenotypeDef TryFindParentDroneXenotypeFromEgg(Hediff_InsectEgg egg) + { + XenotypeDef droneDef = null; + if (egg == null) + return null; + + if (egg.implanter != null) + droneDef = HiveUtility.TryGetQueenXenotype(egg.implanter); + + if (droneDef == null && egg.father != null) + droneDef = HiveUtility.TryGetQueenXenotype(egg.implanter); + + return droneDef; + } + } +} diff --git a/Source/Genes/Breeding/PatchPregnancyHelper.cs b/Source/Genes/Hive/Patches/Patch_InsectIncubator_PregnancyHelper.cs similarity index 95% rename from Source/Genes/Breeding/PatchPregnancyHelper.cs rename to Source/Genes/Hive/Patches/Patch_InsectIncubator_PregnancyHelper.cs index 81a0ad4..fc3e530 100644 --- a/Source/Genes/Breeding/PatchPregnancyHelper.cs +++ b/Source/Genes/Hive/Patches/Patch_InsectIncubator_PregnancyHelper.cs @@ -15,9 +15,11 @@ namespace RJW_Genes /// /// This Class patches the RJW-DoEgg to allow up to MaxEggSizeMul times the original amount of eggs. /// This harmony patch was kindly provided by 'shabalox' https://github.com/Shabalox/RJW_Genes_Addons/ + /// + /// For Gene: rjw_genes_insectincubator /// [HarmonyPatch(typeof(PregnancyHelper), "DoEgg")] - static class PatchPregnancyHelper + static class Patch_InsectIncubator_PregnancyHelper { [HarmonyTranspiler] public static IEnumerable Transpiler(IEnumerable instructions, ILGenerator il) diff --git a/Source/Genes/Hive/Thoughts/ThoughtWorker_QueenPresent_Social.cs b/Source/Genes/Hive/Thoughts/ThoughtWorker_QueenPresent_Social.cs new file mode 100644 index 0000000..e4e7792 --- /dev/null +++ b/Source/Genes/Hive/Thoughts/ThoughtWorker_QueenPresent_Social.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 +{ + public class ThoughtWorker_QueenPresent_Social : ThoughtWorker + { + protected override ThoughtState CurrentSocialStateInternal(Pawn p, Pawn other) + { + // p is the pawn `thinking`, and other is the pawn being thought about. + // here: p = loyal pawn, other = potential queen + + if (!p.RaceProps.Humanlike) + return (ThoughtState) false; + + if (!other.RaceProps.Humanlike) + return (ThoughtState) false; + + if (!RelationsUtility.PawnsKnowEachOther(p, other)) + return (ThoughtState) false; + + // Only check if they are spawned + if (!p.Spawned || !other.Spawned) + return (ThoughtState)false; + + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(p)) + return (ThoughtState)false; + + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_zealous_loyalty) && HiveUtility.QueensOnMap() == 1) + { + return (ThoughtState) HiveUtility.IsAdultQueen(other); + } + + return (ThoughtState)false; + } + } +} diff --git a/Source/Genes/Hive/Thoughts/ThoughtWorker_RivalQueen_Social.cs b/Source/Genes/Hive/Thoughts/ThoughtWorker_RivalQueen_Social.cs new file mode 100644 index 0000000..24b1b79 --- /dev/null +++ b/Source/Genes/Hive/Thoughts/ThoughtWorker_RivalQueen_Social.cs @@ -0,0 +1,39 @@ +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_RivalQueen_Social : ThoughtWorker + { + protected override ThoughtState CurrentSocialStateInternal(Pawn p, Pawn other) + { + if (!p.RaceProps.Humanlike) + return (ThoughtState)false; + if (!other.RaceProps.Humanlike) + return (ThoughtState)false; + + if (!RelationsUtility.PawnsKnowEachOther(p, other)) + return (ThoughtState)false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(p)) + return (ThoughtState)false; + + // Only check if they are spawned + if (!p.Spawned || !other.Spawned) + { + return (ThoughtState)false; + } + + if(HiveUtility.IsAdultQueen(p) && HiveUtility.IsAdultQueen(other)) + { + return (ThoughtState)true; + } + return (ThoughtState)false; + } + } +} diff --git a/Source/Genes/Hive/Thoughts/ThoughtWorker_WorkerDespised_Social.cs b/Source/Genes/Hive/Thoughts/ThoughtWorker_WorkerDespised_Social.cs new file mode 100644 index 0000000..8a9ad53 --- /dev/null +++ b/Source/Genes/Hive/Thoughts/ThoughtWorker_WorkerDespised_Social.cs @@ -0,0 +1,39 @@ +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_WorkerDespised_Social : ThoughtWorker + { + protected override ThoughtState CurrentSocialStateInternal(Pawn p, Pawn other) + { + // p is the pawn `thinking`, and other is the pawn being thought about. + // here: p = queen, other = potential worker + + if (!p.RaceProps.Humanlike) + return (ThoughtState) false; + + if (!other.RaceProps.Humanlike) + return (ThoughtState) false; + + if (!RelationsUtility.PawnsKnowEachOther(p, other)) + return (ThoughtState) false; + + // Only check if they are spawned + if (!p.Spawned || !other.Spawned) + return (ThoughtState)false; + + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_queen) && GeneUtility.HasGeneNullCheck(other, GeneDefOf.rjw_genes_worker)) + { + return (ThoughtState)true; + } + + return (ThoughtState)false; + } + } +} diff --git a/Source/Genes/Hive/Thoughts/Thoughtworker_MultipleQueens_Mood.cs b/Source/Genes/Hive/Thoughts/Thoughtworker_MultipleQueens_Mood.cs new file mode 100644 index 0000000..3265a00 --- /dev/null +++ b/Source/Genes/Hive/Thoughts/Thoughtworker_MultipleQueens_Mood.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 Thoughtworker_MultipleQueens_Mood : ThoughtWorker + { + + protected override ThoughtState CurrentStateInternal(Pawn p) + { + // Error Handling and Check for Pawn being on Map + if (p == null || !p.Spawned) + return (ThoughtState) false; + // Queens cannot have loyalty thoughts + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_queen)) + return (ThoughtState)false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(p)) + return (ThoughtState)false; + + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_zealous_loyalty) && HiveUtility.QueensOnMap() >= 2) + { + return (ThoughtState)true; + } + + return (ThoughtState) false; + } + + } +} diff --git a/Source/Genes/Hive/Thoughts/Thoughtworker_QueenAbsent_Mood.cs b/Source/Genes/Hive/Thoughts/Thoughtworker_QueenAbsent_Mood.cs new file mode 100644 index 0000000..502b013 --- /dev/null +++ b/Source/Genes/Hive/Thoughts/Thoughtworker_QueenAbsent_Mood.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 Thoughtworker_QueenAbsent_Mood : ThoughtWorker + { + + protected override ThoughtState CurrentStateInternal(Pawn p) + { + // Error Handling and Check for Pawn being on Map + if (p == null || !p.Spawned) + return (ThoughtState) false; + // Queens cannot have loyalty thoughts + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_queen)) + return (ThoughtState)false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(p)) + return (ThoughtState)false; + + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_zealous_loyalty) && HiveUtility.QueensOnMap() == 0) + { + return (ThoughtState)true; + } + + return (ThoughtState) false; + } + + } +} diff --git a/Source/Genes/Hive/Thoughts/Thoughtworker_QueenPresent_Mood.cs b/Source/Genes/Hive/Thoughts/Thoughtworker_QueenPresent_Mood.cs new file mode 100644 index 0000000..e6003be --- /dev/null +++ b/Source/Genes/Hive/Thoughts/Thoughtworker_QueenPresent_Mood.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 Thoughtworker_QueenPresent_Mood : ThoughtWorker + { + + protected override ThoughtState CurrentStateInternal(Pawn p) + { + // Error Handling and Check for Pawn being on Map + if (p == null || !p.Spawned) + return (ThoughtState) false; + // Queens cannot have loyalty thoughts + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_queen)) + return (ThoughtState)false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(p)) + return (ThoughtState)false; + + if (GeneUtility.HasGeneNullCheck(p, GeneDefOf.rjw_genes_zealous_loyalty) && HiveUtility.QueensOnMap() == 1) + { + return (ThoughtState)true; + } + + return (ThoughtState) false; + } + + } +} diff --git a/Source/Genes/Hive/Thoughts/Thoughtworker_RivalQueen_Mood.cs b/Source/Genes/Hive/Thoughts/Thoughtworker_RivalQueen_Mood.cs new file mode 100644 index 0000000..fbcdb2b --- /dev/null +++ b/Source/Genes/Hive/Thoughts/Thoughtworker_RivalQueen_Mood.cs @@ -0,0 +1,32 @@ +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_RivalQueen_Mood : ThoughtWorker + { + + protected override ThoughtState CurrentStateInternal(Pawn p) + { + if (p == null || !p.Spawned) + return (ThoughtState) false; + // If the pawn is not on Map (e.g. caravan), no mali + if (!HiveUtility.PawnIsOnHomeMap(p)) + return (ThoughtState)false; + + if (HiveUtility.IsAdultQueen(p) && HiveUtility.QueensOnMap() >= 2) + { + return (ThoughtState) true; + } + + return (ThoughtState) false; + } + + } +} diff --git a/Source/Genes/Life_Force/Abilities/CompAbilityEffect_CockEater.cs b/Source/Genes/Life_Force/Abilities/CompAbilityEffect_CockEater.cs index dc0f0fa..977c77b 100644 --- a/Source/Genes/Life_Force/Abilities/CompAbilityEffect_CockEater.cs +++ b/Source/Genes/Life_Force/Abilities/CompAbilityEffect_CockEater.cs @@ -51,9 +51,9 @@ namespace RJW_Genes } // Increase LifeForce for Biter GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(CockBiter), gained_lifeforce); - // Handle Damage for Bitten - CockBittenPawn.health.RemoveHediff(part); + CockBittenPawn.TakeDamage(new DamageInfo(DamageDefOf.Bite, 99999f, 999f, hitPart: Genital_Helper.get_genitalsBPR(CockBittenPawn))); + //CockBittenPawn.health.RemoveHediff(part); CockBittenPawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.rjw_genes_cock_eaten, CockBittenPawn, null); //Only one penis at the time diff --git a/Source/Genes/Patch_AddNotifyOnGeneration.cs b/Source/Genes/Patch_AddNotifyOnGeneration.cs new file mode 100644 index 0000000..3395a81 --- /dev/null +++ b/Source/Genes/Patch_AddNotifyOnGeneration.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using System.Linq; +using Verse; + +namespace RJW_Genes.Genes +{ + [HarmonyPatch] + public static class Patch_AddNotifyOnGeneration + { + [HarmonyPatch(typeof(PawnGenerator), "GenerateGenes")] + [HarmonyPostfix] + public static void PawnGenerator_GenerateGenes_Postfix(Pawn pawn) + { + if (pawn.genes == null) return; + + foreach(var gene in pawn.genes.GenesListForReading) + { + if (gene is RJW_Gene rjwGene) + rjwGene.Notify_OnPawnGeneration(); + } + } + } +} diff --git a/Source/Genes/RJW_Gene.cs b/Source/Genes/RJW_Gene.cs index d03440c..c006d2c 100644 --- a/Source/Genes/RJW_Gene.cs +++ b/Source/Genes/RJW_Gene.cs @@ -12,5 +12,15 @@ namespace RJW_Genes if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) Sexualizer.sexualize_pawn(pawn); } + + /// + /// Executed via PawnGenerator.GenerateGenes at Pawn generation + /// Allows for execution of code that should only happen during PawnGeneration + /// + /// This has an accompanying patch `Patch_AddNotifyOnGeneration.cs`. + /// + public virtual void Notify_OnPawnGeneration() + { + } } } diff --git a/Source/Genes/Special/AgeTransferExtension.cs b/Source/Genes/Special/AgeTransferExtension.cs new file mode 100644 index 0000000..e309381 --- /dev/null +++ b/Source/Genes/Special/AgeTransferExtension.cs @@ -0,0 +1,17 @@ +using Verse; + +namespace RJW_Genes +{ + public class AgeTransferExtension : DefModExtension + { + /// + /// Amount by which the Biological Age Ticks will be changed. + /// + public int ageTickChange; + + /// + /// Minimum Age for youthing to take place - pawns cannot end up underaged. + /// + public int minAgeInYears; + } +} \ No newline at end of file diff --git a/Source/Genes/Special/Patch_AgeDrain.cs b/Source/Genes/Special/Patch_AgeDrain.cs index 4138a78..060c20d 100644 --- a/Source/Genes/Special/Patch_AgeDrain.cs +++ b/Source/Genes/Special/Patch_AgeDrain.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine; +using Verse; namespace RJW_Genes.Genes.Special { @@ -18,9 +20,9 @@ namespace RJW_Genes.Genes.Special * I am not sure how I feel about this, but as some people that I consider "normal" asked me about this I changed it as requested in #26 and #28 */ - const long AGE_TRANSFERED = 120000; // 120k == 2 days + const long AGE_TRANSFERED_FALLBACK = 120000; // 120k == 2 days // 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety - const long MINIMUM_AGE = 18 * 60 * 60000 + 1; + const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1; public static void Postfix(SexProps props) { @@ -28,18 +30,50 @@ namespace RJW_Genes.Genes.Special { return; } - if (GeneUtility.IsAgeDrainer(props.pawn) && props.pawn.ageTracker.AgeBiologicalTicks > MINIMUM_AGE) + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (GeneUtility.IsAgeDrainer(pawn) && !GeneUtility.IsAgeDrainer(partner)) { - var pawnAge = props.pawn.ageTracker.AgeBiologicalTicks; - //ModLog.Error($"Firing Age Drain \nMinimum Age is \t{MINIMUM_AGE} \nPawn Age is \t{pawnAge} \nTransferred \t{AGE_TRANSFERED}\nResulting in \t{pawnAge - AGE_TRANSFERED}"); - - // Make Partner older - props.partner.ageTracker.AgeBiologicalTicks += AGE_TRANSFERED; - // Make Pawn younger if he is older than minimum age - if (pawnAge - AGE_TRANSFERED > MINIMUM_AGE) - props.pawn.ageTracker.AgeBiologicalTicks = Math.Max(MINIMUM_AGE, (pawnAge - AGE_TRANSFERED)); + TransferAge(pawn, partner); } + else if (GeneUtility.IsAgeDrainer(partner) && !GeneUtility.IsAgeDrainer(pawn)) + { + TransferAge(partner,pawn); + } + else if (GeneUtility.IsAgeDrainer(partner) && GeneUtility.IsAgeDrainer(pawn) && RJW_Genes_Settings.rjw_genes_detailed_debug) + { + ModLog.Message($"[Sexual Age Drainer] both {pawn} and {partner} are sexual-age-drainers - nothing happens."); + } + } + /// + /// Transfers age from the giver to the receiver. + /// + /// The pawn that will receive biological-Age-Ticks, and becomes younger if they are not already young. + /// The pawn that will be giving biological-Age-Ticks. This pawn is always aged, even if the other pawn is too young. + private static void TransferAge(Pawn receiver, Pawn giver) + { + AgeTransferExtension transferExt = GeneDefOf.rjw_genes_sex_age_drain.GetModExtension(); + long age_transfered = transferExt?.ageTickChange ?? AGE_TRANSFERED_FALLBACK; + long minimum_age = transferExt?.minAgeInYears * 60 * 60000 + 1 ?? MINIMUM_AGE_FALLBACK; + + var pawnAge = receiver.ageTracker.AgeBiologicalTicks; + + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"[Sexual Age Drainer] {receiver} is aging {giver} by {age_transfered} ({Math.Round(age_transfered / 60000.0, 2)} days)"); + + // Giver ALWAYS ages + giver.ageTracker.AgeBiologicalTicks += age_transfered; + + // Make Receiver younger if they are older than minimum age + if (pawnAge - age_transfered > minimum_age) + receiver.ageTracker.AgeBiologicalTicks = Math.Max(minimum_age, (pawnAge - age_transfered)); + else { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"[Sexual Age Drainer] {receiver} was too young ({receiver.ageTracker.AgeBiologicalYears}), and remains unchanged."); + } } } } diff --git a/Source/Genes/Special/Patch_OrgasmMytosis.cs b/Source/Genes/Special/Patch_OrgasmMytosis.cs new file mode 100644 index 0000000..8c5b6e9 --- /dev/null +++ b/Source/Genes/Special/Patch_OrgasmMytosis.cs @@ -0,0 +1,323 @@ +using HarmonyLib; +using RimWorld; +using RimWorld.QuestGen; +using rjw; +using rjw.Modules.Shared.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + + /// + /// There was a big change with RJW 5.3.6 and I got a new Issue #52 documenting it. + /// Basically, the reroll and orgasm logic was changed. + /// + + [HarmonyPatch(typeof(JobDriver_Sex), "SetupOrgasmTicks")] + public static class Patch_OrgasmMytosis + { + + private const float SEVERITY_INCREASE_PER_ORGASM = 0.075f; + + public static void Postfix(JobDriver_Sex __instance) + { + Pawn orgasmingPawn = __instance.pawn; + if (orgasmingPawn != null && GeneUtility.HasGeneNullCheck(orgasmingPawn, GeneDefOf.rjw_genes_sexual_mytosis) && ! orgasmingPawn.health.hediffSet.HasHediff(HediffDefOf.rjw_genes_mytosis_shock_hediff)) + { + var mytosisHediff = GetOrgasmMytosisHediff(orgasmingPawn); + mytosisHediff.Severity += SEVERITY_INCREASE_PER_ORGASM; + + if (mytosisHediff.Severity >= 1.0) + { + orgasmingPawn.health.RemoveHediff(mytosisHediff); + + var copy = Multiply(orgasmingPawn); + + ApplyMytosisShock(copy); + ApplyMytosisShock(orgasmingPawn); + + orgasmingPawn.Strip(); + + } + else + { + float orgasm_time_reduction = Math.Max(1.0f - mytosisHediff.Severity, 0.1f); + __instance.sex_ticks = (int) (__instance.sex_ticks * orgasm_time_reduction); + } + + } + + } + + private static void ApplyMytosisShock(Pawn copy) + { + var stunA = HediffMaker.MakeHediff(HediffDefOf.rjw_genes_mytosis_shock_hediff, copy); + stunA.Severity = 1; + copy.health.AddHediff(stunA); + } + + /// + /// Helps to get the Orgasm Mytosis Hediff of a Pawn. If it does not exist, one is added. + /// + /// The pawn that had the orgasm, for which a hediff is looked up or created. + /// + public static Hediff GetOrgasmMytosisHediff(Pawn orgasmed) + { + Hediff orgasmicMytosisHediff = orgasmed.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_orgasmic_mytosis_hediff); + if (orgasmicMytosisHediff == null) + { + orgasmicMytosisHediff = HediffMaker.MakeHediff(HediffDefOf.rjw_genes_orgasmic_mytosis_hediff, orgasmed); + orgasmicMytosisHediff.Severity = 0; + orgasmed.health.AddHediff(orgasmicMytosisHediff); + } + return orgasmicMytosisHediff; + } + + public static Pawn Multiply(Pawn toMultiply) + { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message("Hitting Multiply of Mytosis Pawn!"); + + PawnGenerationRequest request = new PawnGenerationRequest( + kind: toMultiply.kindDef, + faction: toMultiply.Faction, + forceGenerateNewPawn: true, + developmentalStages: DevelopmentalStage.Adult, + allowDowned: true, + canGeneratePawnRelations: false, + colonistRelationChanceFactor: 0, + allowFood: false, + allowAddictions: false, + relationWithExtraPawnChanceFactor: 0, + forbidAnyTitle: true, + forceNoBackstory: true, + fixedGender: toMultiply.gender + ); + + /* + * Devnote: Adding these will lead to deadly issues! + fixedBiologicalAge: toMultiply.ageTracker.AgeBiologicalTicks, + fixedChronologicalAge: toMultiply.ageTracker.AgeChronologicalTicks, + */ + + Pawn copy = PawnGenerator.GeneratePawn(request); + + + copy.gender = toMultiply.gender; + copy.ageTracker = toMultiply.ageTracker; + copy.Name = CreateCloneName(toMultiply,2); + + copy.health = CopyRelevantHediffs(copy, toMultiply); + copy.genes = CopyGeneTracker(copy,toMultiply.genes); + + copy.ideo = toMultiply.ideo; + copy.records = new Pawn_RecordsTracker(copy); + copy.outfits = toMultiply.outfits; + + copy.relations = toMultiply.relations; + copy.skills = CopySkillTracker(copy,toMultiply.skills); + + copy.equipment.DestroyAllEquipment(); + copy.apparel.DestroyAll(); + + //TODO: Make a letter on birth! + + + PawnUtility.TrySpawnHatchedOrBornPawn(copy, toMultiply); + // Move the copy in front of the origin, rather than on top + if (toMultiply.Spawned) + if (toMultiply.CurrentBed() != null) + { + copy.Position = copy.Position + new IntVec3(0, 0, 1).RotatedBy(toMultiply.CurrentBed().Rotation); + } + + + // Birthmother doesn't show as relation (See log below) + // copy.relations.AddDirectRelation(PawnRelationDefOf.ParentBirth, toMultiply); + + + copy.style = CopyStyleTracker(copy, toMultiply.style); + copy.story = CopyStoryTracker(copy, toMultiply.story); + + copy.Draw(); + return copy; + } + + private static Name CreateCloneName(Pawn toCopyFrom, int additions=1) + { + if (toCopyFrom.Name is NameTriple) + { + NameTriple casted = (NameTriple)toCopyFrom.Name; + String Postfix = " " + RandomNamePostFix(additions); + Name newName = new NameTriple(first:casted.First + Postfix, nick: casted.Nick + Postfix, last: casted.Last); + if (newName.UsedThisGame) + return CreateCloneName(toCopyFrom, additions); + return newName; + } + return toCopyFrom.Name; + } + + private static Pawn_GeneTracker CopyGeneTracker(Pawn toCopyTo, Pawn_GeneTracker toCopyFrom) + { + var tracker = new Pawn_GeneTracker(toCopyTo); + + // Due to Overwrite logics, we first add Endogenes and then a second pass on xenogenes + + // Pass 1: Endogenes + foreach (Gene gene in toCopyFrom.GenesListForReading) { + GeneDef def = gene.def; + if (!toCopyFrom.Xenogenes.Contains(gene)) + tracker.AddGene(def, false); + } + + // Pass 2: Xenogenes + foreach (Gene gene in toCopyFrom.GenesListForReading) + { + GeneDef def = gene.def; + if (toCopyFrom.Xenogenes.Contains(gene)) + tracker.AddGene(def, true); + } + + tracker.Reset(); + var skin = tracker.GetMelaninGene(); + var hair = tracker.GetHairColorGene(); + + //ModLog.Message($"{toCopyTo} had Skin {skin.defName} and {hair.defName} as colour-genes"); + + + return tracker; + } + + private static Pawn_StoryTracker CopyStoryTracker(Pawn toCopyTo, Pawn_StoryTracker toCopyFrom) + { + var tracker = new Pawn_StoryTracker(toCopyTo); + + tracker.Childhood = toCopyFrom.Childhood; + tracker.Adulthood = toCopyFrom.Adulthood; + + tracker.headType = toCopyFrom.headType; + tracker.bodyType = toCopyFrom.bodyType; + tracker.hairDef = toCopyFrom.hairDef; + tracker.furDef = toCopyFrom.furDef; + + tracker.traits = toCopyFrom.traits; + + tracker.skinColorOverride = toCopyFrom.skinColorOverride; + tracker.HairColor = toCopyFrom.HairColor; + + + return tracker; + } + + private static Pawn_SkillTracker CopySkillTracker(Pawn toCopyTo, Pawn_SkillTracker toCopyFrom) + { + var tracker = new Pawn_SkillTracker(toCopyTo); + + tracker.skills = toCopyFrom.skills; + + return tracker; + } + + private static Pawn_HealthTracker CopyRelevantHediffs(Pawn toCopyTo, Pawn copiedFrom) + { + var toCopyFrom = copiedFrom.health; + var tracker = toCopyTo.health; + // Step 0: Remove everything, Reset + tracker.RemoveAllHediffs(); + tracker.Reset(); + // Step 1: Copy ALL Hediffs + foreach (Hediff hed in toCopyFrom.hediffSet.hediffs) + { + // DevNote: There were a lot of issues around bodyparts: + // Some Hediffs really need to know their bodypart, e.g. an implanted arm can either be left or right. + // Ignoring this will lead to many errors, mostly around nullpointers. + + BodyPartRecord originalBPR = hed.Part; + if (originalBPR != null) { + BodyPartRecord copyBPR = toCopyTo.RaceProps?.body.AllParts.Find(bpr => bpr.def == originalBPR.def); + if (copyBPR != null && !copyBPR.IsMissingForPawn(toCopyTo)) { + Hediff copiedHediff = HediffMaker.MakeHediff(hed.def, toCopyTo, copyBPR); + tracker.AddHediff(copiedHediff); + } + } else + { + Hediff copiedHediff = HediffMaker.MakeHediff(hed.def, toCopyTo); + tracker.AddHediff(copiedHediff); + } + } + // Step 2: Remove all Artifical Parts + List hediffsToRemove = new List(); + foreach (Hediff hed in tracker.hediffSet.hediffs) + { + if (hed is Hediff_AddedPart && ((Hediff_AddedPart)hed).def.countsAsAddedPartOrImplant) + { + hediffsToRemove.Add(hed); + } + } + tracker.hediffSet.hediffs.RemoveAll(x => hediffsToRemove.Contains(x)); + + // Step 3: Tend issues from Removal + foreach (Hediff copiedHediff in tracker.hediffSet.hediffs) + { + if (copiedHediff.Bleeding) + copiedHediff.Tended(1.0f,1.0f); + } + + return tracker; + } + + private static Pawn_StyleTracker CopyStyleTracker(Pawn toCopyTo, Pawn_StyleTracker toCopyFrom) + { + var tracker = new Pawn_StyleTracker(toCopyTo); + + tracker.beardDef = toCopyFrom.beardDef; + tracker.BodyTattoo = toCopyFrom.BodyTattoo; + tracker.FaceTattoo = toCopyFrom.FaceTattoo; + + return tracker; + } + + private static String RandomNamePostFix(int numberOfParts) + { + List additions = new List() + { + "A","B","C","D","E","F","X","Y","Z", + "Two", + "Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega" + }; + + additions.Shuffle(); + return String.Join(" ",additions.Take(numberOfParts)); + } + } + + +} + +/* +* +*Warning: +*Tried to add pawn relation ParentBirth with self, pawn=Henri +UnityEngine.StackTraceUtility:ExtractStackTrace () +Verse.Log:Warning (string) +RimWorld.Pawn_RelationsTracker:AddDirectRelation (RimWorld.PawnRelationDef,Verse.Pawn) +RJW_Genes.Patch_OrgasmMytosis:Multiply (Verse.Pawn) +RJW_Genes.Patch_OrgasmMytosis:Postfix (rjw.JobDriver_Sex,int&) +(wrapper dynamic-method) rjw.JobDriver_Sex:rjw.JobDriver_Sex.Roll_Orgasm_Duration_Reset_Patch1 (rjw.JobDriver_Sex) +(wrapper dynamic-method) rjw.JobDriver_Sex:rjw.JobDriver_Sex.Orgasm_Patch2 (rjw.JobDriver_Sex) +(wrapper dynamic-method) rjw.JobDriver_Sex:rjw.JobDriver_Sex.SexTick_Patch1 (rjw.JobDriver_Sex,Verse.Pawn,Verse.Thing,bool,bool) +rjw.JobDriver_Rape/<>c__DisplayClass1_0:b__6 () +(wrapper dynamic-method) Verse.AI.JobDriver:Verse.AI.JobDriver.DriverTick_Patch0 (Verse.AI.JobDriver) +Verse.AI.Pawn_JobTracker:JobTrackerTick () +Verse.Pawn:Tick () +Verse.TickList:Tick () +(wrapper dynamic-method) Verse.TickManager:Verse.TickManager.DoSingleTick_Patch2 (Verse.TickManager) +Verse.TickManager:TickManagerUpdate () +Verse.Game:UpdatePlay () +Verse.Root_Play:Update () + + */ \ No newline at end of file diff --git a/Source/Genes/Special/Patch_Youth_Fountain.cs b/Source/Genes/Special/Patch_Youth_Fountain.cs index bc07f1b..b64ca83 100644 --- a/Source/Genes/Special/Patch_Youth_Fountain.cs +++ b/Source/Genes/Special/Patch_Youth_Fountain.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Verse; namespace RJW_Genes.Genes.Special { @@ -18,9 +19,9 @@ namespace RJW_Genes.Genes.Special * I am not sure how I feel about this, but as some people that I consider "normal" asked me about this I changed it as requested in #26 and #28 */ - const long AGE_REDUCTION = 60000; // 60k == 1 day + const long AGE_REDUCTION_FALLBACK = 60000; // 60k == 1 day // 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety - const long MINIMUM_AGE = 18 * 60 * 60000 + 1; + const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1; public static void Postfix(SexProps props) { @@ -28,16 +29,36 @@ namespace RJW_Genes.Genes.Special { return; } - if (GeneUtility.IsYouthFountain(props.pawn) && props.pawn.ageTracker.AgeBiologicalTicks >= MINIMUM_AGE) - { - var partnerAge = props.partner.ageTracker.AgeBiologicalTicks; - if(partnerAge - AGE_REDUCTION > MINIMUM_AGE) - props.partner.ageTracker.AgeBiologicalTicks = Math.Max(MINIMUM_AGE, partnerAge - AGE_REDUCTION); + if (GeneUtility.IsYouthFountain(props.pawn)) + { + ChangeAgeForPawn(props.partner, props.pawn); + } + if (GeneUtility.IsYouthFountain(props.partner)) + { + ChangeAgeForPawn(props.pawn,props.partner); } } + private static void ChangeAgeForPawn(Pawn ToYouth, Pawn YouthingPawn) + { + AgeTransferExtension transferExt = GeneDefOf.rjw_genes_youth_fountain.GetModExtension(); + long age_reduction = transferExt?.ageTickChange ?? AGE_REDUCTION_FALLBACK; + long minimum_age = transferExt?.minAgeInYears * 60 * 60000 + 1 ?? MINIMUM_AGE_FALLBACK; + + var partnerAge = ToYouth.ageTracker.AgeBiologicalTicks; + + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"Firing Youth Fountain - {YouthingPawn} is youthing {ToYouth} by {age_reduction} ({Math.Round(age_reduction / 60000.0, 2)} days)"); + + if (partnerAge - age_reduction > minimum_age) { + ToYouth.ageTracker.AgeBiologicalTicks = Math.Max(minimum_age, partnerAge - age_reduction); + } + else if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"[Youth Fountain] {ToYouth} was too young ({ToYouth.ageTracker.AgeBiologicalYears}), and remains unchanged."); + } + } } diff --git a/Source/HediffDefOf.cs b/Source/HediffDefOf.cs index 4d59a41..4e3b052 100644 --- a/Source/HediffDefOf.cs +++ b/Source/HediffDefOf.cs @@ -16,5 +16,8 @@ namespace RJW_Genes public static readonly HediffDef rjw_genes_succubus_drained; public static readonly HediffDef rjw_genes_orgasm_rush_hediff; public static readonly HediffDef rjw_genes_fertilin_craving; + + public static readonly HediffDef rjw_genes_orgasmic_mytosis_hediff; + public static readonly HediffDef rjw_genes_mytosis_shock_hediff; } } diff --git a/Source/RJW_Genes.cs b/Source/RJW_Genes.cs index c17c779..db4ffbf 100644 --- a/Source/RJW_Genes.cs +++ b/Source/RJW_Genes.cs @@ -1,10 +1,26 @@ -using Verse; +using System.Collections.Generic; +using System.Linq; +using Verse; -namespace BTE_MMLA +namespace RJW_Genes { [StaticConstructorOnStartup] public static class RJW_Genes { - static RJW_Genes() => Log.Message("RJW-Genes loaded"); + static RJW_Genes() + { + ModLog.Message("RJW-Genes loaded"); + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + { + ModLog.Message($"{HiveUtility.getQueenXenotypes().EnumerableCount()} Queen-Xenotypes ({string.Join(",", HiveUtility.getQueenXenotypes().Select(t => t.defName))})"); + ModLog.Message($"{HiveUtility.getDroneXenotypes().EnumerableCount()} Drone-Xenotypes ({string.Join(",", HiveUtility.getDroneXenotypes().Select(t => t.defName))})"); + ModLog.Message($"Found {HiveUtility.GetQueenWorkerMappings().Count} Queen-Worker Mappings ({string.Join(",", HiveUtility.GetQueenWorkerMappings().Keys.Select(t => t.defName))} + Default) "); + + + IEnumerable offspringChanceDefs = DefDatabase.AllDefs; + IEnumerable faultOffspringDefs = offspringChanceDefs.Where(t => t.queenChance + t.workerChance + t.workerChance > 1.02 || t.queenChance + t.workerChance + t.workerChance < 0.98 ); + ModLog.Message($"Found {offspringChanceDefs.Count()} OffspringChanceDefs, of which {faultOffspringDefs.Count()} had faulty chances ({string.Join(",", faultOffspringDefs.Select(t => t.defName))})"); + } + } } } diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index 29d14d9..0ece225 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -30,7 +30,6 @@ - @@ -44,8 +43,14 @@ - - + + + + + + + + @@ -87,6 +92,23 @@ + + + + + + + + + + + + + + + + + @@ -116,7 +138,10 @@ + + + @@ -173,8 +198,7 @@ False - ..\..\RJW-Sexperience\1.4\Assemblies\RJWSexperience.dll - False + ..\..\RJW-Sexperience-1.1.4.0\1.4\Assemblies\RJWSexperience.dll @@ -192,5 +216,6 @@ False + \ No newline at end of file diff --git a/Source/Settings/RJW_Genes_Settings.cs b/Source/Settings/RJW_Genes_Settings.cs index 71cf028..f6e2f83 100644 --- a/Source/Settings/RJW_Genes_Settings.cs +++ b/Source/Settings/RJW_Genes_Settings.cs @@ -17,7 +17,7 @@ namespace RJW_Genes listing_Standard.ColumnWidth = rect.width / 2.05f; listing_Standard.Begin(rect); listing_Standard.Gap(24f); - listing_Standard.Label("Fertlin-Gain from Animals" + ": " + + listing_Standard.Label("Fertilin-Gain from Animals" + ": " + Math.Round((double)(RJW_Genes_Settings.rjw_genes_fertilin_from_animals_factor * 100f), 0).ToString() + "%", -1f, "of fertilin gained (compared to human-baseline)."); RJW_Genes_Settings.rjw_genes_fertilin_from_animals_factor = listing_Standard.Slider(RJW_Genes_Settings.rjw_genes_fertilin_from_animals_factor, 0f, 3f); diff --git a/TODOS.md b/TODOS.md index 7e223a1..33ece5e 100644 --- a/TODOS.md +++ b/TODOS.md @@ -8,6 +8,8 @@ Any help is very appreciated, even if it is just pointing me to existing similar **Incubi** - Add a forced striptease Ability +**Age Transfer Genes** - Add (configurable) option to satisfy Bodymodders and their AgeReversalDemand + ## Planned Genes **Adjustable Cock-Size** like e.g. artificial genitalia have @@ -18,11 +20,9 @@ Any help is very appreciated, even if it is just pointing me to existing similar **Cum-Drugs** eating cum has an effect similar to Go-Juice (including (separate?) addiction) -**Self-Fertilizing Eggs** Pawns fertilize eggs that are put inside them (with themselves as a parent) - **Death-Rest** until the pawn is cumflated. -**Alpha / Beta Genes** that you can only have one alpha, and the alpha makes mostly beta children (1:10). This might fit with the xenotypes below. As this is an RJW mod, this should also somewhat affect sex (e.g. betas cannot impregnate betas). +**STD Immunity** & maybe a potential to be carrier, but not suffer effects. ## Planned Xenotypes @@ -34,20 +34,10 @@ Any help is very appreciated, even if it is just pointing me to existing similar - [] Maybe: Boost pregnancy times of Animals - [] Maybe: Make it Animal-Fertilin-Dependend - [] Either: Can only eat meat or cannot eat meat +- [] Gene to prefer hookups of animals that are in a menstrual cycle Can't help but think about Rexxar Porn now I am a bad person. -**Hive Mother:** - -- [] Spawn the small scarabs -- [] Fertilise Eggs inside her -- [] Produce cocoons -- [] Maybe: Insert "dropped" Insect eggs -- [] Very fragile, no use except breeding -- [] Maybe: can only eat insect jelly -- [] Should look like a nice green-yellow alien as we all know fuckable insects would look like. -- [] There can only be one Hive Mother, some penalties if there are others. This could be implement with an "Alpha Gene" that gives heavy penalties when other Alpha exists. - ## 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: @@ -60,4 +50,16 @@ There were some suggestions on the Discord I saved them somewhere else. I am far - Streamline Filenames / Names to either be LifeForce or Fertilin (e.g. `Hediffs_Fertilin.xml` but `Pawnkind_LifeForce.xml`). I think most things are called LifeForce. - Similar cleanup for the patches, and make a note what to find where in the patches -- Change Project structure to the 1.3, 1.4 Structure of other mods \ No newline at end of file +- Change Project structure to the 1.3, 1.4 Structure of other mods + +## Split: + +I plan to split this mod. +Namely, I want to make a + +1. base-mod (with genitalia and size genes, anything alternating all base stats) +2. bonus-mod, with Fertilin and other complex genes +3. xenotype-mod (only xenotypes + scenarios) +4. animal genes inheritance (Yes, bit of a meme that it was separate mod earlier) + +I first want to make a bit more content, and then I hope there will be a "breaking change" in RJW so I can also do a breaking change on top of that. \ No newline at end of file