Ejemplo n.º 1
0
        public void RegisterFloraFabricator(List <IDecorationItem> decorationItems)
        {
            if (this.IsRegistered == false)
            {
                // Create new Craft Tree Type
                CreateCustomTree(out CraftTree.Type craftType, decorationItems);
                this.TreeTypeID = craftType;

                // Add the new TechType to the buildables
                CraftDataHandler.AddBuildable(this.TechType);

                // Add the new TechType to the group of Interior Module buildables
                CraftDataHandler.AddToGroup(TechGroup.InteriorModules, TechCategory.InteriorModule, this.TechType, TechType.Fabricator);

                // Register handover text
                LanguageHandler.SetLanguageLine(HandOverText, LanguageHelper.GetFriendlyWord(HandOverText));

                // Unlock at start
                KnownTechHandler.UnlockOnStart(this.TechType);

                // Set the buildable prefab
                PrefabHandler.RegisterPrefab(this);

                // Register sprite
                SpriteHandler.RegisterSprite(this.TechType, AssetsHelper.Assets.LoadAsset <Sprite>("fabricator_icon_green"));

                // Load texture
                this.ColoredTexture = AssetsHelper.Assets.LoadAsset <Texture2D>("submarine_fabricator_green");

                // Associate the recipie to the new TechType
                CraftDataHandler.SetTechData(this.TechType, this.Recipe);

                this.IsRegistered = true;
            }
        }
Ejemplo n.º 2
0
        protected virtual void Patch()
        {
            this.TechType = TechTypeHandler.AddTechType(NameID, FriendlyName, Description, RequiredForUnlock == TechType.None);

            if (!ModulesEnabled) // Even if the options have this be disabled,
            {
                return;          // we still want to run through the AddTechType methods to prevent mismatched TechTypeIDs as these settings are switched
            }
            if (RequiredForUnlock == TechType.None)
            {
                KnownTechHandler.UnlockOnStart(this.TechType);
            }
            else
            {
                KnownTechHandler.SetAnalysisTechEntry(RequiredForUnlock, new TechType[1] {
                    this.TechType
                }, $"{FriendlyName} blueprint discovered!");
            }

            PrefabHandler.RegisterPrefab(this);

            SpriteHandler.RegisterSprite(this.TechType, $"./QMods/MoreCyclopsUpgrades/Assets/{NameID}.png");

            CraftDataHandler.SetTechData(this.TechType, GetRecipe());

            if (AddToCraftTree)
            {
                CraftTreeHandler.AddCraftingNode(Fabricator, this.TechType, FabricatorTabs);
            }

            CraftDataHandler.SetEquipmentType(this.TechType, EquipmentType.CyclopsModule);
            CraftDataHandler.AddToGroup(TechGroup.Cyclops, TechCategory.CyclopsUpgrades, this.TechType);

            SetStaticTechTypeID(this.TechType);
        }
