示例#1
0
            public static bool TryGet(TechType originTech, out TechType recyclingTech, bool initialRun = false)
            {
                recyclingTech = TechType.None;
                if (originTech == TechType.None)
                {
                    return(false);
                }
                if (cache.TryGetValue(originTech, out recyclingTech))
                {
                    return(true);
                }
#if SUBNAUTICA
                RecipeData originData = CraftDataHandler.GetTechData(originTech);
#elif BELOWZERO
                RecipeData originData = CraftDataHandler.GetRecipeData(originTech);
#endif
                if (originData == null)
                {
                    if (!initialRun)
                    {
                        Logger.Log(Logger.Level.Error, $"Failed to load RecipeData for TechType '{originTech}'.");
                    }
                    return(false);
                }

                if (Config.IsBlacklisted(originTech))
                {
                    blacklist.Add(originTech);
                }
                recyclingTech     = CreateRecyclingData(originTech, originData);
                cache[originTech] = recyclingTech;

                return(true);
            }
        protected override RecipeData GetBlueprintRecipe()
        {
#if SN1
            return(CraftDataHandler.GetTechData(TechType.Fabricator));
#elif BZ
            return(CraftDataHandler.GetRecipeData(TechType.Fabricator));
#endif
        }
示例#3
0
            public static TechInfo getTechInfo(TechType techType)
            {
#if GAME_SN
                return(CraftDataHandler.GetTechData(techType));
#elif GAME_BZ
                return(CraftDataHandler.GetRecipeData(techType));
#endif
            }
        internal static RecipeData GetData(TechType techType)
        {
#if SN1
            return(CraftDataHandler.GetTechData(techType));
#elif BZ
            return(CraftDataHandler.GetRecipeData(techType));
#endif
        }
        protected override RecipeData GetBlueprintRecipe()
        {
#if SN1
            return(CraftDataHandler.GetTechData(TypeToClone));
#elif BZ
            return(CraftDataHandler.GetRecipeData(TypeToClone));
#endif
        }
示例#6
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);
        }
示例#7
0
        public static bool BatteryCheck(Pickupable pickupable)
        {
            EnergyMixin energyMixin = pickupable.gameObject.GetComponentInChildren <EnergyMixin>();

            if (energyMixin != null)
            {
                GameObject gameObject   = energyMixin.GetBattery();
                bool       defaultCheck = false;
                if (gameObject != null)
                {
                    defaultCheck = energyMixin.defaultBattery == CraftData.GetTechType(gameObject);
                }

                if (gameObject == null && QModServices.Main.ModPresent("NoBattery"))
                {
                    return(true);
                }
                if (gameObject != null && (defaultCheck || QModServices.Main.ModPresent("NoBattery")))
                {
                    IBattery battery = gameObject.GetComponent <IBattery>();
#if SUBNAUTICA
                    TechData techData = CraftDataHandler.GetTechData(pickupable.GetTechType());
#elif BELOWZERO
                    RecipeData techData = CraftDataHandler.GetRecipeData(pickupable.GetTechType());
#endif
                    bool recipeCheck = techData.Ingredients.FindAll((ingredient) => ingredient.techType == TechType.Battery || ingredient.techType == TechType.PrecursorIonBattery || ingredient.techType == TechType.LithiumIonBattery || ingredient.techType == TechType.PowerCell || ingredient.techType == TechType.PrecursorIonPowerCell).Count == 0;
                    if (battery != null && QModServices.Main.ModPresent("NoBattery") && recipeCheck)
                    {
                        ErrorMessage.AddMessage($"{pickupable.GetTechType().ToString()} has a battery in it. Cannot Recycle.");
                        return(false);
                    }
                    else if (battery != null && defaultCheck && battery.charge > (battery.capacity * 0.99))
                    {
                        return(true);
                    }
                    else
                    {
                        if (gameObject != null && !defaultCheck)
                        {
                            ErrorMessage.AddMessage($"{CraftData.GetTechType(gameObject).ToString()} is not the default battery for {pickupable.GetTechType().ToString()}.");
                        }
                        else
                        {
                            ErrorMessage.AddMessage($"{pickupable.GetTechType().ToString()} is not fully charged and cannot be recycled.");
                        }

                        return(false);
                    }
                }
                else
                {
                    if (gameObject != null)
                    {
                        ErrorMessage.AddMessage($"{CraftData.GetTechType(gameObject).ToString()} is not the default battery for {pickupable.GetTechType().ToString()}.");
                    }
                    else
                    {
                        ErrorMessage.AddMessage($"{pickupable.GetTechType().ToString()} has no battery.");
                    }

                    return(false);
                }
            }

            IBattery b2 = pickupable.GetComponent <IBattery>();
            if (b2 != null)
            {
                if (b2.charge > (b2.capacity * 0.99))
                {
                    return(true);
                }
                else
                {
                    ErrorMessage.AddMessage($"{pickupable.GetTechType().ToString()} is not fully charged and cannot be recycled.");
                    return(false);
                }
            }
            return(true);
        }
