Esempio n. 1
0
        public static void Patch()
        {
            bundle = AssetBundle.LoadFromFile(Path.Combine(Environment.CurrentDirectory, "QMods/Precursor Fabricator/fabricatorassets"));

            string assetFolder = Path.Combine(Environment.CurrentDirectory, "QMods/Precursor Fabricator/Assets");

            TechType fabricator = TechTypeHandler.AddTechType("AlienFab", "Precursor Fabricator", "A device capable of fabricating materials of alien origin");

            PrefabHandler.RegisterPrefab(new FabricatorPrefab("AlienFab", "WorldEntities/AlienFabricator", fabricator));

            SpriteHandler.RegisterSprite(fabricator, Path.Combine(assetFolder, "PrecursorFabricator.png"));

            TechType ingot = TechTypeHandler.AddTechType("PrecursorIngot", "Precursor Alloy Ingot", "A super-dense, electronically active bar of alien metal");

            PrefabHandler.RegisterPrefab(new IngotPrefab("PrecursorIngot", "WorldEntities/PrecursorIngot", ingot));

            SpriteHandler.RegisterSprite(ingot, Path.Combine(assetFolder, "PrecursorIngot.png"));

            CraftDataHandler.AddBuildable(fabricator);
            CraftDataHandler.AddToGroup(TechGroup.InteriorPieces, TechCategory.InteriorPiece, fabricator);
            CraftDataHandler.SetCraftingTime(fabricator, 2f);
            TechData data = new TechData(new Ingredient(TechType.PlasteelIngot, 2), new Ingredient(TechType.PrecursorIonCrystal, 2), new Ingredient(TechType.Kyanite, 1));

            CraftDataHandler.SetTechData(fabricator, data);

            TechData ingotData = new TechData(new Ingredient(TechType.PlasteelIngot, 6), new Ingredient(TechType.PrecursorIonCrystal, 1));

            ingotData.craftAmount = 1;
            CraftDataHandler.SetTechData(ingot, ingotData);

            root = CraftTreeHandler.CreateCustomCraftTreeAndType("PrecursorFabricator", out fabType);
            root.AddCraftingNode(ingot);

            if (TechTypeHandler.TryGetModdedTechType("IonFragment", out TechType depletedCube))
            {
                root.AddCraftingNode(depletedCube);
            }
        }
Esempio n. 2
0
 protected internal static void GetAutomobileTechData(string href, Guid modelId)
 {
     try
     {
         
         Dictionary<string, string> itemProperties = new Dictionary<string, string>();
         //foreach (string href in listOfModelsHrefs)
         WebClient WebClient = new WebClient();
         string page = WebClient.DownloadString(href);
         HtmlDocument Doc = new HtmlDocument();
         Doc.LoadHtml(page);
         var rows = Doc.DocumentNode.SelectNodes("//table[@class='text']").Descendants("tr");
         //Parallel.ForEach(rows, elem =>
         foreach (var elem in rows)
         {
             var count = elem.SelectNodes("./td").Count;
             if (count > 1)
             {
                 string propKey = elem.SelectSingleNode("./td").InnerText.Trim();
                 string propValue = elem.SelectSingleNode("./td[2]").InnerText.Trim();
                
                 itemProperties[propKey] = propValue;
              
             }
          
         }
         TechData techInfor = new TechData
         {
             ModelId = modelId,
             TechInfo = SerealizeDictionary(itemProperties)
         };
         techData.Add(techInfor);
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.Message);
     }
 }
Esempio n. 3
0
        internal void AttemptToTakeItem(TechType techType)
        {
            var amount = GetItemCount(techType);

            QuickLogger.Debug($"Container returned {amount} item/s for TechType {techType}");
#if SUBNAUTICA
            var itemSize = CraftData.GetItemSize(techType);
#elif BELOWZERO
            var itemSize = TechData.GetItemSize(techType);
#endif
            if (Inventory.main.HasRoomFor(itemSize.x, itemSize.y))
            {
                if (amount > 0)
                {
                    QuickLogger.Debug($"Attempting to take {_multiplier} item/s");

                    for (int i = 0; i < _multiplier; i++)
                    {
                        var        itemData = ContainerItems.FirstOrDefault(x => x.TechType == techType);
                        Pickupable pickup   = InventoryHelpers.ConvertToPickupable(itemData);

                        if (pickup == null)
                        {
                            QuickLogger.Debug($"There are 0 {techType} in the container while using first or default Current Amount of {techType} is: {GetItemCount(techType)}", true);
                            return;
                        }

                        Inventory.main.Pickup(pickup);
                        ContainerItems.Remove(itemData);
                        OnContainerUpdate?.Invoke(GetTotalCount(), _maxItems);
                    }
                }
                else
                {
                    QuickLogger.Debug($"There are 0 {techType} in the container.", true);
                }
            }
        }
Esempio n. 4
0
        internal void RemoveItemFromContainer(TechType item)
        {
            QuickLogger.Debug("Taking From Container", true);
            if (Items.ContainsKey(item))
            {
#if SUBNAUTICA
                var itemSize = CraftData.GetItemSize(item);
#elif BELOWZERO
                var itemSize = TechData.GetItemSize(item);
#endif
                if (Inventory.main.HasRoomFor(itemSize.x, itemSize.y))
                {
                    if (Items[item] > 0)
                    {
                        Items[item] -= 1;
                        var pickup = CraftData.InstantiateFromPrefab(item).GetComponent <Pickupable>();
                        Inventory.main.Pickup(pickup);
                        OnContainerUpdate?.Invoke();
                        _mono?.Producer?.TryStartingNextClone();
                    }
                }
            }
        }
        private void SearchForModdedTechTypes()
        {
            int i = 0;

            int[] techTypeArray = (int[])Enum.GetValues(typeof(TechType));

            for (int j = 0; j < techTypeArray.Length; j++)
            {
                if (techTypeArray[j] >= 11000)
                {
                    TechType techType = (TechType)techTypeArray[j];
                    string   techName = TechTypeExtensions.AsString(techType);

                    EquipmentType equipmentType = TechData.GetEquipmentType(techType);
                    FoundModdedTechTypes.Add(techName, techType);
                    TypeDefCache.Add(techType, equipmentType);
                    BZLogger.Log($"Modded techtype found! Name: [{techName}], ID: [{(int)techType}], Type: [{equipmentType}]");
                    i++;
                }
            }

            BZLogger.Log($"Found [{i}] modded TechType(s).");
        }
