Пример #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
            }
        protected override RecipeData GetBlueprintRecipe()
        {
#if SN1
            return(CraftDataHandler.GetTechData(TypeToClone));
#elif BZ
            return(CraftDataHandler.GetRecipeData(TypeToClone));
#endif
        }
Пример #5
0
        internal static RecipeData GetData(TechType techType)
        {
#if SN1
            return(CraftDataHandler.GetTechData(techType));
#elif BZ
            return(CraftDataHandler.GetRecipeData(techType));
#endif
        }
        public static void Postfix()
        {
            if (Main.Config.Hardcore)
            {
                var map = PDAScanner.mapping;
                foreach (TechType techType in Enum.GetValues(typeof(TechType)))
                {
                    var data = CraftDataHandler.GetTechData(techType);
                    map.TryGetValue(techType, out var entryData);

                    if (data is null && entryData is { isFragment: false } && entryData.blueprint == TechType.None)
Пример #7
0
        internal static string GetTechDataString(TechType techType)
        {
            var techData = CraftDataHandler.GetTechData(techType);

            var sb = new StringBuilder();

            sb.Append($"Craft {Language.main.Get(techType)} Ingredients:");
            sb.Append(Environment.NewLine);

            foreach (Ingredient ingredient in techData.Ingredients)
            {
                sb.Append(Language.main.Get(ingredient.techType));
                sb.Append(Environment.NewLine);
            }

            return(sb.ToString());
        }
        static void Postfix(CrashHome __instance)
        {
            //rebreather
            var rebreatherTechData = CraftDataHandler.GetTechData(TechType.Rebreather);

            rebreatherTechData.Ingredients.Add(new Ingredient(TechType.RadiationHelmet, 1));

            CraftDataHandler.SetTechData(TechType.Rebreather, rebreatherTechData);

            //reinforcedSuit
            var reinforcedSuitTechData = CraftDataHandler.GetTechData(TechType.ReinforcedDiveSuit);

            reinforcedSuitTechData.Ingredients.Add(new Ingredient(TechType.RadiationSuit, 1));
            reinforcedSuitTechData.Ingredients.Add(new Ingredient(TechType.RadiationGloves, 1));

            CraftDataHandler.SetTechData(TechType.ReinforcedDiveSuit, reinforcedSuitTechData);
        }
Пример #9
0
        internal static TechData CheckIfTechDataAvailable(FCSOperation craft, out bool pass)
        {
            var techData = CraftDataHandler.GetTechData(craft.TechType);

            pass = true;

            if (techData != null)
            {
                foreach (Ingredient ingredient in techData.Ingredients)
                {
                    if (craft.Manager.GetItemCount(ingredient.techType) < ingredient.amount)
                    {
                        pass = false;
                        break;
                    }
                }
            }

            return(techData);
        }
Пример #10
0
 protected override TechData GetBlueprintRecipe()
 {
     return(CraftDataHandler.GetTechData(TechToCopy) ?? new TechData());
 }
Пример #11
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);
        }
Пример #12
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);
        }
Пример #13
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);
        }
Пример #14
0
 internal static bool CheckIfTechDataAvailable(TechType craft)
 {
     return(CraftDataHandler.GetTechData(craft) != null);
 }
Пример #15
0
        public static void Postfix(ref TechType __result)
        {
            if (__result == TechType.None)
            {
                return;
            }

            RecipeData recipeData;
            TechType   techType2;
            bool       eggCheck;

            while (!(eggCheck = TechTypeExtensions.FromString(__result.AsString() + "Egg", out techType2, true)) && (recipeData = CraftDataHandler.GetTechData(__result)) != null && recipeData.ingredientCount > 0)
            {
                try{ __result = recipeData.Ingredients.GetRandom().techType; }
                catch
                {
                    // ignored
                }
            }

            if (eggCheck)
            {
                __result = techType2;
            }
        }