Ejemplo n.º 3
0
        private static void HandleUnlocks(IModifiedRecipe modifiedRecipe)
        {
            if (modifiedRecipe.ForceUnlockAtStart)
            {
                KnownTechHandler.UnlockOnStart(modifiedRecipe.ItemID);
            }

            if (modifiedRecipe.UnlocksCount.HasValue)
            {
                KnownTechHandler.SetAnalysisTechEntry(modifiedRecipe.ItemID, modifiedRecipe.Unlocks);
            }
        }
        private void Patch()
        {
            if (IsPatched)
            {
                return; // Already patched. Skip all this.
            }
            if (Prerequisite != null && !Prerequisite.IsPatched)
            {
                Prerequisite.Patch(); // Go and patch the prerequisite craftable first
            }
            PrePatch();               // Run any prepatch overrides

            if (PatchTechTypeOnly)    // Register just the TechType to preserve the ID.
            {
                this.TechType = TechTypeHandler.AddTechType(NameID, FriendlyName, Description, false);
            }
            else // Full patching
            {
                this.TechType = TechTypeHandler.AddTechType(
                    internalName: NameID,
                    displayName: FriendlyName,
                    tooltip: Description,
                    sprite: ImageUtils.LoadSpriteFromFile($"./QMods/UpgradedVehicles/Assets/{NameID}.png"),
                    unlockAtStart: false);

                CraftTreeHandler.AddCraftingNode(FabricatorType, this.TechType, FabricatorTab);
                CraftDataHandler.SetTechData(this.TechType, GetRecipe());

                PrefabHandler.RegisterPrefab(this);

                if (Config.ForceUnlockAtStart)
                {
                    KnownTechHandler.UnlockOnStart(this.TechType);
                }
                else
                {
                    KnownTechHandler.SetAnalysisTechEntry(RequiredForUnlock, new TechType[1] {
                        this.TechType
                    }, $"{FriendlyName} blueprint discovered!");
                }

                CraftDataHandler.AddToGroup(GroupForPDA, CategoryForPDA, this.TechType);
            }

            PostPatch(); // Run any postpatch overrides

            IsPatched = true;
        }
        public static void Patch()
        {
            try
            {
                // Hook up with harmony
                var harmony = HarmonyInstance.Create("com.standpeter.seamothhabitatbuilder");
                harmony.PatchAll(Assembly.GetExecutingAssembly());

                // Create TechType and register its inventory icon
                SeamothBuilderModule = TechTypeHandler.AddTechType("SeamothBuilderModule", "Seamoth habitat builder", "Allows the Seamoth to perform habitat construction tasks.");
                SpriteHandler.RegisterSprite(SeamothBuilderModule, "QMods/SeamothHabitatBuilder/Assets/SeamothBuilderModule.png");

                // Create blueprint
                TechData blueprint = new TechData
                {
                    craftAmount = 1,
                    Ingredients = new List <Ingredient>(2)
                    {
                        new Ingredient(TechType.Builder, 1),
                        new Ingredient(TechType.AdvancedWiringKit, 1)
                    }
                };
                CraftDataHandler.SetTechData(SeamothBuilderModule, blueprint);

                // Make the item craftable
                const string subTree = "Seamoth modules";
                CraftTreeHandler.AddCraftingNode(CraftTree.Type.SeamothUpgrades, SeamothBuilderModule, subTree);
                KnownTechHandler.UnlockOnStart(SeamothBuilderModule);

                // Set how the new item gets used
                CraftDataHandler.AddToGroup(TechGroup.VehicleUpgrades, TechCategory.VehicleUpgrades, SeamothBuilderModule);
                CraftDataHandler.SetQuickSlotType(SeamothBuilderModule, QuickSlotType.Selectable);
                CraftDataHandler.SetEquipmentType(SeamothBuilderModule, EquipmentType.SeamothModule);

                // Register the prefab for the item
                ModPrefab prefab = new SeamothBuilderPrefab("SeamothBuilder", "WorldEntities/Tools/SeamothBuilderModule", SeamothBuilderModule);
                PrefabHandler.RegisterPrefab(prefab);

                Console.WriteLine("[SeamothHabitatBuilder] Succesfully patched!");
            }
            catch (Exception e)
            {
                Console.WriteLine("[SeamothHabitatBuilder] Caught exception! " + e.InnerException.Message);
                Console.WriteLine(e.InnerException.StackTrace);
            }
        }