Esempio n. 6
0
        private bool IsAllowedToAdd(Pickupable pickupable, bool verbose)
        {
            TechType techType = pickupable.GetTechType();

            if (compatibleTech.Contains(techType))
            {
                return(true);
            }

            EquipmentType equipmentType = TechData.GetEquipmentType(techType);

            if (equipmentType == EquipmentType.BatteryCharger)
            {
                return(true);
            }

            if (verbose)
            {
                ErrorMessage.AddMessage(Language.main.Get("BatteryChargerIncompatibleItem"));
            }

            return(false);
        }
Esempio n. 7
0
        public static bool TryOverflowIntoBioreactors(SubRoot subRoot, TechType fishType, ref int breedCount)
        {
            var bioReactors = subRoot != null?subRoot.gameObject.GetComponentsInChildren <BaseBioReactor>() ?? new BaseBioReactor[0] : new BaseBioReactor[0];

            if (bioReactors.Length == 0)
            {
                return(breedCount > 0);
            }

            var sizePerFish =
#if SN1
                CraftData.GetItemSize(fishType);
#else
                TechData.GetItemSize(fishType);
#endif
            var failCount = 0;
            while (failCount < bioReactors.Length && breedCount > 0)
            {
                foreach (var reactor in bioReactors)
                {
                    if (breedCount > 0 && reactor.container.HasRoomFor(sizePerFish.x, sizePerFish.y))
                    {
                        CoroutineHost.StartCoroutine(AddToReactor(subRoot, fishType, sizePerFish, reactor));
                        breedCount--;
                    }
                    else
                    {
                        failCount++;
                    }
                }
                if (failCount < bioReactors.Length)
                {
                    failCount = 0;
                }
            }
            return(breedCount > 0);
        }
        private bool IsAllowedToAdd(Pickupable pickupable, bool verbose)
        {
            bool flag = false;

            var techType = pickupable.GetTechType();

#if SUBNAUTICA
            var equipType = CraftData.GetEquipmentType(techType);
#elif BELOWZERO
            var equipType = TechData.GetEquipmentType(techType);
#endif


            if (equipType == EquipmentType.PowerCellCharger)
            {
                flag = true;
            }
            else
            {
                QuickLogger.Message(AIPowerCellSocketBuildable.OnlyPowercellsAllowed(), true);
            }

            return(flag);
        }
Esempio n. 9
0
        public void Patch_EventsInvoked()
        {
            // ARRANGE
            const TechType createdTechType = TechType.Accumulator;

            IPrefabHandler           mockPrefabHandler    = Substitute.For <IPrefabHandler>();
            ISpriteHandler           mockSpriteHandler    = Substitute.For <ISpriteHandler>();
            ITechTypeHandlerInternal mockTechTypeHandler  = Substitute.For <ITechTypeHandlerInternal>();
            ICraftDataHandler        mockCraftDataHandler = Substitute.For <ICraftDataHandler>();
            IKnownTechHandler        mockKnownTechHandler = Substitute.For <IKnownTechHandler>();

            mockTechTypeHandler
            .AddTechType(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <string>(), Arg.Any <string>(), Arg.Any <bool>())
            .Returns(createdTechType);

            var techData = new TechData();

            var pdaItem = new SimpleTestPdaItem
            {
                PrefabHandler    = mockPrefabHandler,
                SpriteHandler    = mockSpriteHandler,
                TechTypeHandler  = mockTechTypeHandler,
                CraftDataHandler = mockCraftDataHandler,
                KnownTechHandler = mockKnownTechHandler,
                TechDataToReturn = techData,
            };

            // ACT
            pdaItem.Patch();

            // ASSERT
            mockCraftDataHandler.Received(1).SetTechData(createdTechType, techData);
            mockCraftDataHandler.Received(1).AddToGroup(TechGroup.Cyclops, TechCategory.Cyclops, createdTechType);
            mockKnownTechHandler.DidNotReceiveWithAnyArgs();
            mockTechTypeHandler.Received(1).AddTechType(Arg.Any <string>(), "classId", "friendlyName", "description", true);
        }
        private bool IsAllowedToAdd(Pickupable pickupable, bool verbose)
        {
            bool flag = false;

            var techType = pickupable.GetTechType();

#if SUBNAUTICA
            var equipType = CraftData.GetEquipmentType(techType);
#elif BELOWZERO
            var equipType = TechData.GetEquipmentType(techType);
#endif


            if (equipType == EquipmentType.PowerCellCharger)
            {
                flag = true;
            }
            else
            {
                ErrorMessage.AddMessage(FCSDeepDrillerBuildable.OnlyPowercellsAllowed());
            }

            return(flag);
        }
Esempio n. 11
0
 public ReinforcedColdGloves() : base("ReinforcedColdGloves", "Reinforced Cold Gloves", "Reinforced insulating gloves provide physical protection and insulation from extreme temperatures.")
 {
     OnFinishedPatching += () =>
     {
         int coldResist = TechData.GetColdResistance(TechType.ColdSuitGloves);
         DWEquipmentBonanza.Reflection.AddColdResistance(this.TechType, System.Math.Max(10, coldResist));
         DWEquipmentBonanza.Reflection.SetItemSize(this.TechType, 2, 2);
         Log.LogDebug($"Finished patching {this.TechType.AsString()}, found source cold resist of {coldResist}, cold resistance for techtype {this.TechType.AsString()} = {TechData.GetColdResistance(this.TechType)}");
         Main.AddSubstitution(this.TechType, TechType.ColdSuitGloves);
         Main.AddSubstitution(this.TechType, TechType.ReinforcedGloves);
         Main.AddModTechType(this.TechType);
     };
 }
