using Revitalize.Framework.Utilities; using StardewValley; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Revitalize.Framework.Crafting { public class Recipe { public Dictionary ingredients; public Dictionary outputs; private Item displayItem; public Item DisplayItem { get { if (this.displayItem == null) return outputs.ElementAt(0).Key; else { return displayItem; } } set { this.displayItem = value; } } public string outputDescription; public string outputName; public Recipe() { } /// /// Constructor for single item output. /// /// All the ingredients required to make the output. /// The item given as output with how many public Recipe(Dictionary inputs,KeyValuePair output) { this.ingredients = inputs; this.DisplayItem = output.Key; this.outputDescription = output.Key.getDescription(); this.outputName = output.Key.DisplayName; this.outputs = new Dictionary(); this.outputs.Add(output.Key, output.Value); } public Recipe(Dictionary inputs,Dictionary outputs,string OutputName, string OutputDescription,Item DisplayItem=null) { this.ingredients = inputs; this.outputs = outputs; this.outputName = OutputName; this.outputDescription = OutputDescription; this.DisplayItem = DisplayItem; } /// /// Checks if a player contains all recipe ingredients. /// /// public bool PlayerContainsAllIngredients() { return InventoryContainsAllIngredient(Game1.player.Items.ToList()); } /// /// Checks if a player contains a recipe ingredient. /// /// /// public bool PlayerContainsIngredient(KeyValuePair pair) { return InventoryContainsIngredient(Game1.player.Items.ToList(), pair); } /// /// Checks if an inventory contains all items. /// /// /// public bool InventoryContainsAllIngredient(List items) { foreach (KeyValuePair pair in this.ingredients) { if (InventoryContainsIngredient(items,pair) == false) return false; } return true; } /// /// Checks if an inventory contains an ingredient. /// /// /// /// public bool InventoryContainsIngredient(List items,KeyValuePair pair) { foreach (Item i in items) { if (i == null) continue; if (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) { if (self.Name == other.Name && self.getCategoryName() == other.getCategoryName() && self.GetType() == other.GetType()) return true; return false; } public void consume(ref List from) { if (!InventoryContainsAllIngredient(from)) return; InventoryManager manager = new InventoryManager(from); List removalList = new List(); foreach (KeyValuePair pair in this.ingredients) { foreach(Item InventoryItem in manager.items) { if (InventoryItem == null) continue; if (ItemEqualsOther(InventoryItem, pair.Key)) { if (InventoryItem.Stack == pair.Value) { removalList.Add(InventoryItem); //remove the item } else { InventoryItem.Stack -= pair.Value; //or reduce the stack size. } } } } foreach (var v in removalList) { manager.items.Remove(v); } removalList.Clear(); from = manager.items; } public void produce(ref List to,bool dropToGround=false,bool isPlayerInventory=false) { InventoryManager manager; if (isPlayerInventory == true) { manager = new InventoryManager(new List()); } else { manager = new InventoryManager(to); } foreach(KeyValuePair pair in this.outputs) { Item I = pair.Key.getOne(); I.addToStack(pair.Value - 1); bool added=manager.addItem(I); if (added == false && dropToGround==true) { Game1.createItemDebris(I, Game1.player.getStandingPosition(), Game1.player.getDirection()); } } to = manager.items; } public void craft(ref List from,ref List to,bool dropToGround=false,bool isPlayerInventory=false) { InventoryManager manager = new InventoryManager(to); if (manager.ItemCount + this.outputs.Count >= manager.capacity) { if (isPlayerInventory) Game1.showRedMessage("Inventory Full"); else return; } consume(ref from); produce(ref to,dropToGround,isPlayerInventory); } public void craft() { List playerItems = Game1.player.Items.ToList(); List outPutItems = new List(); craft(ref playerItems,ref outPutItems, true,true); Game1.player.Items = playerItems; //Set the items to be post consumption. foreach(Item I in outPutItems) { Game1.player.addItemToInventory(I); //Add all items produced. } } public bool PlayerCanCraft() { return PlayerContainsAllIngredients(); } public bool CanCraft(List items) { return InventoryContainsAllIngredient(items); } } }