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 }
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 }
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); }
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); }
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); }