Esempio n. 12
0
 public ReinforcedColdSuit() : base("ReinforcedColdSuit", "Reinforced Cold Suit", "Reinforced, insulated diving suit providing physical protection and insulation from extreme temperatures.")
 {
     OnFinishedPatching += () =>
     {
         int coldResist = TechData.GetColdResistance(TechType.ColdSuit);
         Reflection.AddColdResistance(this.TechType, System.Math.Max(50, coldResist));
         Reflection.SetItemSize(this.TechType, 2, 3);
         Log.LogDebug($"Finished patching {this.TechType.AsString()}, found source cold resist of {coldResist}, cold resistance for techtype {this.TechType.AsString()} = {TechData.GetColdResistance(this.TechType)}");
         Main.AddSubstitution(this.TechType, TechType.ColdSuit);
         Main.AddSubstitution(this.TechType, TechType.ReinforcedDiveSuit);
         Main.AddModTechType(this.TechType);
         Reflection.AddCompoundTech(this.TechType, new List <TechType>()
         {
             TechType.ReinforcedDiveSuit,
             TechType.ColdSuit
         });
     };
 }
Esempio n. 13
0
        private static void HandleModifiedRecipe(IModifiedRecipe modifiedRecipe)
        {
            bool overrideRecipe = false;

            ITechData original = CraftData.Get(modifiedRecipe.ItemID);

            var replacement = new TechData();

            // Amount
            if (modifiedRecipe.AmountCrafted.HasValue)
            {
                overrideRecipe         |= true;
                replacement.craftAmount = modifiedRecipe.AmountCrafted.Value;
            }
            else
            {
                replacement.craftAmount = original.craftAmount;
            }

            // Ingredients
            if (modifiedRecipe.IngredientsCount.HasValue)
            {
                overrideRecipe |= true;
                foreach (EmIngredient ingredient in modifiedRecipe.Ingredients)
                {
                    replacement.Ingredients.Add(
                        new Ingredient(
                            ingredient.ItemID,
                            ingredient.Required));
                }
            }
            else
            {
                for (int i = 0; i < original.ingredientCount; i++)
                {
                    replacement.Ingredients.Add(
                        new Ingredient(
                            original.GetIngredient(i).techType,
                            original.GetIngredient(i).amount));
                }
            }

            // Linked Items
            if (modifiedRecipe.LinkedItemsCount.HasValue)
            {
                overrideRecipe |= true;
                foreach (TechType linkedItem in modifiedRecipe.LinkedItems)
                {
                    replacement.LinkedItems.Add(linkedItem);
                }
            }
            else
            {
                for (int i = 0; i < original.linkedItemCount; i++)
                {
                    replacement.LinkedItems.Add(original.GetLinkedItem(i));
                }
            }

            if (overrideRecipe)
            {
                CraftDataHandler.SetTechData(modifiedRecipe.ItemID, replacement);
            }
        }
Esempio n. 14
0
 /// <summary>
 /// <para>Allows you to edit recipes, i.e. TechData for TechTypes.</para>
 /// <para>Can be used for existing TechTypes too.</para>
 /// </summary>
 /// <param name="techType">The TechType whose TechData you want to edit.</param>
 /// <param name="techData">The TechData for that TechType.</param>
 /// <seealso cref="TechData"/>
 void ICraftDataHandler.SetTechData(TechType techType, TechData techData)
 {
     CraftDataPatcher.CustomTechData[techType] = techData;
 }
Esempio n. 15
0
 /// <summary>
 /// <para>Allows you to edit recipes, i.e. TechData for TechTypes.</para>
 /// <para>Can be used for existing TechTypes too.</para>
 /// </summary>
 /// <param name="techType">The TechType whose TechData you want to edit.</param>
 /// <param name="techData">The TechData for that TechType.</param>
 /// <seealso cref="TechData"/>
 public static void SetTechData(TechType techType, TechData techData)
 {
     Main.SetTechData(techType, techData);
 }
