From bb679527af18235beb1e6d424f3afa7cc8decb52 Mon Sep 17 00:00:00 2001 From: Vegapnk Date: Mon, 14 Nov 2022 15:55:52 +0100 Subject: [PATCH] Fixed Anus Replacement, added sample gene to add extra penis or no penis, added License --- .LICENSE.txt.swp | Bin 0 -> 4096 bytes Common/Assemblies/Rjw-Genes.dll | Bin 9216 -> 12288 bytes .../GeneDefs_ExtraGenitaliaEndogenes.xml | 40 ++++++++ ...ml => GeneDefs_GenitaliaTypeEndogenes.xml} | 2 +- Common/Patches/Xenotypes/GenitaliaUpdate.xml | 24 ++--- LICENSE.txt | 9 ++ Source/GeneDefOf.cs | 5 + Source/GeneDefs_GenitaliaTypeEndogenes.xml | 87 ++++++++++++++++ .../Genes/ExtraGenitalia/Gene_ExtraPenis.cs | 61 ++++++++++++ Source/Genes/ExtraGenitalia/Gene_NoPenis.cs | 58 +++++++++++ .../Genes/Genitalia/Gene_CanineGenitalia.cs | 8 +- .../Genes/Genitalia/Gene_DemonicGenitalia.cs | 8 +- .../Genes/Genitalia/Gene_DragonGenitalia.cs | 8 +- .../Genes/Genitalia/Gene_EquineGenitalia.cs | 8 +- .../Genes/Genitalia/Gene_FelineGenitalia.cs | 8 +- Source/Genes/Genitalia/Gene_HumanGenitalia.cs | 8 +- .../Genitalia/Gene_OvipositorGenitalia.cs | 8 +- Source/Genes/Genitalia/Gene_SlimeGenitalia.cs | 8 +- Source/Genes/Genitalia/GenitaliaChanger.cs | 41 +++----- Source/GenitaliaUtility.cs | 93 ++++++++++++++++++ Source/Rjw-Genes.csproj | 11 ++- 21 files changed, 431 insertions(+), 64 deletions(-) create mode 100644 .LICENSE.txt.swp create mode 100644 Common/Defs/Genes/GeneDefs_ExtraGenitaliaEndogenes.xml rename Common/Defs/Genes/{GeneDefs_GenitaliaEndogenes.xml => GeneDefs_GenitaliaTypeEndogenes.xml} (99%) create mode 100644 LICENSE.txt create mode 100644 Source/GeneDefs_GenitaliaTypeEndogenes.xml create mode 100644 Source/Genes/ExtraGenitalia/Gene_ExtraPenis.cs create mode 100644 Source/Genes/ExtraGenitalia/Gene_NoPenis.cs create mode 100644 Source/GenitaliaUtility.cs diff --git a/.LICENSE.txt.swp b/.LICENSE.txt.swp new file mode 100644 index 0000000000000000000000000000000000000000..02c6893a43709219bb5b78bfe08e188103c5621b GIT binary patch literal 4096 zcmYc?2=nw+u+TGN00IF9hIL^@$zdNE8M;^)7<^Lm^D;o<1b~Zcuy=@mfUZTTN2pP- z2Ts-c$@&3B`RPT8xe9KXIjO}88Wk31n)<;dsfoGz#UL`VprBYkIX^cyKTkg>GdDcH zC?`eVH$SCVKgcUw*F7~awOHTB)7jN8*j2Bjq6DW+qY|SbFd70VAy8V9rfb0)YHVa^ u01{VLQdAHY3Pn*e${7uT(GVC7fzc2c4S~@R7!85Z5Eu=C(GVEkApih{D=Y~B literal 0 HcmV?d00001 diff --git a/Common/Assemblies/Rjw-Genes.dll b/Common/Assemblies/Rjw-Genes.dll index b5b908fc23415b9aed799fbcd0e898479d5d723a..6446c8d443580c16520e67dae76cff39ed444014 100644 GIT binary patch literal 12288 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 b-2ctFFhTs=&u6OY_-~GLzxCwT9fAJ=?o@(* diff --git a/Common/Defs/Genes/GeneDefs_ExtraGenitaliaEndogenes.xml b/Common/Defs/Genes/GeneDefs_ExtraGenitaliaEndogenes.xml new file mode 100644 index 0000000..4adc957 --- /dev/null +++ b/Common/Defs/Genes/GeneDefs_ExtraGenitaliaEndogenes.xml @@ -0,0 +1,40 @@ + + + + rjw_genes_genitalia + + + + + + rjw_genes_extra_penis + + Males of this species grow an additional penis . + Genes/Icons/Placeholder + RJW_Genes.Gene_ExtraPenis + 15 + +
  • PenisAmount
  • +
    +
    + + + + rjw_genes_no_penis + + Males of this do not have a penis. + Genes/Icons/Placeholder + RJW_Genes.Gene_NoPenis + 16 + +
  • PenisAmount
  • +
    +
    + +
    \ No newline at end of file diff --git a/Common/Defs/Genes/GeneDefs_GenitaliaEndogenes.xml b/Common/Defs/Genes/GeneDefs_GenitaliaTypeEndogenes.xml similarity index 99% rename from Common/Defs/Genes/GeneDefs_GenitaliaEndogenes.xml rename to Common/Defs/Genes/GeneDefs_GenitaliaTypeEndogenes.xml index c4f40d0..ff90a9f 100644 --- a/Common/Defs/Genes/GeneDefs_GenitaliaEndogenes.xml +++ b/Common/Defs/Genes/GeneDefs_GenitaliaTypeEndogenes.xml @@ -6,8 +6,8 @@
  • GenitalType
  • - diff --git a/Common/Patches/Xenotypes/GenitaliaUpdate.xml b/Common/Patches/Xenotypes/GenitaliaUpdate.xml index aa225d6..3d98b1a 100644 --- a/Common/Patches/Xenotypes/GenitaliaUpdate.xml +++ b/Common/Patches/Xenotypes/GenitaliaUpdate.xml @@ -101,6 +101,18 @@ + + + Always + +
  • + Defs/XenotypeDef[defName="Genie"]/genes + +
  • rjw_genes_human_genitalia
  • + + +
    +
    @@ -128,18 +140,6 @@ - - Always - -
  • - Defs/XenotypeDef[defName="Genie"]/genes - -
  • rjw_genes_slime_genitalia
  • - - -
    -
    - Always diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..6384532 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,9 @@ +Copyright 2022 Vegapnk + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs index 0758245..caa43fa 100644 --- a/Source/GeneDefOf.cs +++ b/Source/GeneDefOf.cs @@ -8,6 +8,7 @@ namespace RJW_Genes { [MayRequireBiotech] public static readonly GeneCategoryDef rjw_genes_genitalia; + // Base Genitalia Types [MayRequireBiotech] public static readonly GeneDef rjw_genes_human_genitalia; [MayRequireBiotech] public static readonly GeneDef rjw_genes_equine_genitalia; [MayRequireBiotech] public static readonly GeneDef rjw_genes_demonic_genitalia; @@ -16,5 +17,9 @@ namespace RJW_Genes [MayRequireBiotech] public static readonly GeneDef rjw_genes_ovipositor_genitalia; [MayRequireBiotech] public static readonly GeneDef rjw_genes_feline_genitalia; [MayRequireBiotech] public static readonly GeneDef rjw_genes_canine_genitalia; + + // Extra Genitalia + [MayRequireBiotech] public static readonly GeneDef rjw_genes_extra_penis; + [MayRequireBiotech] public static readonly GeneDef rjw_genes_no_penis; } } diff --git a/Source/GeneDefs_GenitaliaTypeEndogenes.xml b/Source/GeneDefs_GenitaliaTypeEndogenes.xml new file mode 100644 index 0000000..ff90a9f --- /dev/null +++ b/Source/GeneDefs_GenitaliaTypeEndogenes.xml @@ -0,0 +1,87 @@ + + + + + rjw_genes_genitalia + +
  • GenitalType
  • +
    + 0 + +
    + + + rjw_genes_human_genitalia + + Carriers of this carry genitalia similar to humans. + Genes/Icons/Placeholder + RJW_Genes.Gene_HumanGenitalia + 1 + + + + rjw_genes_equine_genitalia + + Carriers of this gene develop equine genitalia. + Genes/Icons/Placeholder + RJW_Genes.Gene_EquineGenitalia + 2 + + + + rjw_genes_canine_genitalia + + Carriers of this gene develop canine genitalia. + Genes/Icons/Placeholder + RJW_Genes.Gene_CanineGenitalia + 3 + + + + rjw_genes_feline_genitalia + + Carriers of this gene develop feline genitalia. + Genes/Icons/Placeholder + RJW_Genes.Gene_FelineGenitalia + 4 + + + + rjw_genes_demonic_genitalia + + Carriers of this gene have demonic genitalia. + Genes/Icons/Placeholder + RJW_Genes.Gene_DemonicGenitalia + 5 + + + + rjw_genes_dragon_genitalia + + Carriers of this gene develop dragon genitalia. + Genes/Icons/Placeholder + RJW_Genes.Gene_DragonGenitalia + 6 + + + + rjw_genes_slime_genitalia + + Carriers of this gene have slime genitalia. + Genes/Icons/Placeholder + RJW_Genes.Gene_SlimeGenitalia + 7 + + + + rjw_genes_ovipositor_genitalia + + Carriers of this gene have ovipositors similar to insects. + Genes/Icons/Placeholder + RJW_Genes.Gene_OvipositorGenitalia + 8 + + +
    \ No newline at end of file diff --git a/Source/Genes/ExtraGenitalia/Gene_ExtraPenis.cs b/Source/Genes/ExtraGenitalia/Gene_ExtraPenis.cs new file mode 100644 index 0000000..b01e626 --- /dev/null +++ b/Source/Genes/ExtraGenitalia/Gene_ExtraPenis.cs @@ -0,0 +1,61 @@ +using Verse; +using rjw; +using RimWorld; + +namespace RJW_Genes +{ + public class Gene_ExtraPenis : Gene + { + + internal Hediff additional_penis; + + public override void PostMake() + { + base.PostMake(); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + // Penis are only added for male pawns! + if (pawn.gender == Gender.Male && additional_penis == null) + { + createAndAddPenis(); + } + } + + public override void PostAdd() + { + base.PostAdd(); + + // Penis are only added for male pawns! + if (pawn.gender == Gender.Male && additional_penis == null) + { + createAndAddPenis(); + } + } + + public override void PostRemove() + { + base.PostRemove(); + if(additional_penis != null) + pawn.health.RemoveHediff(additional_penis); + } + + internal void createAndAddPenis() + { + var correctGene = GenitaliaUtility.GetGenitaliaTypeGeneForPawn(pawn); + var penisDef = GenitaliaUtility.GetPenisForGene(correctGene); + var partBPR = Genital_Helper.get_genitalsBPR(pawn); + additional_penis = HediffMaker.MakeHediff(penisDef, pawn); + + var CompHediff = additional_penis.TryGetComp(); + if (CompHediff != null) + { + CompHediff.initComp(pawn); + CompHediff.updatesize(); + } + + pawn.health.AddHediff(additional_penis, partBPR); + } + + } +} diff --git a/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs b/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs new file mode 100644 index 0000000..8c88452 --- /dev/null +++ b/Source/Genes/ExtraGenitalia/Gene_NoPenis.cs @@ -0,0 +1,58 @@ +using Verse; +using rjw; +using RimWorld; + +namespace RJW_Genes +{ + public class Gene_NoPenis : Gene + { + + 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 + public override void PostMake() + { + base.PostMake(); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + // Penis are only added for male pawns! + if (pawn.gender == Gender.Male && removed_penis == null) + { + RemoveButStorePenis(); + } + } + + public override void PostAdd() + { + base.PostAdd(); + + // Penis are only added for male pawns! + if (pawn.gender == Gender.Male && removed_penis == null) + { + RemoveButStorePenis(); + } + } + + public override void PostRemove() + { + base.PostRemove(); + if(removed_penis != null) + pawn.health.AddHediff(removed_penis); + } + + internal void RemoveButStorePenis() + { + var partBPR = Genital_Helper.get_genitalsBPR(pawn); + Hediff penisToRemove = Genital_Helper.get_AllPartsHediffList(pawn).FindLast(x => Genital_Helper.is_penis(x)); + + if(penisToRemove != null) + { + removed_penis = penisToRemove; + pawn.health.RemoveHediff(penisToRemove); + } + } + + } +} diff --git a/Source/Genes/Genitalia/Gene_CanineGenitalia.cs b/Source/Genes/Genitalia/Gene_CanineGenitalia.cs index 5a9389d..1d37041 100644 --- a/Source/Genes/Genitalia/Gene_CanineGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_CanineGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.canine_penis,Genital_Helper.canine_vagina,Genital_Helper.generic_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.canine_penis,Genital_Helper.canine_vagina,Genital_Helper.generic_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.canine_penis, Genital_Helper.canine_vagina, Genital_Helper.generic_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.canine_penis, Genital_Helper.canine_vagina, Genital_Helper.generic_anus); } } diff --git a/Source/Genes/Genitalia/Gene_DemonicGenitalia.cs b/Source/Genes/Genitalia/Gene_DemonicGenitalia.cs index 2f1b3a9..5d33f84 100644 --- a/Source/Genes/Genitalia/Gene_DemonicGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_DemonicGenitalia.cs @@ -9,14 +9,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.demon_penis,Genital_Helper.demon_vagina,Genital_Helper.demon_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.demon_penis,Genital_Helper.demon_vagina,Genital_Helper.demon_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.demon_penis, Genital_Helper.demon_vagina, Genital_Helper.demon_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.demon_penis, Genital_Helper.demon_vagina, Genital_Helper.demon_anus); } } diff --git a/Source/Genes/Genitalia/Gene_DragonGenitalia.cs b/Source/Genes/Genitalia/Gene_DragonGenitalia.cs index 05f3aaf..4e44954 100644 --- a/Source/Genes/Genitalia/Gene_DragonGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_DragonGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.dragon_penis,Genital_Helper.dragon_vagina,Genital_Helper.generic_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.dragon_penis,Genital_Helper.dragon_vagina,Genital_Helper.generic_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.dragon_penis, Genital_Helper.dragon_vagina, Genital_Helper.generic_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.dragon_penis, Genital_Helper.dragon_vagina, Genital_Helper.generic_anus); } } diff --git a/Source/Genes/Genitalia/Gene_EquineGenitalia.cs b/Source/Genes/Genitalia/Gene_EquineGenitalia.cs index 03aa029..47eb65a 100644 --- a/Source/Genes/Genitalia/Gene_EquineGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_EquineGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.equine_penis,Genital_Helper.equine_vagina,Genital_Helper.generic_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.equine_penis,Genital_Helper.equine_vagina,Genital_Helper.generic_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.equine_penis, Genital_Helper.equine_vagina, Genital_Helper.generic_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.equine_penis, Genital_Helper.equine_vagina, Genital_Helper.generic_anus); } } diff --git a/Source/Genes/Genitalia/Gene_FelineGenitalia.cs b/Source/Genes/Genitalia/Gene_FelineGenitalia.cs index 910951d..506437c 100644 --- a/Source/Genes/Genitalia/Gene_FelineGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_FelineGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.feline_penis,Genital_Helper.feline_vagina,Genital_Helper.generic_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.feline_penis,Genital_Helper.feline_vagina,Genital_Helper.generic_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.feline_penis, Genital_Helper.feline_vagina, Genital_Helper.generic_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.feline_penis, Genital_Helper.feline_vagina, Genital_Helper.generic_anus); } } diff --git a/Source/Genes/Genitalia/Gene_HumanGenitalia.cs b/Source/Genes/Genitalia/Gene_HumanGenitalia.cs index 389bf0a..cd9ee11 100644 --- a/Source/Genes/Genitalia/Gene_HumanGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_HumanGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.average_penis,Genital_Helper.average_vagina,Genital_Helper.average_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.average_penis,Genital_Helper.average_vagina,Genital_Helper.average_anus); } public override void PostAdd() { base.PostAdd(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.average_penis, Genital_Helper.average_vagina, Genital_Helper.average_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.average_penis, Genital_Helper.average_vagina, Genital_Helper.average_anus); } } diff --git a/Source/Genes/Genitalia/Gene_OvipositorGenitalia.cs b/Source/Genes/Genitalia/Gene_OvipositorGenitalia.cs index 2594737..3cab5d9 100644 --- a/Source/Genes/Genitalia/Gene_OvipositorGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_OvipositorGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.ovipositorM,Genital_Helper.ovipositorF,Genital_Helper.insect_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.ovipositorM,Genital_Helper.ovipositorF,Genital_Helper.insect_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.ovipositorM, Genital_Helper.ovipositorF, Genital_Helper.insect_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.ovipositorM, Genital_Helper.ovipositorF, Genital_Helper.insect_anus); } } diff --git a/Source/Genes/Genitalia/Gene_SlimeGenitalia.cs b/Source/Genes/Genitalia/Gene_SlimeGenitalia.cs index 31b8556..9837271 100644 --- a/Source/Genes/Genitalia/Gene_SlimeGenitalia.cs +++ b/Source/Genes/Genitalia/Gene_SlimeGenitalia.cs @@ -8,14 +8,16 @@ namespace RJW_Genes public override void PostMake() { base.PostMake(); - Sexualizer.sexualize_pawn(pawn); - GenitaliaChanger.changeGenitalia(this.pawn,Genital_Helper.slime_penis,Genital_Helper.slime_vagina,Genital_Helper.slime_anus); + if (GenitaliaUtility.PawnStillNeedsGenitalia(pawn)) + Sexualizer.sexualize_pawn(pawn); + + GenitaliaChanger.ChangeGenitalia(this.pawn,Genital_Helper.slime_penis,Genital_Helper.slime_vagina,Genital_Helper.slime_anus); } public override void PostAdd() { base.PostMake(); - GenitaliaChanger.changeGenitalia(this.pawn, Genital_Helper.slime_penis, Genital_Helper.slime_vagina, Genital_Helper.slime_anus); + GenitaliaChanger.ChangeGenitalia(this.pawn, Genital_Helper.slime_penis, Genital_Helper.slime_vagina, Genital_Helper.slime_anus); } } diff --git a/Source/Genes/Genitalia/GenitaliaChanger.cs b/Source/Genes/Genitalia/GenitaliaChanger.cs index 6a3f02f..047beab 100644 --- a/Source/Genes/Genitalia/GenitaliaChanger.cs +++ b/Source/Genes/Genitalia/GenitaliaChanger.cs @@ -11,16 +11,15 @@ namespace RJW_Genes /// /// This method changes the pawns genitalia to the given types of genitalia. /// All genitals will be changed, e.g. pawns with 2 penises (for whatever reason) or is a futa, all genitals will be changed. - /// Anuses are currently not changed, due to a small bug. /// /// the pawn who's genitals will be changed /// the new type of penis /// the new type of vagina - /// the new type of anus (currently disabled) - public static void changeGenitalia(Pawn pawn, HediffDef penisReplacement, HediffDef vaginaReplacement, HediffDef anusReplacement) + /// the new type of anus + public static void ChangeGenitalia(Pawn pawn, HediffDef penisReplacement, HediffDef vaginaReplacement, HediffDef anusReplacement) { - var oldParts = Genital_Helper.get_AllPartsHediffList(pawn); - var partBPR = Genital_Helper.get_genitalsBPR(pawn); + var oldParts = Genital_Helper.get_AllPartsHediffList(pawn); + BodyPartRecord correctBPR; if (!oldParts.NullOrEmpty()) { @@ -31,16 +30,21 @@ namespace RJW_Genes { if (IsArtificial(existingGenital)) continue; + correctBPR = Genital_Helper.get_genitalsBPR(pawn); replacementGenital = null; CompHediff = null; - if (IsPenis(existingGenital)) - replacementGenital = HediffMaker.MakeHediff(penisReplacement, pawn, partBPR); + if (Genital_Helper.is_penis(existingGenital)) + replacementGenital = HediffMaker.MakeHediff(penisReplacement, pawn, correctBPR); - if (IsVagina(existingGenital)) - replacementGenital = HediffMaker.MakeHediff(vaginaReplacement, pawn, partBPR); + if (Genital_Helper.is_vagina(existingGenital)) + replacementGenital = HediffMaker.MakeHediff(vaginaReplacement, pawn, correctBPR); - //TODO: Adding Anus in this way had an issue by multiplying Anusses. At the moment Anus are not covered. + if (IsAnus(existingGenital)) + { + correctBPR = Genital_Helper.get_anusBPR(pawn); + replacementGenital = HediffMaker.MakeHediff(anusReplacement, pawn, correctBPR); + } if (replacementGenital != null) { @@ -53,7 +57,7 @@ namespace RJW_Genes GenderHelper.ChangeSex(pawn, () => { pawn.health.RemoveHediff(existingGenital); - pawn.health.AddHediff(replacementGenital, partBPR); + pawn.health.AddHediff(replacementGenital, correctBPR); }); } } @@ -66,21 +70,6 @@ namespace RJW_Genes } - private static bool IsPenis(Hediff candidate) - { - return - candidate.def.defName.ToLower().Contains("penis") || - candidate.def.defName.ToLower().Contains("ovipositorm") || - candidate.def.defName.ToLower().Contains("tentacle"); - } - - private static bool IsVagina(Hediff candidate) - { - return - candidate.def.defName.ToLower().Contains("vagina") || - candidate.def.defName.ToLower().Contains("ovipositorf"); - } - private static bool IsAnus(Hediff candidate) { return candidate.def.defName.ToLower().Contains("anus"); } diff --git a/Source/GenitaliaUtility.cs b/Source/GenitaliaUtility.cs new file mode 100644 index 0000000..97785dc --- /dev/null +++ b/Source/GenitaliaUtility.cs @@ -0,0 +1,93 @@ +using RimWorld; +using Verse; +using rjw; + +namespace RJW_Genes +{ + public class GenitaliaUtility + { + + /// + /// Returns the first (non) overwritten gene from the rjw_genes genitalia genes. + /// In case the pawn has none, as default the human one is returned. + /// + /// the pawn whom to find genitaliagenes for + /// The first GeneDef of the pawn related to GenitaliaTypes + public static GeneDef GetGenitaliaTypeGeneForPawn(Pawn pawn) + { + + foreach (var gene in pawn.genes.GenesListForReading) + { + if (gene.def.defName.Contains("rjw_genes") && gene.def.defName.EndsWith("_genitalia")) + if (!gene.Overridden) + return gene.def; + } + + return GeneDefOf.rjw_genes_human_genitalia; + } + + /// + /// Adds a genital created from a given Def to the pawn. + /// Does not alter/touch gender. + /// + /// The pawn whom to add the genital to, + /// The type of genital to be added + public static void AddGenitalToPawn(Pawn pawn,HediffDef genitalToAdd) + { + if (pawn == null || genitalToAdd == null) + return; + + var partBPR = Genital_Helper.get_genitalsBPR(pawn); + var additionalGenital = HediffMaker.MakeHediff(genitalToAdd, pawn); + + var CompHediff = additionalGenital.TryGetComp(); + if (CompHediff != null) + { + CompHediff.initComp(pawn); + CompHediff.updatesize(); + } + + pawn.health.AddHediff(additionalGenital, partBPR); + } + + + public static HediffDef GetPenisForGene(GeneDef gene) + { + switch (gene.defName) + { + case "rjw_genes_human_genitalia": return Genital_Helper.average_penis; + case "rjw_genes_equine_genitalia": return Genital_Helper.equine_penis; + case "rjw_genes_canine_genitalia": return Genital_Helper.canine_penis; + case "rjw_genes_feline_genitalia": return Genital_Helper.feline_penis; + case "rjw_genes_demonic_genitalia": return Genital_Helper.demon_penis; + case "rjw_genes_dragon_genitalia": return Genital_Helper.dragon_penis; + case "rjw_genes_slime_genitalia": return Genital_Helper.slime_penis; + case "rjw_genes_ovipositor_genitalia": return Genital_Helper.ovipositorM; + + default: return Genital_Helper.average_penis; + } + } + + + public static bool PawnStillNeedsGenitalia(Pawn pawn) + { + // There is the issue that the genes fire in a pseudo-random order + // Hence it can happen that the pawn still needs genitalia + // I wanted to make a simple lookup, but I think the genes are applied for all humans encountered so it could be huge + // So the heuristic is to check if the pawn has any of the 3 standard genitalia OR has all genes ticked that says "I don't want genitalia". + if (pawn == null) return false; + + bool pawn_has_any_genitalia = + Genital_Helper.has_genitals(pawn) || Genital_Helper.has_anus(pawn) || Genital_Helper.has_breasts(pawn); + + bool pawn_is_not_supposed_to_have_genitalia = + pawn.genes.GenesListForReading.Any(x => x.def.defName == "rjw_genes_no_penis"); + + if (pawn_is_not_supposed_to_have_genitalia) + return false; + else + return !pawn_has_any_genitalia; + + } + } +} diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index 580fb2f..b2a146b 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -28,6 +28,7 @@ ..\..\rjw\1.4\Assemblies\RJW.dll + False @@ -40,12 +41,16 @@ False - + + + + + @@ -55,8 +60,12 @@ + + + + \ No newline at end of file