コード例 #1
0
        public override void DefsLoaded()
        {
            hasAlienRace = GenTypes.GetTypeInAnyAssembly("AlienRace.RaceSettings", "AlienRace") != null;

            FB_Factions.RemoveAll(x => true);
            FB_Factions.Add(FactionDef.Named("FactionBlender_Pirate"));
            FB_Factions.Add(FactionDef.Named("FactionBlender_Civil"));

            ProcessSettings();

            DefInjector.InjectMiscToFactions(FB_Factions);

            Logger.Message("Injecting pawn groups to our factions");
            FillFilterLists();
            DefInjector.InjectPawnKindDefsToFactions(FB_Factions);

            if (hasAlienRace)
            {
                Logger.Message("Injecting pawn groups to our race settings");
                DefInjector.InjectPawnKindEntriesToRaceSettings();
            }
            else
            {
                Logger.Message("AlienRace not loaded; no race settings for us!");
            }
        }
コード例 #2
0
        public override void SettingsChanged()
        {
            lastSettingChanged = "";

            Logger.Message("Re-injecting pawn groups to our factions");
            DefInjector.InjectPawnKindDefsToFactions(FB_Factions);

            if (hasAlienRace)
            {
                Logger.Message("Re-injecting pawn groups to our race settings");
                DefInjector.InjectPawnKindEntriesToRaceSettings();
            }
        }