Esempio n. 16
0
        /// <summary>
        /// This is a copy paste of the original <see cref="Survival.Eat(GameObject)"/> because there are too many things to transpile
        /// </summary>
        /// <param name="__instance"></param>
        /// <param name="useObj"></param>
        private void NewPrefixPatch(Survival __instance, GameObject useObj)
        {
            bool flag = false;

            if (useObj != null)
            {
                Eatable component = useObj.GetComponent <Eatable>();
                if (component != null)
                {
                    bool flag2 = component.maxCharges == 0 || component.charges > 0;
                    if (component.GetFoodValue() != 0f && flag2)
                    {
                        if (__instance.food <= __instance.GetStomachSize() - 1)
                        {
                            __instance.food = Mathf.Clamp(__instance.food + component.GetFoodValue(), __instance.GetMinStomachSize(), __instance.GetStomachOverfillSize());
                        }
                        __instance.onEat.Trigger(component.GetFoodValue());
                        if (component.GetFoodValue() > 0f)
                        {
                            GoalManager.main.OnCustomGoalEvent("Eat_Something");
                        }
                        result = component.removeOnUse;
                        flag   = true;
                    }
                    if (component.GetWaterValue() != 0f && flag2)
                    {
                        __instance.water = Mathf.Clamp(__instance.water + component.GetWaterValue(), __instance.GetMinWater(), __instance.GetWaterOverfillSize());
                        __instance.onDrink.Trigger(component.GetWaterValue());
                        if (component.GetWaterValue() > 0f)
                        {
                            GoalManager.main.OnCustomGoalEvent("Drink_Something");
                        }
                        result = component.removeOnUse;
                        flag   = true;
                    }
                    float healthValue = component.GetHealthValue();
                    if (healthValue != 0f && flag2)
                    {
                        if (healthValue > 0f)
                        {
                            __instance.liveMixin.AddHealth(healthValue);
                            GoalManager.main.OnCustomGoalEvent("Heal_Damage");
                        }
                        else if (healthValue <= -1f)
                        {
                            __instance.liveMixin.TakeDamage(-healthValue, default(Vector3), DamageType.FoodPoison, null);
                        }
                        result = component.removeOnUse;
                        flag   = true;
                    }
                    float coldMeterValue = component.GetColdMeterValue();
                    if (coldMeterValue != 0f && flag2)
                    {
                        __instance.bodyTemperature.AddCold(coldMeterValue);
                        result = component.removeOnUse;
                        flag   = true;
                    }
                    if (!__instance.InConversation() && ((__instance.food > __instance.GetLowFoodThreshold() && __instance.food - component.GetFoodValue() < __instance.GetLowFoodThreshold()) || (__instance.water > __instance.GetLowWaterThreshold() && __instance.water - component.GetWaterValue() < __instance.GetLowWaterThreshold())))
                    {
                        __instance.vitalsOkNotification.Play();
                    }
                }
                if (flag)
                {
                    TechType techType = CraftData.GetTechType(useObj);
                    if (techType == TechType.None)
                    {
                        Pickupable component2 = useObj.GetComponent <Pickupable>();
                        if (component2)
                        {
                            techType = component2.GetTechType();
                        }
                    }
                    FMODAsset useSound = __instance.player.GetUseSound(TechData.GetSoundType(techType));
                    if (useSound)
                    {
                        Utils.PlayFMODAsset(useSound, __instance.player.transform.position, 20f);
                    }
                    if (component.IsRotten())
                    {
                        Utils.PlayFMODAsset(__instance.ateRottenFoodSound, __instance.player.transform.position, 20f);
                    }
                    if (techType == TechType.Bladderfish)
                    {
                        Player.main.GetComponent <OxygenManager>().AddOxygen(__instance.GetO2FromBlatterfish());
                    }
                    if (component.maxCharges > 0)
                    {
                        component.ConsumeCharge();
                    }
                }
            }
        }
        public void SlotArmUp()
        {
#if DEBUG
#else
            if (!Player.main.IsPilotingSeatruck() || !AvatarInputHandler.main.IsEnabled())
            {
                return;
            }
#endif
            if (currentSelectedArm == SeaTruckArm.Left)
            {
                leftButtonDownProcessed = false;

                QuickSlotType quickSlotType = TechData.GetSlotType(currentLeftArmType);

                if (quickSlotType == QuickSlotType.Selectable)
                {
                    leftArm.OnUseUp(out float coolDown);
                }
                else if (quickSlotType == QuickSlotType.SelectableChargeable)
                {
                    if (!helper.IsPowered())
                    {
                        return;
                    }

                    if (helper.GetSlotProgress(LeftArmSlotID) != 1f)
                    {
                        return;
                    }

                    if (leftArm.OnUseUp(out float coolDown))
                    {
                        helper.TruckQuickSlotTimeUsed[LeftArmSlotID] = Time.time;
                        helper.TruckQuickSlotCooldown[LeftArmSlotID] = coolDown;
                    }

                    helper.TruckQuickSlotCharge[LeftArmSlotID] = 0f;
                }
            }
            else if (currentSelectedArm == SeaTruckArm.Right)
            {
                rightButtonDownProcessed = false;

                QuickSlotType quickSlotType = TechData.GetSlotType(currentRightArmType);

                if (quickSlotType == QuickSlotType.Selectable)
                {
                    rightArm.OnUseUp(out float coolDown);
                }
                else if (quickSlotType == QuickSlotType.SelectableChargeable)
                {
                    if (!helper.IsPowered())
                    {
                        return;
                    }

                    if (helper.GetSlotProgress(RightArmSlotID) != 1f)
                    {
                        return;
                    }

                    if (rightArm.OnUseUp(out float coolDown))
                    {
                        helper.TruckQuickSlotTimeUsed[RightArmSlotID] = Time.time;
                        helper.TruckQuickSlotCooldown[RightArmSlotID] = coolDown;
                    }

                    helper.TruckQuickSlotCharge[LeftArmSlotID] = 0f;
                }
            }
        }
