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); } }
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); } }
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); } } }
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)."); }
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); }
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); }
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); }
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); }; }
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 }); }; }
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); } }
/// <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; }
/// <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); }
/// <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; } } }
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); }
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); }
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); }
public static void Write(this BinaryWriter writer, TechData techData, MapInfoFormatVersion formatVersion) => techData.WriteTo(writer, formatVersion);
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; } } }
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();
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); }
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); }
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; } }
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); }