コード例 #3
0
        public override void DefsLoaded()
        {
            ProcessSettings();

            // Set the debug flag
            IsDebug = ((SettingHandle <bool>)config["MoreDebug"]).Value;

            // Curate the surgery worker class list before building allSurgeryDefs
            Dictionary <string, Type[]> searchConfigMapper = new Dictionary <string, Type[]> {
                { "Adminster", new[] { typeof(Recipe_AdministerIngestible), typeof(Recipe_AdministerUsableItem) } },
                { "InstallNaturalBodyPart", new[] { typeof(Recipe_InstallNaturalBodyPart) } },
                { "InstallArtificialBodyPart", new[] { typeof(Recipe_InstallArtificialBodyPart) } },
                { "InstallImplant", new[] { typeof(Recipe_InstallImplant), typeof(Recipe_ChangeImplantLevel) } },
                { "VanillaRemoval", new[] { typeof(Recipe_RemoveHediff), AccessTools.TypeByName("RimWorld.Recipe_RemoveBodyPart"), typeof(Recipe_RemoveImplant) } },
            };

            foreach (string cName in searchConfigMapper.Keys)
            {
                if (((SettingHandle <bool>)config["Search" + cName + "Recipes"]).Value)
                {
                    surgeryWorkerClassesFilter.AddRange(searchConfigMapper[cName]);
                }
            }

            // Add additional search types for modded surgery classes
            if (((SettingHandle <bool>)config["SearchModdedSurgeryClasses"]).Value)
            {
                List <string> moddedWorkerClassNames = new List <string> {
                    // (EPOE doesn't have any custom worker classes)

                    // EPOE Forked
                    "EPIA.Recipe_RemoveImplant",
                    "EPIA.Recipe_RemoveScarHediff",
                    "EPIA.Recipe_RemoveBrainScarHediff",

                    // Rah's Bionics and Surgery Expansion
                    "ScarRemoving.Recipe_RemoveHediff_noBrain",

                    // Medical Surgery Expansion
                    "OrenoMSE.Recipe_InstallBodyPartModule",
                    "OrenoMSE.Recipe_InstallImplantSystem",
                    "OrenoMSE.Recipe_RemoveImplantSystem",

                    // Medical Surgery Expansion 2.0
                    "MSE2.Recipe_InstallModule",
                    "MSE2.Recipe_RemoveModules",
                    "MSE2.Recipe_InstallNaturalBodyPartWithChildren",
                    "MSE2.Recipe_InstallArtificialBodyPartWithChildren",

                    // Cyber Fauna
                    "SurgeryCF_Simple",
                    "SurgeryCF_Bionic",
                    "SurgeryCF_Archo",
                    "SurgeryCF_Battle",

                    // Chj's Androids
                    "Androids.Recipe_Disassemble",
                    "Androids.Recipe_RepairKit",

                    // Android Tiers
                    "MOARANDROIDS.Recipe_AndroidRewireSurgery",
                    "MOARANDROIDS.Recipe_RemoveSentience",
                    "MOARANDROIDS.Recipe_RerollTraits",
                    "MOARANDROIDS.Recipe_InstallImplantAndroid",
                    "MOARANDROIDS.Recipe_InstallArtificialBodyPartAndroid",
                    "MOARANDROIDS.Recipe_InstallArtificialBrain",
                    "MOARANDROIDS.Recipe_ApplyHydraulicNaniteBank",
                    "MOARANDROIDS.Recipe_ApplyHealFrameworkSystem",
                    "MOARANDROIDS.Recipe_ApplyHealCoolingSystem",
                    "MOARANDROIDS.Recipe_ApplyHealCPUSerum",

                    // Alien vs. Predator
                    "RRYautja.Recipe_Remove_Gauntlet",
                    "RRYautja.Recipe_RemoveHugger",

                    // Questionable Ethics
                    "QEthics.RecipeWorker_CreateBrainScan",
                    "QEthics.RecipeWorker_GenomeSequencing",
                    "QEthics.RecipeWorker_InstallNaturalBodyPart",
                    "QEthics.RecipeWorker_NerveStapling",

                    // Harpies
                    "SyrHarpy.Recipe_InstallPart",

                    // A RimWorld of Magic
                    "TorannMagic.Recipe_RegrowBodyPart",
                    "TorannMagic.Recipe_RegrowUniversalBodyPart",

                    // PolarisBloc
                    "Polarisbloc.Recipe_MakeCartridgeSurgery",
                    "Polarisbloc.Recipe_InstallCombatChip",
                    "Polarisbloc.Recipe_RemoveHediffIsOld",
                    "Polarisbloc.Recipe_RestoreMissingPart",
                    "Polarisbloc.Recipe_RemoveImplant",
                    "Polarisbloc.Recipe_TransgenderSurgery",
                    "Polarisbloc.Recipe_SurgeryChangeBioAge",
                    "Polarisbloc.Recipe_ExtractAbility",

                    // What the Hack
                    "WhatTheHack.Recipes.Recipe_ExtractBrainData",
                    // The rest of them are really only for mechanoids

                    // CyberNet
                    "CyberNet.Recipe_InstallCyberNetBrainImplant",

                    // Cybernetic Organism and Neural Network
                    "CONN.Recipe_InstallArtificialBodyPartAndClearPawnFromCache",

                    // Vanilla Factions Expanded: Insectoids
                    "VFEI.Other.Recipe_AddMutationHediff",

                    // Deathrattle
                    "DeathRattle.Recipe_AdministerComaDrug",

                    // Rim of Madness: Vampires has blood recipes, but who knows which blood is compatible to a vampire?
                    // Just leave them alone.

                    /*
                     * "Vampire.Recipe_ExtractBloodVial",
                     * "Vampire.Recipe_ExtractBloodPack",
                     * "Vampire.Recipe_ExtractBloodWine",
                     * "Vampire.Recipe_TransferBlood",
                     */
                };

                foreach (string workerName in moddedWorkerClassNames)
                {
                    Type worker = Helpers.SafeTypeByName(workerName);

                    if (worker != null)
                    {
                        surgeryWorkerClassesFilter.Add(worker);
                    }
                }
            }

            Stopwatch stopwatch = Stopwatch.StartNew();
            string    beforeMsg = "Injecting {0} surgical recipes into {1}";
            string    afterMsg  = "Injected {0} surgical recipes into {1} (took {2:F4}s; {3:N0} combinations)";

            // Start with a few global lists
            List <ThingDef> allPawnDefs = DefDatabase <ThingDef> .AllDefs.Where(
                thing => Helpers.IsSupertypeOf(typeof(Pawn), thing.thingClass)
                ).ToList();

            List <RecipeDef> allSurgeryDefs = DefDatabase <RecipeDef> .AllDefs.Where(
                recipe => recipe.IsSurgery && surgeryWorkerClassesFilter.Any(t => Helpers.IsSupertypeOf(t, recipe.workerClass))
                ).ToList();

            // Because we use pawn.recipes so often for surgery checks, and not the other side (surgery.recipeUsers),
            // merge the latter into the former.  Our new additions will be sure to add it in both sides to keep
            // pawn.recipes complete.
            stopwatch.Start();
            foreach (ThingDef pawn in allPawnDefs)
            {
                if (pawn.recipes == null)
                {
                    pawn.recipes = new List <RecipeDef> {
                    }
                }
                ;
                pawn.recipes.AddRange(
                    allSurgeryDefs.Where(s => s.recipeUsers != null && s.recipeUsers.Contains(pawn))
                    );
                pawn.recipes.RemoveDuplicates();
            }

            // Pre-caching
            allSurgeryDefs.ForEach(s => Helpers.GetSurgeryBioType(s));
            allPawnDefs.ForEach(p => Helpers.GetPawnBioType(p));
            stopwatch.Stop();

            Logger.Message("Prep work / pre-caching (took {0:F4}s; {1:N0} defs)", stopwatch.ElapsedMilliseconds / 1000f, allSurgeryDefs.Count() + allPawnDefs.Count());
            stopwatch.Reset();

            // Animal/Animal
            if (((SettingHandle <bool>)config["PatchAnimalToAnimal"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "animal", "other animals");
                }

                var surgeryList = allSurgeryDefs.Where(s => Helpers.GetSurgeryBioType(s) == "animal").ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "animal").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "animal", "other animals", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Humanlike/Humanlike
            if (((SettingHandle <bool>)config["PatchHumanlikeToHumanlike"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "humanlike", "other humanlikes");
                }

                var surgeryList = allSurgeryDefs.Where(s => Helpers.GetSurgeryBioType(s) == "humanlike").ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "humanlike").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "humanlike", "other humanlikes", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // */Mech (artificial+mech only)
            if (((SettingHandle <bool>)config["PatchArtificialToMech"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "artificial part", "mechs");
                }

                var surgeryList = allSurgeryDefs.Where(s =>
                                                       Helpers.IsSupertypeOf(typeof(Recipe_InstallArtificialBodyPart), s.workerClass) ||
                                                       Helpers.IsSupertypeOf("OrenoMSE.Recipe_InstallBodyPartModule", s.workerClass) ||
                                                       Helpers.GetSurgeryBioType(s) == "mech"
                                                       ).ToList();
                var pawnList = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "mech").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "artificial part", "mechs", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Animal/Humanlike
            if (((SettingHandle <bool>)config["PatchAnimalToHumanlike"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "animal", "humanlikes");
                }

                var surgeryList = allSurgeryDefs.Where(s => Helpers.GetSurgeryBioType(s) == "animal").ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "humanlike").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "animal", "humanlikes", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Humanlike/Animal
            if (((SettingHandle <bool>)config["PatchHumanlikeToAnimal"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "humanlike", "animals");
                }

                var surgeryList = allSurgeryDefs.Where(s => Helpers.GetSurgeryBioType(s) == "humanlike").ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "animal").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "humanlike", "animals", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Any Fleshlike to any Fleshlike (only if all other similar ones are on)
            if (
                ((SettingHandle <bool>)config["PatchAnimalToAnimal"]).Value &&
                ((SettingHandle <bool>)config["PatchHumanlikeToHumanlike"]).Value &&
                ((SettingHandle <bool>)config["PatchAnimalToHumanlike"]).Value &&
                ((SettingHandle <bool>)config["PatchHumanlikeToAnimal"]).Value
                )
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "fleshlike", "fleshlikes");
                }

                var surgeryList = allSurgeryDefs.Where(s => Regex.IsMatch(Helpers.GetSurgeryBioType(s), "animal|(?:human|flesh)like|mixed")).ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) != "mech").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "fleshlike", "fleshlikes", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Humanlike/Mech
            if (((SettingHandle <bool>)config["PatchHumanlikeToMech"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "humanlike", "mechs");
                }

                var surgeryList = allSurgeryDefs.Where(s => Helpers.GetSurgeryBioType(s) == "humanlike").ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "mech").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "humanlike", "mechs", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Mech-like/Humanlike
            if (((SettingHandle <bool>)config["PatchMechlikeToHumanlike"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message(beforeMsg, "mech-like", "humanlikes");
                }

                var surgeryList = allSurgeryDefs.Where(s => Helpers.GetSurgeryBioType(s) == "mech").ToList();
                var pawnList    = allPawnDefs.Where(p => Helpers.GetPawnBioType(p) == "humanlike").ToList();

                stopwatch.Start();
                DefInjector.InjectSurgeryRecipes(surgeryList, pawnList);
                stopwatch.Stop();

                Logger.Message(afterMsg, "mech-like", "humanlikes", stopwatch.ElapsedMilliseconds / 1000f, surgeryList.Count() * pawnList.Count());
            }
            stopwatch.Reset();

            // Hand/foot clean up
            if (((SettingHandle <bool>)config["CleanupHandFootSurgeries"]).Value)
            {
                if (IsDebug)
                {
                    Logger.Message("Cleaning up hand/foot surgical recipes");
                }

                var surgeryList = allSurgeryDefs.Where(
                    s => s.label.ToLower() is string sl && (sl.Contains("hand") || sl.Contains("foot"))
                    ).ToList();

                stopwatch.Start();
                DefInjector.CleanupHandFootSurgeryRecipes(surgeryList);
                stopwatch.Stop();

                Logger.Message("Cleaning up hand/foot surgical recipes (took {0:F4}s)", stopwatch.ElapsedMilliseconds / 1000f);
            }
            stopwatch.Reset();

            // Clean up
            if (IsDebug)
            {
                Logger.Message("Merging duplicate surgical recipes, hyperlinking, and sorting");
            }

            stopwatch.Start();
            DefInjector.CleanupSurgeryRecipes(allSurgeryDefs, allPawnDefs);
            stopwatch.Stop();

            Logger.Message("Merged duplicate surgical recipes, hyperlinking, and sorting (took {0:F4}s)", stopwatch.ElapsedMilliseconds / 1000f);
            stopwatch.Reset();

            // No need to occupy all of this memory
            Helpers.ClearCaches();
        }