Esempio n. 18
0
        private static bool Prefix(TechType techType, int num = 1, bool noMessage = false, bool spawnIfCantAdd = true)
        {
            if (techType == TechType.Titanium && num == 2 && !noMessage && spawnIfCantAdd)
            {
                TechType scannedFragment = PDAScanner.scanTarget.techType;
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Intercepting scan of fragment {scannedFragment.ToString()}");
#endif

                TechData recipe; // "Variable declaration can be inlined" says Visual Studio, but I'm not sure if it would remain in-scope further down the function if it is.
                if (IngredientsFromScanning.Main.config.TryOverrideRecipe(scannedFragment, out recipe))
                {
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using OverrideRecipe: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }
                else if ((int)scannedFragment > 1112 && (int)scannedFragment < 1117)
                {
                    // TechTypes 1113 to 1116 are Cyclops fragments, which have no blueprint associated, so we need to process them specially.
                    recipe = new TechData();

                    /*CyclopsHullFragment = 1113,
                     * CyclopsBridgeFragment = 1114,
                     * CyclopsEngineFragment = 1115,
                     * CyclopsDockingBayFragment = 1116,*/

                    switch ((int)scannedFragment)
                    {
                    case 1113:
                        recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 2));
                        recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                        break;

                    case 1114:
                        recipe.Ingredients.Add(new Ingredient(TechType.EnameledGlass, 3));
                        break;

                    case 1115:
                        recipe.Ingredients.Add(new Ingredient(TechType.Lubricant, 1));
                        recipe.Ingredients.Add(new Ingredient(TechType.AdvancedWiringKit, 1));
                        recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                        break;

                    case 1116:
                        recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 2));
                        break;
                    }
                    recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                    recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 1));
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using recipe from manual override: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }
                else
                {
                    PDAScanner.EntryData entryData = PDAScanner.GetEntryData(scannedFragment);
                    if (entryData == null) // Sanity check; this should always be true
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Failed to find EntryData for fragment");
#endif

                        /*CraftData.AddToInventory(TechType.Titanium);
                         * CraftData.AddToInventory(TechType.Titanium); // Adding them one-by-one so as to prevent it being caught by this very routine.*/
                        return(true);
                    }
                    //Logger.Log(Logger.Level.Debug, $"Found entryData {entryData.ToString()}");
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Found entryData {JsonConvert.SerializeObject(entryData, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif


                    //CraftData.AddToInventory(TechType.Titanium);
                    //CraftData.AddToInventory(TechType.Copper);
                    recipe = CraftDataHandler.GetTechData(entryData.blueprint);
                    if (recipe == null)
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Failed to find blueprint for EntryData");
#endif

                        /*CraftData.AddToInventory(TechType.Titanium);
                         * CraftData.AddToInventory(TechType.Titanium); // One-by-one again, as above.*/
                        return(true);
                    }
                    //Logger.Log(Logger.Level.Debug, $"Found recipe {recipe.ToString()}");
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using recipe from EntryData: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }

                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    if (IngredientsFromScanning.Main.config.TrySubstituteIngredient(recipe.Ingredients[i].techType, out List <Ingredient> Substitutes))
                    {
                        foreach (Ingredient sub in Substitutes)
                        {
                            recipe.Ingredients.Add(sub);
                        }
                        recipe.Ingredients.RemoveAt(i); // Remove the current ingredient...
                        i--;                            // ...and make sure the loop continues at the item after this, not the one after that.
                    }
                }

                // I believe the easiest way to get a random item from the blueprint would be to make a list of techTypes; if an ingredient is used twice in the recipe, it will appear in the list twice.
                // That way, we can generate a random number where 0<=rnd<list.count, and select that item.
                List <TechType> bp = new List <TechType> {
                };
                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    for (int j = 0; j < recipe.Ingredients[i].amount; j++)
                    {
                        bp.Add(recipe.Ingredients[i].techType);
                    }
                }

                // Now build up weights
                List <WeightedItem> BlueprintPairs = new List <WeightedItem>();
                float TotalWeight = 0f;
                //Logger.Log(Logger.Level.Error, "Unidentified Vehicle Type!");
                for (int i = 0; i < bp.Count; i++)
                {
                    float thisWeight = IngredientsFromScanning.Main.config.GetWeightForTechType(bp[i]);
                    TotalWeight += thisWeight;
                    WeightedItem thisWeightedItem = new WeightedItem(TotalWeight, bp[i]);
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Adding item to drop list, TechType = {thisWeightedItem.tech.ToString()},   this weight = {thisWeight}, cumulative weight = {thisWeightedItem.Weight}");
#endif
                    BlueprintPairs.Add(thisWeightedItem);
                }

                // Now we should be able to pick a few random numbers between 0 and the list's total weight, and add those. We want to remove that entry afterwards, but that's not a big ask.
                System.Random rng            = new System.Random();
                int           numIngredients = Math.Min(IngredientsFromScanning.Main.config.GenerateGiftValue(), BlueprintPairs.Count);
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Generated a value for this scan of {numIngredients} components.");
#endif

                int    awards = 0;
                double r;
                for (int i = 0; i < numIngredients && BlueprintPairs.Count > 0; i++)
                {
                    r = rng.NextDouble() * TotalWeight;
                    for (int j = 0; j < BlueprintPairs.Count; j++)
                    {
                        //                                               This part is for sanity checking
                        //                                   ___________________________|______________________________
                        //                                  /                                                          \
                        if (r < BlueprintPairs[j].Weight || ((j + 1) == BlueprintPairs.Count && awards < numIngredients))
                        {
#if !RELEASE
                            Logger.Log(Logger.Level.Debug, $"With randomised weight of {r}, adding tech {BlueprintPairs[j].tech} to player inventory");
#endif
                            AddInventory(BlueprintPairs[j].tech, 1, false, true);
                            //CraftData.AddToInventory(BlueprintPairs[j].tech, 1, false, true);
                            awards++;
                            TotalWeight -= IngredientsFromScanning.Main.config.GetWeightForTechType(BlueprintPairs[j].tech);
                            BlueprintPairs.RemoveAt(j);
                            break;
                        }
                    }
                }
                return(false);
            }
            return(true);
        }
Esempio n. 19
0
        public static void Patch()
        {
            // Create new Craft Tree Type
            CreateCustomTree(out CraftTree.Type craftType);
            HModTreeType = craftType;

            // Create a new TechType for new fabricator
            HModFabTechType = TechTypeHandler.AddTechType(CustomFabAndTreeID,
                                                          FriendlyName,
                                                          "Construct Player upgrade modules So you can survive more deadly woonds, or even deliver them yourself.",
                                                          ImageUtils.LoadSpriteFromFile(@"./QMods/HealthModuleMod/Assets/MissingFabricator.png"),
                                                          true);

            // Create a Recipie for the new TechType
            var customFabRecipe = new TechData()
            {
                craftAmount = 1,
                Ingredients = new List <Ingredient>(new Ingredient[3]//State you are using 3 ingredients
                {
                    new Ingredient(TechType.Titanium, 1),
                    new Ingredient(TechType.ComputerChip, 1),
                    new Ingredient(TechType.FiberMesh, 2),
                    //State what ingredients you are using.
                })
            };

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

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

            LanguageHandler.SetLanguageLine(HandOverText, "Use Vehicle Module Fabricator");

            // Set the buildable prefab
            PrefabHandler.RegisterPrefab(new HModFabricatorModulePrefab(CustomFabAndTreeID, HModFabTechType));

            // Associate the recipie to the new TechType
            CraftDataHandler.SetTechData(HModFabTechType, customFabRecipe);

            string unlockMessage = $"{FriendlyName} blueprint discovered!";

            SMLHelper.CustomSpriteHandler.customSprites.Add(new SMLHelper.CustomSprite(TechType.Terraformer, ImageUtils.LoadSpriteFromFile(@"./QMods/HealthModuleMod/Assets/TerraFormer.png")));

            var toUnlock = new TechType[1] {
                TechType.DiamondBlade
            };

            KnownTechHandler.SetAnalysisTechEntry(TechType.Diamond, toUnlock, unlockMessage);
            var toUnlock1 = new TechType[1] {
                HModFabTechType
            };

            KnownTechHandler.SetAnalysisTechEntry(TechType.FiberMesh, toUnlock1, unlockMessage);
            var toUnlock2 = new TechType[1] {
                TechType.Terraformer
            };

            KnownTechHandler.SetAnalysisTechEntry(TechType.Melon, toUnlock2, unlockMessage);
            var toUnlock3 = new TechType[1] {
                TechType.BaseUpgradeConsole
            };

            KnownTechHandler.SetAnalysisTechEntry(TechType.Terraformer, toUnlock3, unlockMessage);
            //KnownTechHandler.SetAnalysisTechEntry(TechType.Cyclops, toUnlock, unlockMessage);
        }