示例#8
0
        public static bool Prefix(Trashcan __instance)
        {
            if (__instance.biohazard)
            {
                return(true);
            }

            __instance.storageContainer.hoverText        = "Recycling Bin";
            __instance.storageContainer.storageLabel     = "Recycling Bin";
            __instance.storageContainer.container._label = "Recycling Bin";

            inventoryItems   = new List <InventoryItem>();
            forcePickupItems = new List <Pickupable>();

            foreach (Trashcan.Waste waste in __instance.wasteList)
            {
                InventoryItem item = waste.inventoryItem;

                if (item is null)
                {
                    continue;
                }

                TechType techType = item.item.GetTechType();
#if SUBNAUTICA
                TechData techData = CraftDataHandler.GetTechData(techType);
#elif BELOWZERO
                RecipeData techData = CraftDataHandler.GetRecipeData(techType);
#endif

                if (!GameInput.GetButtonHeld(GameInput.Button.Deconstruct) && techType != TechType.Titanium && techData != null && techData.ingredientCount > 0 && Main.BatteryCheck(item.item))
                {
                    if (CheckRequirements(__instance, item.item, techData))
                    {
                        foreach (Ingredient ingredient in techData.Ingredients)
                        {
                            for (int i = ingredient.amount; i > 0; i--)
                            {
                                GameObject gameObject = CraftData.InstantiateFromPrefab(ingredient.techType, false);
                                gameObject.SetActive(true);
                                Pickupable pickupable = gameObject.GetComponent <Pickupable>();
                                pickupable.Pickup(false);
                                if ((item.item.GetComponent <IBattery>() == null && pickupable.GetComponent <IBattery>() != null && QModServices.Main.ModPresent("NoBattery")) || pickupable.GetComponent <LiveMixin>() != null)
                                {
                                    UnityEngine.Object.Destroy(pickupable.gameObject);
                                }
                                else
                                {
                                    forcePickupItems.Add(pickupable);
                                }
                            }
                        }
                        break;
                    }
                }
                else
                {
                    if (GameInput.GetButtonHeld(GameInput.Button.Deconstruct))
                    {
                        inventoryItems.Add(item);
                    }
                    else
                    {
                        forcePickupItems.Add(item.item);
                    }

                    break;
                }
            }
            forcePickupItems.ForEach((rejectedItem) => Inventory.main.ForcePickup(rejectedItem));
            inventoryItems.ForEach((item) => UnityEngine.Object.Destroy(item.item.gameObject));

            return(false);
        }
        private static bool PreAddToInventory(TechType techType, int num = 1, bool noMessage = false, bool spawnIfCantAdd = true)
        {
            if (techType == TechType.Titanium && num == 2 && !noMessage && spawnIfCantAdd)
            {
                TechType   scannedFragment = TechType.None;
                RecipeData recipe          = null;
                if (BlueprintHandTargetPatches.bIsDatabox)
                {
                    //if (!Main.config.bInterceptDataboxes)
                    //    return true;

                    scannedFragment = BlueprintHandTargetPatches.databoxUnlock;
                    if (Main.config.TryOverrideRecipe(scannedFragment, out recipe))
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Using OverrideRecipe: {Json.JsonConvert.SerializeObject(recipe, Json.Formatting.Indented)}");
#endif
                    }
                    else
                    {
                        recipe = CraftDataHandler.GetTechData(scannedFragment);
                    }
                }
                else
                {
                    scannedFragment = PDAScanner.scanTarget.techType;
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Intercepting scan of fragment {scannedFragment.ToString()}");
#endif

                    if (PartsFromScanning.Main.config.TryOverrideRecipe(scannedFragment, out recipe))
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Using OverrideRecipe: {Json.JsonConvert.SerializeObject(recipe, 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 RecipeData();

                        /*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: {Json.JsonConvert.SerializeObject(recipe, 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 {Json.JsonConvert.SerializeObject(entryData, Json.Formatting.Indented)}");
#endif


                        //CraftData.AddToInventory(TechType.Titanium);
                        //CraftData.AddToInventory(TechType.Copper);
#if SUBNAUTICA_STABLE
                        recipe = CraftDataHandler.GetTechData(entryData.blueprint);
#elif BELOWZERO
                        recipe = CraftDataHandler.GetRecipeData(entryData.blueprint);
#endif
                        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: {Json.JsonConvert.SerializeObject(recipe, Json.Formatting.Indented)}");
#endif
                    }
                }

                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    if (PartsFromScanning.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 = 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(PartsFromScanning.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))
                        {
                            AddInventory(BlueprintPairs[j].tech, 1, false, true);
                            //CraftData.AddToInventory(BlueprintPairs[j].tech, 1, false, true);
                            awards++;
                            TotalWeight -= Main.config.GetWeightForTechType(BlueprintPairs[j].tech);
                            BlueprintPairs.RemoveAt(j);
                            break;
                        }
                    }
                }
                return(false);
            }
            return(true);
        }