Ejemplo n.º 6
0
        private void PatchTechDataEntry()
        {
            CraftDataHandler.SetTechData(this.TechType, GetBlueprintRecipe());

            CraftDataHandler.AddToGroup(this.GroupForPDA, this.CategoryForPDA, this.TechType);

            if (this.UnlockedAtStart)
            {
                KnownTechHandler.UnlockOnStart(this.TechType);
            }
            else
            {
                KnownTechHandler.SetAnalysisTechEntry(this.RequiredForUnlock, new TechType[1] {
                    this.TechType
                }, $"{this.FriendlyName} blueprint discovered!");
            }
        }
        public static void AddRecipe(TechType craftedItem, TechData recipe, CraftTree.Type craftTree, string path)
        {
            Assert.AreNotEqual(craftedItem.ToString(), ((int)craftedItem).ToString(), "This API in intended only for use with standard, non-modded TechTypes.");
            // Only modded enums use the int string as their ToString value

            //CraftTreeHandler.customNodes.Add(new CustomCraftNode(craftedItem, craftTree, path));
            CraftDataHandler.SetTechData(craftedItem, recipe);

            string[] steps = path.Split(CraftingNode.Splitter);

            if (steps.Length <= 1)
            {
                CraftTreeHandler.AddCraftingNode(craftTree, craftedItem);
            }
            else
            {
                CraftTreeHandler.AddCraftingNode(craftTree, craftedItem, steps);
            }

            KnownTechHandler.UnlockOnStart(craftedItem);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Loads the fabricator tabs
 /// </summary>
 public static void FabricatorTabs()
 {
     try
     {
         Log.Debug("Loading fabricator tabs... (0/2)");
         ingotsplus = ingotDict["yenzen-ingotsplus"];
         var spritetabcraft2  = ingotsplus.LoadAsset <Sprite>("IPFabTabCraft");
         var spritetabunpack2 = ingotsplus.LoadAsset <Sprite>("IPFabTabUnpack");
         CraftTreeHandler.AddTabNode(CraftTree.Type.Fabricator, "Craft", "Craft MoreIngots", spritetabcraft2, "Resources");
         Log.Debug("Loading fabricator tabs... (1/2)");
         CraftTreeHandler.AddTabNode(CraftTree.Type.Fabricator, "Unpack", "Unpack MoreIngots", spritetabunpack2, "Resources");
         Log.Debug("Loading fabricator tabs... (2/2)");
         Log.Debug("Fabricator tabs loaded");
         KnownTechHandler.UnlockOnStart(TechType.ScrapMetal);
         KnownTechHandler.UnlockOnStart(TechType.PrecursorIonCrystal);
     }
     catch (Exception e)
     {
         Log.e(e);
     }
 }
Ejemplo n.º 9
0
            public TankType(TechType tank, float baseO2capacity, Sprite sprite = null, bool bUnlockAtStart = false, float speedModifier = 1f)
            {
                Logger.Log(Logger.Level.Debug, $"Registering tank TechType.{tank.AsString()}");
                if (sprite != null)
                {
                    this.sprite = sprite;
                }
                else
                {
                    this.sprite = SpriteManager.Get(tank);
                }
                string tankName = Language.main.Get(tank);

                this.BaseO2Capacity = baseO2capacity;
                this.speedModifier  = speedModifier;
                if (Main.config.bManualRefill)
                {
                    //new TankCraftHelper(tank).Patch();
                    this.refillTechType = TechTypeHandler.AddTechType((tank.AsString(false) + "Refill"), tankName + " Refill", "Refilled " + tankName, false);
                    KnownTechHandler.SetAnalysisTechEntry(tank, new TechType[] { this.refillTechType });
                    SpriteHandler.RegisterSprite(this.refillTechType, this.sprite);
                    var techData = new RecipeData()
                    {
                        craftAmount = 0,
                        Ingredients = new List <Ingredient>()
                        {
                            new Ingredient(tank, 1)
                        }
                    };
                    techData.LinkedItems.Add(tank);

                    CraftDataHandler.SetTechData(this.refillTechType, techData);
                    CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, this.refillTechType, new string[] {
                        "Personal",
                        "TankRefill"
                    });
#if SUBNAUTICA_STABLE
                    if (CraftData.GetCraftTime(tank, out float craftTime))
#elif BELOWZERO
                    if (TechData.GetCraftTime(tank, out float craftTime))
#endif
                    {
                        Logger.Log(Logger.Level.Debug, $"Setting crafting time of {craftTime} for TechType.{this.refillTechType.AsString()}");
                        CraftDataHandler.SetCraftingTime(this.refillTechType, craftTime);
                    }
                    else
                    {
                        Logger.Log(Logger.Level.Debug, $"Couldn't find crafting time for TechType.{tank}");
                    }

                    if (!Main.bannedTech.Contains(this.refillTechType))
                    {
                        Main.bannedTech.Add(this.refillTechType);
                    }
                    if (bUnlockAtStart)
                    {
                        KnownTechHandler.UnlockOnStart(this.refillTechType);
                    }
                }
                else
                {
                    this.refillTechType = TechType.None;
                }
            }
Ejemplo n.º 10
0
 protected void unlockOnStart() => KnownTechHandler.UnlockOnStart(TechType);