Esempio n. 20
0
        public static void Patch()
        {
            mainDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            assetsFolder  = Path.Combine(mainDirectory, "Assets");
            LoadAssetBundle();
            LoadConfig();
            //patch crafting recipes
            //is there a more efficient way of doing this?
            turbineBlade = TechTypeHandler.AddTechType("TurbineBlade", "Turbine Blade", "Necessary component in constructing a wind turbine. Large and lightweight for maximum aerodynamics.", GetSprite("TurbineBlade"));
            CraftDataHandler.SetItemSize(turbineBlade, new Vector2int(2, 1));
            var techDataBlade = new TechData()
            {
                craftAmount = 3,
                Ingredients = new List <Ingredient>()
                {
                    new Ingredient(TechType.Titanium, 3)
                }
            };

            CraftDataHandler.SetTechData(turbineBlade, techDataBlade);
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, turbineBlade, "Resources", "Electronics");

            turbineGenerator = TechTypeHandler.AddTechType("TurbineGenerator", "Turbine Generator", "Necessary component in constructing a wind turbine. Converts mechanical energy of the blades into usable electricity.", GetSprite("Generator"));
            CraftDataHandler.SetItemSize(turbineGenerator, new Vector2int(2, 2));
            var techDataGen = new TechData()
            {
                craftAmount = 1,
                Ingredients = new List <Ingredient>()
                {
                    new Ingredient(TechType.WiringKit, 1),
                    new Ingredient(TechType.PowerCell, 1),
                    new Ingredient(TechType.Lubricant, 1)
                }
            };

            CraftDataHandler.SetTechData(turbineGenerator, techDataGen);
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, turbineGenerator, "Resources", "Electronics");

            turbinePole = TechTypeHandler.AddTechType("TurbinePole", "Turbine Base", "Necessary component in constructing a wind turbine. Supports the large structure.", GetSprite("TurbinePole"));
            CraftDataHandler.SetItemSize(turbinePole, new Vector2int(1, 2));
            var techDataPole = new TechData()
            {
                craftAmount = 1,
                Ingredients = new List <Ingredient>()
                {
                    new Ingredient(TechType.Titanium, 4)
                }
            };

            CraftDataHandler.SetTechData(turbinePole, techDataPole);
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, turbinePole, "Resources", "Electronics");

            var turbine = new WindTurbine.TurbinePatch();

            turbine.Patch();

            //Add the databank entry.
            LanguageHandler.SetLanguageLine("Ency_WindTurbine", "Wind Turbine");
            LanguageHandler.SetLanguageLine("EncyDesc_WindTurbine", string.Format("A large generator suspended by 17.5 meter tall pole. The lightweight blades are rotated by the planet's strong air currents and efficiently converts the force into electrical energy. The generator contains a large internal battery that can hold up to {0} units of power. Unlike solar panels, these operate at roughly the same efficiency throughout the day. Orientation does not appear to affect power output. However certain places seem to simply have more wind than others. Power output also increases with altitude.", config.MaxPower));

            //This just isn't working for now. Maybe another update?
            //var windTool = new WindTool.WindToolPatch();
            //windTool.Patch();
        }
 public static void AddRecipe(TechType craftedItem, TechData recipe, CraftingPath craftingPath)
 {
     AddRecipe(craftedItem, recipe, craftingPath.Scheme, craftingPath.Path);
 }
Esempio n. 22
0
 public static void Write(this BinaryWriter writer, TechData techData, MapInfoFormatVersion formatVersion) => techData.WriteTo(writer, formatVersion);
Esempio n. 23
0
 public InsulatedRebreather() : base("InsulatedRebreather", "Insulated Rebreather", "Rebreather equipped with insulation helps slow the onset of hypothermia")
 {
     OnFinishedPatching += () =>
     {
         int coldResist = TechData.GetColdResistance(TechType.ColdSuitHelmet);
         DWEquipmentBonanza.Reflection.AddColdResistance(this.TechType, System.Math.Max(20, coldResist));
         DWEquipmentBonanza.Reflection.SetItemSize(this.TechType, 2, 2);
         Log.LogDebug($"Finished patching {this.TechType.AsString()}, using source cold resist of {coldResist}, cold resistance for techtype {this.TechType.AsString()} = {TechData.GetColdResistance(this.TechType)}");
         Main.AddSubstitution(this.TechType, TechType.ColdSuitHelmet);
         Main.AddSubstitution(this.TechType, TechType.Rebreather);
         Main.AddModTechType(this.TechType);
         Reflection.AddCompoundTech(this.TechType, new List <TechType>()
         {
             TechType.Rebreather,
             TechType.ColdSuit
         });
     };
 }
        public void SlotArmHeld()
        {
#if DEBUG
#else
            if (!Player.main.IsPilotingSeatruck() || !AvatarInputHandler.main.IsEnabled())
            {
                return;
            }
#endif
            if (!helper.IsPowered())
            {
                return;
            }

            if (currentSelectedArm == SeaTruckArm.Left)
            {
                if (!leftButtonDownProcessed)
                {
                    return;
                }

                if (helper.GetSlotProgress(LeftArmSlotID) != 1f)
                {
                    return;
                }

                QuickSlotType quickSlotType = TechData.GetSlotType(currentLeftArmType);

                if (quickSlotType == QuickSlotType.Selectable && leftArm.OnUseHeld(out float coolDown))
                {
                    if (helper.TruckPowerRelay)
                    {
                        helper.TruckPowerRelay.ConsumeEnergy(leftArm.GetEnergyCost(), out float amount);
                    }

                    helper.TruckQuickSlotTimeUsed[LeftArmSlotID] = Time.time;
                    helper.TruckQuickSlotCooldown[LeftArmSlotID] = coolDown;
                }
            }
            else if (currentSelectedArm == SeaTruckArm.Right)
            {
                if (!rightButtonDownProcessed)
                {
                    return;
                }

                if (helper.GetSlotProgress(RightArmSlotID) != 1f)
                {
                    return;
                }

                QuickSlotType quickSlotType = TechData.GetSlotType(currentRightArmType);

                if (quickSlotType == QuickSlotType.Selectable && rightArm.OnUseHeld(out float coolDown))
                {
                    if (helper.TruckPowerRelay)
                    {
                        helper.TruckPowerRelay.ConsumeEnergy(leftArm.GetEnergyCost(), out float amount);
                    }

                    helper.TruckQuickSlotTimeUsed[RightArmSlotID] = Time.time;
                    helper.TruckQuickSlotCooldown[RightArmSlotID] = coolDown;
                }
            }
        }
