using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Revitalize.Framework.Utilities; using StardewValley; namespace Revitalize.Framework.Crafting { /// /// A vanilla recipe to be used with standard stardew valley machines such as the furnace. /// public class VanillaRecipe { /// /// The time it takes to make the recipe. /// public int timeToMake; /// /// The items required to craft the recipe. /// public Dictionary requiredItems; /// /// The item that becomes the held object for the vanilla object. /// public KeyValuePair outputItem; /// /// The stats it takes to craft this recipe. /// public StatCost stats; /// /// If true the produced item is automatically added it the player's inventory instead. /// public bool automaticallyPutIntoPlayerInventory; public VanillaRecipe() { } public VanillaRecipe(Dictionary RequiredItems, KeyValuePair OutputItem, int TimeToMake, StatCost Stats, bool AutoIntoPlayerItems) { this.requiredItems = RequiredItems; this.outputItem = OutputItem; this.timeToMake = TimeToMake; this.stats = Stats; this.automaticallyPutIntoPlayerInventory = AutoIntoPlayerItems; } public bool PlayerCanCraft() { return this.PlayerContainsAllIngredients() && this.stats.canSafelyAffordCost(); } public bool CanCraft(List items) { return this.InventoryContainsAllIngredient(items); } /// Checks if a player contains all recipe ingredients. public bool PlayerContainsAllIngredients() { return this.InventoryContainsAllIngredient(Game1.player.Items); } /// Checks if a player contains a recipe ingredient. public bool PlayerContainsIngredient(KeyValuePair pair) { return this.InventoryContainsIngredient(Game1.player.Items.ToList(), pair); } /// Checks if an inventory contains all items. public bool InventoryContainsAllIngredient(IList items) { foreach (KeyValuePair pair in this.requiredItems) if (this.InventoryContainsIngredient(items, pair)==false) return false; return true; } /// Checks if an inventory contains an ingredient. public bool InventoryContainsIngredient(IList items, KeyValuePair pair) { foreach (Item i in items) { if (i != null && this.ItemEqualsOther(i, pair.Key) && pair.Value <= i.Stack) return true; } return false; } /// Checks roughly if two items equal each other. public bool ItemEqualsOther(Item self, Item other) { return self.Name == other.Name && self.getCategoryName() == other.getCategoryName() && self.GetType() == other.GetType(); } /// /// Consumes all of the ingredients for the recipe. /// /// public void consume(ref IList from) { if (this.InventoryContainsAllIngredient(from) == false) return; InventoryManager manager = new InventoryManager(from); List removalList = new List(); foreach (KeyValuePair pair in this.requiredItems) { foreach (Item item in manager.items) { if (item == null) continue; if (this.ItemEqualsOther(item, pair.Key)) { if (item.Stack == pair.Value) removalList.Add(item); //remove the item else item.Stack -= pair.Value; //or reduce the stack size. ModCore.log("Remove: " + pair.Key.Name); } } } foreach (var v in removalList) manager.items.Remove(v); removalList.Clear(); from = manager.items; } /// /// Produces outputs for the crafting recipe. /// public void produce(ref StardewValley.Object obj) { Item I = this.outputItem.Key.getOne(); I.Stack = this.outputItem.Value; if (this.automaticallyPutIntoPlayerInventory == false) { obj.heldObject.Value = (StardewValley.Object)I; obj.MinutesUntilReady = this.timeToMake; } else { if (Game1.player.isInventoryFull() == true) { Game1.createItemDebris(I, Game1.player.getTileLocation(), Game1.random.Next(0, 4), Game1.player.currentLocation); } else { Game1.player.addItemToInventory(I); } } return; } /// /// Consumes all ingredients in given inventory and adds in outputs to the other given inventory. /// private void craft(ref IList from, ref StardewValley.Object obj) { this.consume(ref from); this.stats.payCost(); this.produce(ref obj); } /// /// Checks to see if the player can craft this object and if so go ahead and craft it. /// /// public bool craft(StardewValley.Object o) { if (this.PlayerCanCraft()) { IList playerItems = Game1.player.Items; List outPutItems = new List(); ModCore.log("Can craft recipe."); this.craft(ref playerItems, ref o); return true; } return false; } } }