Ejemplo n.º 11
0
 // Token: 0x06000005 RID: 5 RVA: 0x00002098 File Offset: 0x00000298
 public static void Patch()
 {
     Logger.Log("Started Patching BonesharkEgg");
     QPatch.egg1tt = TechTypeHandler.AddTechType("Boneshark Egg", "Boneshark Egg", "Required to hatch: Spotted Dockleaf.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg1tt);
     LanguageHandler.SetTechTypeTooltip(TechType.BonesharkEgg, "Required to hatch: Spotted Dockleaf");
     KnownTechHandler.UnlockOnStart(QPatch.egg1tt);
     Atlas.Sprite sprite = SpriteManager.Get(TechType.BonesharkEgg);
     SpriteHandler.RegisterSprite(QPatch.egg1tt, sprite);
     Logger.Log("Started Patching CrabsnakeEgg");
     QPatch.egg2tt = TechTypeHandler.AddTechType("Crabsnake Egg", "Crabsnake Egg", "Required to hatch: Jellyshroom.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg2tt);
     LanguageHandler.SetTechTypeTooltip(TechType.CrabsnakeEgg, "Required to hatch: Jellyshroom.");
     KnownTechHandler.UnlockOnStart(QPatch.egg2tt);
     Atlas.Sprite sprite2 = SpriteManager.Get(TechType.CrabsnakeEgg);
     SpriteHandler.RegisterSprite(QPatch.egg2tt, sprite2);
     Logger.Log("Started Patching CrabsquidEgg");
     QPatch.egg3tt = TechTypeHandler.AddTechType("Crabsquid Egg", "Crabsquid Egg", "Required to hatch: Bloodvine.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg3tt);
     LanguageHandler.SetTechTypeTooltip(TechType.CrabsquidEgg, "Required to hatch: Bloodvine.");
     KnownTechHandler.UnlockOnStart(QPatch.egg3tt);
     Atlas.Sprite sprite3 = SpriteManager.Get(TechType.CrabsquidEgg);
     SpriteHandler.RegisterSprite(QPatch.egg3tt, sprite3);
     Logger.Log("Started Patching CrashfishEgg");
     QPatch.egg4tt = TechTypeHandler.AddTechType("Crashfish Egg", "Crashfish Egg", "Required to hatch: Spiked Horn Grass.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg4tt);
     LanguageHandler.SetTechTypeTooltip(TechType.CrashEgg, "Required to hatch: Spiked Horn Grass.");
     KnownTechHandler.UnlockOnStart(QPatch.egg4tt);
     Atlas.Sprite sprite4 = SpriteManager.Get(TechType.CrashEgg);
     SpriteHandler.RegisterSprite(QPatch.egg4tt, sprite4);
     Logger.Log("Started Patching GasopodEgg");
     QPatch.egg5tt = TechTypeHandler.AddTechType("Gasopod Egg", "Gasopod Egg", "Required to hatch: Creepvine.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg5tt);
     LanguageHandler.SetTechTypeTooltip(TechType.GasopodEgg, "Required to hatch: Creepvine.");
     KnownTechHandler.UnlockOnStart(QPatch.egg5tt);
     Atlas.Sprite sprite5 = SpriteManager.Get(TechType.GasopodEgg);
     SpriteHandler.RegisterSprite(QPatch.egg5tt, sprite5);
     Logger.Log("Started Patching JellyrayEgg");
     QPatch.egg6tt = TechTypeHandler.AddTechType("Jellyray Egg", "Jellyray Egg", "Required to hatch: Jellyshroom.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg6tt);
     LanguageHandler.SetTechTypeTooltip(TechType.JellyrayEgg, "Required to hatch: Jellyshroom.");
     KnownTechHandler.UnlockOnStart(QPatch.egg6tt);
     Atlas.Sprite sprite6 = SpriteManager.Get(TechType.JellyrayEgg);
     SpriteHandler.RegisterSprite(QPatch.egg6tt, sprite6);
     Logger.Log("Started Patching LavaLizardEgg");
     QPatch.egg7tt = TechTypeHandler.AddTechType("Lavalizard Egg", "Lavalizard Egg", "Required to hatch: Deep Shroom.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg7tt);
     LanguageHandler.SetTechTypeTooltip(TechType.LavaLizardEgg, "Required to hatch: Deep Shroom.");
     KnownTechHandler.UnlockOnStart(QPatch.egg7tt);
     Atlas.Sprite sprite7 = SpriteManager.Get(TechType.LavaLizardEgg);
     SpriteHandler.RegisterSprite(QPatch.egg7tt, sprite7);
     Logger.Log("Started Patching MesmerEgg");
     QPatch.egg8tt = TechTypeHandler.AddTechType("Mesmer Egg", "Mesmer Egg", "Required to hatch: Violet Beau.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg8tt);
     LanguageHandler.SetTechTypeTooltip(TechType.MesmerEgg, "Required to hatch: Violet Beau.");
     KnownTechHandler.UnlockOnStart(QPatch.egg8tt);
     Atlas.Sprite sprite8 = SpriteManager.Get(TechType.MesmerEgg);
     SpriteHandler.RegisterSprite(QPatch.egg8tt, sprite8);
     Logger.Log("Started Patching RabbitRayEgg");
     QPatch.egg9tt = TechTypeHandler.AddTechType("Rabbitray Egg", "Rabbitray Egg", "Required to hatch: Veined Nettle.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg9tt);
     LanguageHandler.SetTechTypeTooltip(TechType.RabbitrayEgg, "Required to hatch: Veined Nettle.");
     KnownTechHandler.UnlockOnStart(QPatch.egg9tt);
     Atlas.Sprite sprite9 = SpriteManager.Get(TechType.RabbitrayEgg);
     SpriteHandler.RegisterSprite(QPatch.egg9tt, sprite9);
     Logger.Log("Started Patching SandsharkEgg");
     QPatch.egg10tt = TechTypeHandler.AddTechType("Sandshark Egg", "Sandshark Egg", "Required to hatch: Writhing Weed.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg10tt);
     LanguageHandler.SetTechTypeTooltip(TechType.SandsharkEgg, "Required to hatch: Writhing Weed.");
     KnownTechHandler.UnlockOnStart(QPatch.egg10tt);
     Atlas.Sprite sprite10 = SpriteManager.Get(TechType.SandsharkEgg);
     SpriteHandler.RegisterSprite(QPatch.egg10tt, sprite10);
     Logger.Log("Started Patching ShockerEgg");
     QPatch.egg11tt = TechTypeHandler.AddTechType("Shocker Egg", "Shocker Egg", "Required to hatch: Bulb Bush.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg11tt);
     LanguageHandler.SetTechTypeTooltip(TechType.ShockerEgg, "Required to hatch: Bulb Bush.");
     KnownTechHandler.UnlockOnStart(QPatch.egg11tt);
     Atlas.Sprite sprite11 = SpriteManager.Get(TechType.ShockerEgg);
     SpriteHandler.RegisterSprite(QPatch.egg11tt, sprite11);
     Logger.Log("Started Patching SpadefishEgg");
     QPatch.egg12tt = TechTypeHandler.AddTechType("Spadefish Egg", "Spadefish Egg", "Required to hatch: Blue Palm.");
     LanguageHandler.SetTechTypeTooltip(TechType.SpadefishEgg, "Required to hatch: Blue Palm.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg12tt);
     KnownTechHandler.UnlockOnStart(QPatch.egg12tt);
     Atlas.Sprite sprite12 = SpriteManager.Get(TechType.SpadefishEgg);
     SpriteHandler.RegisterSprite(QPatch.egg12tt, sprite12);
     Logger.Log("Started Patching StalkerEgg");
     QPatch.egg13tt = TechTypeHandler.AddTechType("Stalker Egg", "Stalker Egg", "Required to hatch: Creepvine.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg13tt);
     LanguageHandler.SetTechTypeTooltip(TechType.StalkerEgg, "Required to hatch: Creepvine.");
     KnownTechHandler.UnlockOnStart(QPatch.egg13tt);
     Atlas.Sprite sprite13 = SpriteManager.Get(TechType.StalkerEgg);
     SpriteHandler.RegisterSprite(QPatch.egg13tt, sprite13);
     Logger.Log("Started Patching CutefishEgg");
     QPatch.egg14tt = TechTypeHandler.AddTechType("Cutefish Egg", "Cutefish Egg", "Required to hatch: AcidMushroom.");
     LanguageHandler.SetTechTypeTooltip(TechType.CutefishEgg, "Required to hatch: AcidMushroom.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg14tt);
     KnownTechHandler.UnlockOnStart(QPatch.egg14tt);
     Atlas.Sprite sprite14 = SpriteManager.Get(TechType.CutefishEgg);
     SpriteHandler.RegisterSprite(QPatch.egg14tt, sprite14);
     Logger.Log("Started Patching ReefbackEgg");
     QPatch.egg15tt = TechTypeHandler.AddTechType("Reefback Egg", "Reefback Egg", "Required to hatch: AcidMushroom.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg15tt);
     LanguageHandler.SetTechTypeTooltip(TechType.ReefbackEgg, "Required to hatch: AcidMushroom.");
     KnownTechHandler.UnlockOnStart(QPatch.egg15tt);
     Atlas.Sprite sprite15 = SpriteManager.Get(TechType.ReefbackEgg);
     SpriteHandler.RegisterSprite(QPatch.egg15tt, sprite15);
     Logger.Log("Started Patching JumperEgg");
     QPatch.egg16tt = TechTypeHandler.AddTechType("Jumper Egg", "Jumper Egg", "Required to hatch: AcidMushroom.");
     LanguageHandler.SetTechTypeTooltip(TechType.JumperEgg, "Required to hatch: AcidMushroom.");
     LanguageHandler.SetTechTypeTooltip(egg16tt, "Required to hatch: AcidMushroom.");
     CraftDataHandler.AddToGroup(TechGroup.Miscellaneous, TechCategory.Misc, QPatch.egg16tt);
     KnownTechHandler.UnlockOnStart(QPatch.egg16tt);
     Atlas.Sprite sprite16 = SpriteManager.Get(TechType.JumperEgg);
     SpriteHandler.RegisterSprite(QPatch.egg16tt, sprite16);
 }
Ejemplo n.º 12
0
        public void Patch()
        {
            foreach (string s in UnlockAtStart)
            {
                TechType tt = TechTypeUtils.GetModTechType(s);
                if (tt != TechType.None)
                {
                    if (UnlockStartTypes.Contains(tt))
                    {
                        Log.LogError($"Duplicate entry {s} in UnlockAtStart list");
                        // Unlike with the other collections, this is actually an error. A blueprint can't be unlocked multiple times at the start of the game.
                    }
                    else
                    {
                        UnlockStartTypes.Add(tt);
                        KnownTechHandler.UnlockOnStart(tt);
                    }
                }
                else
                {
                    Log.LogError($"Could not parse string '{s}' in UnlockAtStart list as TechType");
                }
            }

            foreach (KeyValuePair <string, string> kvp in SingleUnlocks)
            {
                TechType key = TechTypeUtils.GetModTechType(kvp.Key);
                if (key == TechType.None)
                {
                    Log.LogError($"Could not parse key '{kvp.Key}' in SingleUnlocks collection as TechType");
                    continue;
                }

                TechType value = TechTypeUtils.GetModTechType(kvp.Value);
                if (value == TechType.None)
                {
                    Log.LogError($"Could not parse value '{kvp.Value}' in SingleUnlocks collection as TechType");
                    continue;
                }

                if (SingleUnlockTypes.Contains(key))
                {
                    // A duplicate key in this collection isn't necessarily an error; It may be that a single blueprint has been configured with multiple ways to unlock it.
                    // It's worth logging as a warning, however.
                    Log.LogWarning($"Duplicate key '{kvp.Key}' found in SingleUnlocks collection; Verify that this is intended behaviour.");
                }
                else
                {
                    SingleUnlockTypes.Add(key);
                }

                KnownTechHandler.SetAnalysisTechEntry(value, new HashSet <TechType>()
                {
                    key
                });
            }

            foreach (KeyValuePair <string, List <string> > compound in CompoundTechs)
            {
                TechType tt = TechTypeUtils.GetModTechType(compound.Key);
                if (tt == TechType.None)
                {
                    Log.LogError($"Could not parse string '{compound.Key}' for key as TechType in CompoundTechs");
                    continue;
                }
                if (CompoundTechTypes.Contains(tt))
                {
                    Log.LogWarning($"Multiple entries found in CompoundTechs for TechType {tt.AsString()}; Verify that this is intended behaviour.");
                }
                else
                {
                    CompoundTechTypes.Add(tt);
                }

                HashSet <TechType> compoundTechs = new HashSet <TechType>();
                foreach (string s in compound.Value)
                {
                    TechType t = TechTypeUtils.GetModTechType(s);
                    if (t == TechType.None)
                    {
                        Log.LogError($"Could not parse string '{s}' as TechType in CompoundTechs collection, key {tt.AsString()}");
                    }
                    else if (compoundTechs.Contains(t))
                    {
                        Log.LogError($"Duplicate entry '{s}' in CompoundTechs, key {tt.AsString()}");
                    }
                    else
                    {
                        compoundTechs.Add(t);
                    }
                }

                if (compoundTechs.Count < 2)
                {
                    Log.LogWarning($"Not enough valid TechTypes found in list for CompoundTechs entry {tt.AsString()}; Verify the spelling of all entries within its list.");
                }
                else
                {
                    Reflection.AddCompoundTech(tt, compoundTechs.ToList <TechType>());
                }
            }
        }