Esempio n. 25
0
        public static void ApplyTechData()
        {
            if (ingredientss.Count == 0)
            {
                Log.Warning(name, "The item has no valid ingredients and will not be able to be crafted!");
            }
            if (ingredientss.Count == 1)
            {
                techData = new TechData
                {
                    craftAmount = 1,
                    Ingredients = new List <Ingredient>()
                    {
                        ingredientss.GetLast()
                    }
                };
            }
            if (ingredientss.Count == 2)
            {
                var i1 = ingredientss.GetLast();
                ingredientss.Remove(i1);

                techData = new TechData
                {
                    craftAmount = 1,
                    Ingredients = new List <Ingredient>()
                    {
                        i1,
                        ingredientss.GetLast()
                    }
                };
            }
            if (ingredientss.Count == 3)
            {
                var i1 = ingredientss.GetLast();
                ingredientss.Remove(i1);
                var i2 = ingredientss.GetLast();
                ingredientss.Remove(i2);

                techData = new TechData
                {
                    craftAmount = 1,
                    Ingredients = new List <Ingredient>()
                    {
                        i1,
                        i2,
                        ingredientss.GetLast()
                    }
                };
            }
            if (ingredientss.Count == 4)
            {
                var i1 = ingredientss.GetLast();
                ingredientss.Remove(i1);
                var i2 = ingredientss.GetLast();
                ingredientss.Remove(i2);
                var i3 = ingredientss.GetLast();
                ingredientss.Remove(i3);

                techData = new TechData
                {
                    craftAmount = 1,
                    Ingredients = new List <Ingredient>()
                    {
                        i1,
                        i2,
                        i3,
                        ingredientss.GetLast()
                    }
                };
            }
            if (ingredientss.Count == 5)
            {
                var i1 = ingredientss.GetLast();
                ingredientss.Remove(i1);
                var i2 = ingredientss.GetLast();
                ingredientss.Remove(i2);
                var i3 = ingredientss.GetLast();
                ingredientss.Remove(i3);
                var i4 = ingredientss.GetLast();
                ingredientss.Remove(i4);

                techData = new TechData
                {
                    craftAmount = 1,
                    Ingredients = new List <Ingredient>()
                    {
                        i1,
                        i2,
                        i3,
                        i4,
                        ingredientss.GetLast()
                    }
                };
            }
            CraftDataHandler.SetTechData(techType, techData);
        }
        /// <summary>
        /// Creates the recipe for the GameObject
        /// </summary>
        /// <param name="craftAmount">The Amount of items to return</param>
        /// <param name="ingredients">The List of ingredients</param>
        /// <param name="linkedItemsList"> The list of Linkitems</param>
        /// <returns></returns>
#if SUBNAUTICA
        public static TechData CreateRecipe(int craftAmount, List <Ingredient> ingredients, List <string> linkedItemsList)
        {
            var result = new TechData();
Esempio n. 27
0
        public static bool Prefix(Constructable __instance)
        {
#endif
            if (Player.main.GetVehicle() != null && GameModeUtils.RequiresIngredients())
            {
                Vehicle thisVehicle = Player.main.GetVehicle();
                if (__instance._constructed)
                {
                    return(true);
                }
                int count = __instance.resourceMap.Count;

                int   resourceID = __instance.GetResourceID();
                float backupConstructedAmount = __instance.constructedAmount;
                __instance.constructedAmount -= Time.deltaTime / (count * Constructable.GetConstructInterval());
                __instance.constructedAmount  = Mathf.Clamp01(__instance.constructedAmount);
                int resourceID2 = __instance.GetResourceID();
                if (resourceID2 != resourceID)
                {
                    TechType techType = __instance.resourceMap[resourceID2];

                    Vector2int size =
#if SN1
                        CraftData.GetItemSize(techType);
#elif BZ
                        TechData.GetItemSize(techType);
#endif

                    if (thisVehicle.GetType().Equals(typeof(Exosuit)))
                    {
                        StorageContainer storageContainer = ((Exosuit)thisVehicle).storageContainer;

                        if (storageContainer.container.HasRoomFor(size.x, size.y))
                        {
                            CoroutineHost.StartCoroutine(AddToVehicle(techType, storageContainer.container));
                        }
                        else
                        {
                            __instance.constructedAmount = backupConstructedAmount;
                            return(true);
                        }
                    }
#if SN1
                    else
                    {
                        SeaMoth seamoth      = (SeaMoth)thisVehicle;
                        bool    storageCheck = false;
                        for (int i = 0; i < 12; i++)
                        {
                            try
                            {
                                ItemsContainer storage = seamoth.GetStorageInSlot(i, TechType.VehicleStorageModule);
                                if (storage != null && storage.HasRoomFor(size.x, size.y))
                                {
                                    CoroutineHost.StartCoroutine(AddToVehicle(techType, storage));
                                    storageCheck = true;
                                    break;
                                }
                            }
                            catch (Exception)
                            {
                                continue;
                            }
                        }
                        if (!storageCheck)
                        {
                            __instance.constructedAmount = backupConstructedAmount;
                            return(true);
                        }
                    }
#endif
                }
                __instance.UpdateMaterial();
#if SUBNAUTICA_EXP || BZ
                result.Set(__instance.constructedAmount <= 0f);
                return(false);
#elif SUBNAUTICA_STABLE
                return(__instance.constructedAmount <= 0f);
#endif
            }
            return(true);
        }
Esempio n. 28
0
        public static bool Prefix(Constructable __instance)
        {
#endif
            var player = Player.main;
            if (player.isPiloting && GameModeUtils.RequiresIngredients())
            {
                if (__instance._constructed)
                {
                    return(true);
                }
#if BZ
                if (player.GetComponentInParent <Hoverbike>() is not null)
                {
                    return(true);
                }
#endif
                var count = __instance.resourceMap.Count;

                var resourceID = __instance.GetResourceID();
                var backupConstructedAmount = __instance.constructedAmount;
                __instance.constructedAmount -= Time.deltaTime / (count * Constructable.GetConstructInterval());
                __instance.constructedAmount  = Mathf.Clamp01(__instance.constructedAmount);
                var resourceID2 = __instance.GetResourceID();
                if (resourceID2 != resourceID)
                {
                    var techType = __instance.resourceMap[resourceID2];

                    var size =
#if SN1
                        CraftData.GetItemSize(techType);
#elif BZ
                        TechData.GetItemSize(techType);
#endif

                    var storageCheck = false;
                    var thisVehicle  = Player.main.GetVehicle();
                    if (thisVehicle != null)
                    {
                        switch (thisVehicle)
                        {
                        case Exosuit exosuit:
                        {
                            var storageContainer = exosuit.storageContainer;

                            if (storageContainer.container.HasRoomFor(size.x, size.y))
                            {
                                CoroutineHost.StartCoroutine(AddToVehicle(techType, storageContainer.container));
                                storageCheck = true;
                            }
                            break;
                        }

                        case SeaMoth seaMoth:
                        {
                            for (var i = 0; i < 12; i++)
                            {
                                try
                                {
                                    var storage = seaMoth.GetStorageInSlot(i, TechType.VehicleStorageModule);
                                    if (storage == null || !storage.HasRoomFor(size.x, size.y))
                                    {
                                        continue;
                                    }
                                    CoroutineHost.StartCoroutine(AddToVehicle(techType, storage));
                                    storageCheck = true;
                                    break;
                                }
                                catch
                                {
                                    // ignored
                                }
                            }

                            break;
                        }
                        }
                    }
#if BZ
                    var seaTruck = player.GetComponentInParent <SeaTruckUpgrades>();
                    if (seaTruck != null)
                    {
                        foreach (var storageContainer in seaTruck.GetComponentsInChildren <StorageContainer>() ?? new StorageContainer[0])
                        {
                            try
                            {
                                var storage = storageContainer.container;
                                if (storage == null || !storage.HasRoomFor(size.x, size.y))
                                {
                                    continue;
                                }
                                CoroutineHost.StartCoroutine(AddToVehicle(techType, storage));
                                storageCheck = true;
                                break;
                            }
                            catch
                            {
                                // ignored
                            }
                        }
                    }
#endif

                    if (!storageCheck)
                    {
                        __instance.constructedAmount = backupConstructedAmount;
                        return(true);
                    }
                }
                __instance.UpdateMaterial();
#if SUBNAUTICA_EXP || BZ
                result.Set(__instance.constructedAmount <= 0f);
                return(false);
#elif SUBNAUTICA_STABLE
                return(__instance.constructedAmount <= 0f);
#endif
            }
            return(true);
        }
Esempio n. 29
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;
                }
            }
