diff --git a/Common/Assemblies/Rjw-Genes.dll b/Common/Assemblies/Rjw-Genes.dll index e5045f9..5e1c60b 100644 Binary files a/Common/Assemblies/Rjw-Genes.dll and b/Common/Assemblies/Rjw-Genes.dll differ diff --git a/Common/Defs/RaceGeneDefs/RaceGeneDefs_Base.xml b/Common/Defs/RaceGeneDefs/RaceGeneDefs_Base.xml new file mode 100644 index 0000000..2e03f2b --- /dev/null +++ b/Common/Defs/RaceGeneDefs/RaceGeneDefs_Base.xml @@ -0,0 +1,30 @@ + + + + Insect_base + +
  • + AG_InsectBlood + 0.5 +
  • +
  • + rjw_genes_ovipositor_genitalia + 0.5 +
  • +
    +
    + + + Slime_base + +
  • + AG_SlimeBlood + 0.5 +
  • +
  • + rjw_genes_slime_genitalia + 0.5 +
  • +
    +
    +
    \ No newline at end of file diff --git a/Common/Defs/RaceGeneDefs/RaceGeneDefs_Vanilla_Racegroups.xml b/Common/Defs/RaceGeneDefs/RaceGeneDefs_Vanilla_Racegroups.xml new file mode 100644 index 0000000..8453665 --- /dev/null +++ b/Common/Defs/RaceGeneDefs/RaceGeneDefs_Vanilla_Racegroups.xml @@ -0,0 +1,116 @@ + + + + Canine + Canine_Group + +
  • + Ears_Floppy + 0.9 +
  • +
    +
    + + + + Insect + Insect_Group + +
  • + Beauty_Ugly + 0.5 +
  • +
    +
    + + + Feline + Feline_Group + +
  • + Ears_Cat + 0.9 +
  • +
  • + Sleepy + 0.25 +
  • +
  • + DarkVision + 0.25 +
  • +
    +
    + + + Dragon + Dragon_Group + +
  • + Unstoppable + 0.25 +
  • +
  • + Headbone_CenterHorn + 0.9 +
  • +
    +
    + + + Rodent + Rodent_Group + +
  • + Fertile + 0.25 +
  • +
    +
    + + + Racoon + Raccon_Group + +
  • + StrongStomach + 0.5 +
  • +
    +
    + + +
    \ No newline at end of file diff --git a/Common/Defs/RaceGeneDefs/RaceGeneDefs_template.xml b/Common/Defs/RaceGeneDefs/RaceGeneDefs_template.xml new file mode 100644 index 0000000..20be765 --- /dev/null +++ b/Common/Defs/RaceGeneDefs/RaceGeneDefs_template.xml @@ -0,0 +1,55 @@ + + + + + + \ No newline at end of file diff --git a/Source/Animal_Inheritance/First.cs b/Source/Animal_Inheritance/First.cs new file mode 100644 index 0000000..74eeb6c --- /dev/null +++ b/Source/Animal_Inheritance/First.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using rjw; +using Verse; +using RimWorld; + +namespace RJW_BGS +{ + [StaticConstructorOnStartup] + internal static class First + { + static First() + { + RJWcopy.Racegroupdictbuilder(); + //foreach (RaceGroupDef raceGroupDef2 in DefDatabase.AllDefs) + //{ + //Log.Message("defName = " + raceGroupDef2.defName); + // if (raceGroupDef2.raceNames != null) + // { + // foreach (string race in raceGroupDef2.raceNames) + // { + //Log.Message(race); + // } + // } + //} + } + } +} diff --git a/Source/Animal_Inheritance/GeneChance.cs b/Source/Animal_Inheritance/GeneChance.cs new file mode 100644 index 0000000..2c5453f --- /dev/null +++ b/Source/Animal_Inheritance/GeneChance.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RJW_BGS +{ + public class GeneChance + { + public string defName; + public float chance = 1f; + } +} diff --git a/Source/Animal_Inheritance/Harmony_Init.cs b/Source/Animal_Inheritance/Harmony_Init.cs new file mode 100644 index 0000000..1852e9b --- /dev/null +++ b/Source/Animal_Inheritance/Harmony_Init.cs @@ -0,0 +1,21 @@ +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/Animal_Inheritance/InheritanceUtility.cs b/Source/Animal_Inheritance/InheritanceUtility.cs new file mode 100644 index 0000000..8d5e953 --- /dev/null +++ b/Source/Animal_Inheritance/InheritanceUtility.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; + +namespace RJW_BGS +{ + public class InheritanceUtility + { + public static List AnimalInheritedGenes(Pawn father, Pawn mother) + { + //One parent must be an animal and the other must be human, so only one needs to return + List genelist = new List(); + if (father != null && !father.RaceProps.Humanlike) + { + return SelectGenes(father); + } + + if (mother != null && !mother.RaceProps.Humanlike) + { + return SelectGenes(mother); + //PawnKindDef pawnKindDef = mother.kindDef; + //RaceGeneDef raceGeneDef = RJWcopy.GetRaceGenDefInternal(pawnKindDef); + //if (raceGeneDef != null) + //{ + // GeneDef gene = null; + //In case you hit a modded gene not currently active try again. + // for (int i = 0; i < 50 || gene == null; i++) + // { + // if (raceGeneDef.genes.Any()) + // { + // gene = DefDatabase.GetNamed(raceGeneDef.genes.RandomElement()); + // } + // } + // if (gene != null) + // { + // genelist.Add(gene); +// + // } + // + // } + } + return genelist; + } + + public static List SelectGenes(Pawn pawn) + { + List genelist = new List(); + PawnKindDef pawnKindDef = pawn.kindDef; + RaceGeneDef raceGeneDef = RJWcopy.GetRaceGenDefInternal(pawnKindDef); + if (raceGeneDef != null) + { + foreach (GeneChance gene in raceGeneDef.genes) + { + if (gene.chance >= Rand.Range(0.01f,1f)) + { + genelist.Add(DefDatabase.GetNamed(gene.defName)); + } + } + } + return genelist; + } + + public static void AddGenes(Pawn pawn, List genes) + { + foreach (GeneDef gene in genes) + { + pawn.genes.AddGene(gene, false); + } + } + + public static void NewGenes(Pawn mother, Pawn dad, Pawn baby) + { + if (baby.RaceProps.Humanlike) + { + if (baby.genes == null) + { + baby.genes = new Pawn_GeneTracker(baby); + } + + //Remove the hair and skin genes pawns always start with, should get correct ones from human parent anyway. + for (int i = baby.genes.Endogenes.Count - 1; i >= 0; i--) + { + baby.genes.RemoveGene(baby.genes.Endogenes[i]); + } + + List genes = PregnancyUtility.GetInheritedGenes(dad, mother); + List beastgenes = InheritanceUtility.AnimalInheritedGenes(dad, mother); + InheritanceUtility.AddGenes(baby, beastgenes); + InheritanceUtility.AddGenes(baby, genes); + if(baby.genes.GetFirstEndogeneByCategory(EndogeneCategory.Melanin) == null) + { + AddSkinColor(mother, dad, baby); + } + } + } + + public static void AddSkinColor(Pawn mother, Pawn father, Pawn baby) + { + if (mother != null && mother.genes != null) + { + GeneDef gene = mother.genes.GetFirstEndogeneByCategory(EndogeneCategory.Melanin); + if (gene != null) + { + baby.genes.AddGene(gene, false); + } + } + else if (father != null && father.genes != null) + { + GeneDef gene = father.genes.GetFirstEndogeneByCategory(EndogeneCategory.Melanin); + if (gene != null) + { + baby.genes.AddGene(gene, false); + } + } + else + { + Log.Message("Could not find skincolor of " + baby.Name + "'s parents, giving random skincolor."); + baby.genes.AddGene(PawnSkinColors.RandomSkinColorGene(baby), false); + } + } + + } +} diff --git a/Source/Animal_Inheritance/PatchRJWBestialityPregnancyUtility.cs b/Source/Animal_Inheritance/PatchRJWBestialityPregnancyUtility.cs new file mode 100644 index 0000000..5224c4f --- /dev/null +++ b/Source/Animal_Inheritance/PatchRJWBestialityPregnancyUtility.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; +using rjw; + +namespace RJW_BGS +{ + [HarmonyPatch(typeof(Hediff_BasePregnancy), "Initialize")] + public static class PatchRJWBestialityPregnancyUtility + { + [HarmonyPostfix] + public static void AddGenes(Pawn mother, Pawn dad, ref Hediff_BasePregnancy __instance) + { + foreach (Pawn baby in __instance.babies) + { + if (baby.RaceProps.Humanlike) + { + if (baby.genes == null) + { + baby.genes = new Pawn_GeneTracker(baby); + } + + //Remove the hair and skin genes pawns always start with, should get correct ones from human parent anyway. + for (int i = baby.genes.Endogenes.Count - 1; i >= 0; i--) + { + baby.genes.RemoveGene(baby.genes.Endogenes[i]); + } + + List genes = PregnancyUtility.GetInheritedGenes(dad, mother); + List beastgenes = InheritanceUtility.AnimalInheritedGenes(dad, mother); + InheritanceUtility.AddGenes(baby, beastgenes); + InheritanceUtility.AddGenes(baby, genes); + //foreach (GeneDef gene in genes) + //{ + // baby.genes.AddGene(gene, false); + //} + } + } + } + } +} diff --git a/Source/Animal_Inheritance/PatchRJWHediffInsect_Egg.cs b/Source/Animal_Inheritance/PatchRJWHediffInsect_Egg.cs new file mode 100644 index 0000000..d52f62d --- /dev/null +++ b/Source/Animal_Inheritance/PatchRJWHediffInsect_Egg.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using rjw; +using RimWorld; +using Verse; + +namespace RJW_BGS +{ + [HarmonyPatch(typeof(Hediff_InsectEgg), "GiveBirth")] + public static class PatchRJWHediffInsect_Egg + { + [HarmonyTranspiler] + public static IEnumerable Transpiler(IEnumerable instructions) + { + MethodInfo newgenes = AccessTools.Method(typeof(InheritanceUtility), "NewGenes", null, null); + FieldInfo implanter = AccessTools.Field(typeof(Hediff_InsectEgg), "implanter"); + FieldInfo father = AccessTools.Field(typeof(Hediff_InsectEgg), "father"); + + foreach (CodeInstruction instruction in instructions) + { + yield return instruction; + if (instruction.opcode == OpCodes.Call && instruction.operand.ToString() == "Void BabyPostBirth(Verse.Pawn, Verse.Pawn, Verse.Pawn)") + { + yield return new CodeInstruction(OpCodes.Ldloc_0, null); + yield return new CodeInstruction(OpCodes.Ldfld, implanter); + yield return new CodeInstruction(OpCodes.Ldarg_0, null); + yield return new CodeInstruction(OpCodes.Ldfld, father); + yield return new CodeInstruction(OpCodes.Ldloc_1, null); + yield return new CodeInstruction(OpCodes.Call, newgenes); + } + + } + } + } +} diff --git a/Source/Animal_Inheritance/PatchVanillaPregnancyUtility.cs b/Source/Animal_Inheritance/PatchVanillaPregnancyUtility.cs new file mode 100644 index 0000000..0f5cc90 --- /dev/null +++ b/Source/Animal_Inheritance/PatchVanillaPregnancyUtility.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; +using rjw; + +namespace RJW_BGS +{ + [HarmonyPatch(typeof(PregnancyUtility), "GetInheritedGeneSet", new Type[] + { + typeof(Pawn), + typeof(Pawn), + //typeof(bool) + } + )] + public static class PatchVanillaPregnancyUtility + { + [HarmonyPostfix] + public static void AnimalInheritedGenes(Pawn father, Pawn mother, ref GeneSet __result) + { + List genes = InheritanceUtility.AnimalInheritedGenes(father, mother); + if (genes.Any()) + { + foreach (GeneDef gene in genes) + { + __result.AddGene(gene); + } + } + } + } +} diff --git a/Source/Animal_Inheritance/RJW_BGSSettings.cs b/Source/Animal_Inheritance/RJW_BGSSettings.cs new file mode 100644 index 0000000..180567c --- /dev/null +++ b/Source/Animal_Inheritance/RJW_BGSSettings.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using UnityEngine; +namespace RJW_Genes.Animal_Inheritance +{ + public class RJW_BGSSettings : ModSettings + { + public static void DoWindowContents(Rect inRect) + { + //Copied from RJW settings mostly + Rect outRect = new Rect(0f, 30f, inRect.width, inRect.height - 30f); + Rect rect = new Rect(0f, 0f, inRect.width - 16f, inRect.height + 300f); + //Widgets.BeginScrollView(outRect, ref RJWSettings.scrollPosition, rect, true); + Listing_Standard listing_Standard = new Listing_Standard(); + listing_Standard.maxOneColumn = true; + listing_Standard.ColumnWidth = rect.width / 2.05f; + listing_Standard.Begin(rect); + listing_Standard.Gap(24f); + listing_Standard.CheckboxLabeled("enabled", ref enabled, "no function yet", 0f, 1f); + //listing_Standard.CheckboxLabeled("sexfrenzy", ref sexfrenzy, "disable the effects", 0f, 1f); + listing_Standard.End(); + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref RJW_BGSSettings.enabled, "enabled", RJW_BGSSettings.enabled, true); + } + + public static bool enabled; + } +} diff --git a/Source/Animal_Inheritance/RJW_BGSSettingsController.cs b/Source/Animal_Inheritance/RJW_BGSSettingsController.cs new file mode 100644 index 0000000..53a7659 --- /dev/null +++ b/Source/Animal_Inheritance/RJW_BGSSettingsController.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using UnityEngine; + +namespace RJW_Genes.Animal_Inheritance +{ + public class RJW_BGSSettingsController : Mod + { + public RJW_BGSSettingsController(ModContentPack content) : base(content) + { + base.GetSettings(); + } + + public override string SettingsCategory() + { + return "RJW Genes Animal Gene Inheritance"; + } + public override void DoSettingsWindowContents(Rect inRect) + { + RJW_BGSSettings.DoWindowContents(inRect); + } + } +} diff --git a/Source/Animal_Inheritance/RJWcopies.cs b/Source/Animal_Inheritance/RJWcopies.cs new file mode 100644 index 0000000..cabfd63 --- /dev/null +++ b/Source/Animal_Inheritance/RJWcopies.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using rjw; +using Verse; +using RimWorld; + +namespace RJW_BGS +{ + internal class RJWcopy + { + //Code copied from rjw, as their code was internal and I need the dictionary to know which genes to add to the pawn + public static void Racegroupdictbuilder() + { + foreach (PawnKindDef pawnKindDef2 in from pawnKindDef in DefDatabase.AllDefs + where pawnKindDef.race.race != null + select pawnKindDef) + { + RaceGroupDef raceGroupDef = null; + bool temp = TryGetRaceGroupDef(pawnKindDef2, out raceGroupDef); + } + } + + public static bool TryGetRaceGroupDef(PawnKindDef pawnKindDef, out RaceGroupDef raceGroupDef) + { + + if (RaceGroupByPawnKind.TryGetValue(pawnKindDef, out raceGroupDef)) + { + return raceGroupDef != null; + } + raceGroupDef = GetRaceGroupDefInternal(pawnKindDef); + RaceGroupByPawnKind.Add(pawnKindDef, raceGroupDef); + return raceGroupDef != null; + } + + + public static RaceGroupDef GetRaceGroupDefInternal(PawnKindDef kindDef) + { + string raceName = kindDef.race.defName; + string pawnKindName = kindDef.defName; + IEnumerable allDefs = DefDatabase.AllDefs; + List list = allDefs.Where(delegate (RaceGroupDef group) + { + List pawnKindNames = group.pawnKindNames; + return pawnKindNames != null && pawnKindNames.Contains(pawnKindName); + }).ToList(); + List list2 = allDefs.Where(delegate (RaceGroupDef group) + { + List raceNames = group.raceNames; + return raceNames != null && raceNames.Contains(raceName); + }).ToList(); + int num = list.Count() + list2.Count(); + if (num == 0) + { + return null; + } + if (num == 1) + { + return list.Concat(list2).Single(); + } + RaceGroupDef result; + if ((result = list.FirstOrDefault((RaceGroupDef match) => !IsThisMod(match))) == null) + { + if ((result = list2.FirstOrDefault((RaceGroupDef match) => !IsThisMod(match))) == null) + { + result = (list.FirstOrDefault() ?? list2.FirstOrDefault()); + } + } + return result; + } + + //slightly modified copy of code above so it also works for racegenedefs + public static RaceGeneDef GetRaceGenDefInternal(PawnKindDef kindDef) + { + if (kindDef == null) + { + return null; + } + string raceName = kindDef.race.defName; + string pawnKindName = kindDef.defName; + RaceGroupDef raceGroupDef = GetRaceGroupDef(kindDef); + //string raceGroupName = GetRaceGroupDef(kindDef).defName; + IEnumerable allDefs = DefDatabase.AllDefs; + Log.Message(allDefs.Count().ToString()); + List list = allDefs.Where(delegate (RaceGeneDef group) + { + List pawnKindNames = group.pawnKindNames; + return pawnKindNames != null && pawnKindNames.Contains(pawnKindName); + }).ToList(); + List list2 = allDefs.Where(delegate (RaceGeneDef group) + { + List raceNames = group.raceNames; + return raceNames != null && raceNames.Contains(raceName); + }).ToList(); + List list3 = new List(); + if (raceGroupDef != null) + { + Log.Message("found a raceGroupDef"); + Log.Message(raceGroupDef.defName); + foreach (RaceGeneDef rgd in allDefs) + { + Log.Message(rgd.defName); + } + list3 = allDefs.Where(delegate (RaceGeneDef group) + { + String raceGroupDefName = group.raceGroup; + return raceGroupDefName != null && raceGroupDefName == raceGroupDef.defName; + }).ToList(); + } + RaceGeneDef result = null; + //First check if there is a matching pawnkinddef then race, then racegroup + if (list.Any()) + { + result = list.RandomElement(); + } + else if (list2.Any() && result == null) + { + result = list2.RandomElement(); + } + else if (list3.Any() && result == null) + { + result = list3.RandomElement(); + } + else + { + result = null; + } + return result; + + + } + + private static RaceGroupDef GetRaceGroupDef(PawnKindDef kindDef) + { + RaceGroupDef raceGroupDef = null; + bool temp = TryGetRaceGroupDef(kindDef, out raceGroupDef); + return raceGroupDef; + } + + private static bool IsThisMod(Def def) + { + return LoadedModManager.RunningMods.Single((ModContentPack pack) => pack.Name == "RimJobWorld").AllDefs.Contains(def); + } + + private static readonly IDictionary RaceGroupByPawnKind = new Dictionary(); + } + + +} diff --git a/Source/Animal_Inheritance/RaceGeneDef.cs b/Source/Animal_Inheritance/RaceGeneDef.cs new file mode 100644 index 0000000..1d7e42b --- /dev/null +++ b/Source/Animal_Inheritance/RaceGeneDef.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using rjw; + +namespace RJW_BGS +{ + public class RaceGeneDef : Def + { + + public String raceGroup; + public List raceNames; + public List pawnKindNames; + public List genes; + //public List genechances; + public String hybridName; + } +} diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index 67da2c6..b8edc5b 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -7,7 +7,7 @@ {D7D21B4A-1DA7-41D8-B202-C58CA8FA62AA} Library Properties - Rjw-Genes + RJW_Genes Rjw-Genes v4.8 512 @@ -23,18 +23,19 @@ - ..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll + False - ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll False - ..\..\licentia-labs\Assemblies\LicentiaLabs.dll + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\licentia-labs-master\Assemblies\LicentiaLabs.dll False - ..\..\rjw\1.4\Assemblies\RJW.dll + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\RJW\1.4\Assemblies\RJW.dll False @@ -43,18 +44,28 @@ - - ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll - False - + + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + + + + + + + + + + + + diff --git a/Source/Rjw-Genes.csproj.user b/Source/Rjw-Genes.csproj.user new file mode 100644 index 0000000..6e4223f --- /dev/null +++ b/Source/Rjw-Genes.csproj.user @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file