Esempio n. 30
0
        public static bool PreGetIngredients(ref Recyclotron __instance, ref List <Ingredient> __result)
        {
#if !RELEASE
            Logger.Log(Logger.Level.Debug, $"Recyclotron_GetIngredients_Patch executing");
#endif
            List <Ingredient> ingredients = (List <Ingredient>)RecyclotronIngredients.GetValue(null);
            if (ingredients == null)
            {
#if !RELEASE
                Logger.Log(Logger.Level.Error, $"Failed to acquire List ingredients through Reflection");
#endif
                return(true);
            }

            Logger.Log(Logger.Level.Debug, $"List ingredients received through Reflection");
            HashSet <TechType> batteryTech = (HashSet <TechType>)RecyclotronBatteryTech.GetValue(null);
            if (batteryTech == null)
            {
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Failed to acquire HashSet batteryTech through Reflection");
#endif
                return(true);
            }

            Logger.Log(Logger.Level.Debug, $"HashSet batteryTech received through Reflection");
#if !RELEASE
            Logger.Log(Logger.Level.Debug, $"Reflection values received");
#endif

            ingredients.Clear();
            if (__instance.GetWasteCount() == 1)
            {
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Recyclotron found one item in waste list");
#endif
                Pickupable pickup     = __instance.GetCurrent().inventoryItem.item;
                GameObject gameObject = pickup.gameObject;

                if (gameObject)
                {
                    TechType tt = pickup.GetTechType();
                    Logger.Log(Logger.Level.Debug, $"Item in waste list has TechType {tt.AsString(false)}");
                    ReadOnlyCollection <Ingredient> readOnlyCollection = TechData.GetIngredients(tt);
                    if (readOnlyCollection == null)                     // Try the SMLHelper method instead
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"TechData.GetIngredients failed for TechType {tt.AsString(false)}, attempting SMLHelper");
#endif
                        List <Ingredient> ingredientsList = CraftDataHandler.GetRecipeData(tt)?.Ingredients;
                        if (ingredientsList != null)
                        {
                            readOnlyCollection = new ReadOnlyCollection <Ingredient>(ingredientsList);
                        }
                        else
                        {
#if !RELEASE
                            Logger.Log(Logger.Level.Debug, $"Failed to get ingredients list for TechType {tt.AsString(false)} using SMLHelper");
#endif
                        }
                    }
                    if (readOnlyCollection != null)
                    {
                        foreach (Ingredient ingredient in readOnlyCollection)
                        {
#if !RELEASE
                            Logger.Log(Logger.Level.Debug, $"Processing Ingredients member {ingredient.techType}");
#endif
                            if (!batteryTech.Contains(ingredient.techType))
                            {
                                ingredients.Add(ingredient);
                            }
                        }
                    }
                    //EnergyMixin component = gameObject.GetComponent<EnergyMixin>();
                    //if (component)
                    if (gameObject.TryGetComponent <EnergyMixin>(out EnergyMixin component))
                    {
                        GameObject battery = component.GetBatteryGameObject();
                        if (battery)
                        {
                            ingredients.Add(new Ingredient(CraftData.GetTechType(battery), 1));
                        }
                    }
                }
            }
            __result = ingredients;
            return(false);
        }