using System.Collections.Generic;
using System.Linq;
using Revitalize.Framework.Utilities;
using StardewValley;
namespace Revitalize.Framework.Crafting
{
///
/// A crafting recipe.
///
public class Recipe
{
///
/// The ingredients necessary to craft this recipe.
///
public List ingredients;
///
/// The items produced by this recipe.
///
public List outputs;
public Item DisplayItem
{
get => this.outputs.ElementAt(0).item;
}
///
/// The description for the crafting recipe.
///
public string outputDescription;
///
/// The name for the crafting recipe.
///
public string outputName;
///
/// The stats that this recipe costs. Magic, HP, stamina, gold, etc.
///
public StatCost statCost;
///
/// The number of in-game minutes it takes to craft this item.
///
public int timeToCraft;
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(List inputs, CraftingRecipeComponent output, StatCost StatCost = null,int TimeToCraft=0)
{
this.ingredients = inputs;
this.outputDescription = output.item.getDescription();
this.outputName = output.item.DisplayName;
this.outputs = new List()
{
output
};
this.statCost = StatCost;
this.timeToCraft = TimeToCraft;
}
public Recipe(List inputs, List outputs, string OutputName, string OutputDescription, Item DisplayItem = null, StatCost StatCost = null,int TimeToCraft=0)
{
this.ingredients = inputs;
this.outputs = outputs;
this.outputName = OutputName;
this.outputDescription = OutputDescription;
this.statCost = StatCost;
this.timeToCraft = TimeToCraft;
}
/// Checks if a player contains all recipe ingredients.
public bool PlayerContainsAllIngredients()
{
return this.InventoryContainsAllIngredient(Game1.player.Items.ToList());
}
/// Checks if a player contains a recipe ingredient.
public bool PlayerContainsIngredient(CraftingRecipeComponent pair)
{
return this.InventoryContainsIngredient(Game1.player.Items.ToList(), pair);
}
/// Checks if an inventory contains all items.
public bool InventoryContainsAllIngredient(IList- items)
{
if (this.ingredients.Count == 0) return true;
foreach (CraftingRecipeComponent pair in this.ingredients)
if (!this.InventoryContainsIngredient(items, pair)) return false;
return true;
}
/// Checks if an inventory contains an ingredient.
public bool InventoryContainsIngredient(IList
- items, CraftingRecipeComponent pair)
{
foreach (Item i in items)
{
if (i != null && this.ItemEqualsOther(i, pair.item) && pair.requiredAmount <= 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 (CraftingRecipeComponent pair in this.ingredients)
{
foreach (Item item in manager.items)
{
if (item == null) continue;
if (this.ItemEqualsOther(item, pair.item))
{
if (item.Stack == pair.requiredAmount)
removalList.Add(item); //remove the item
else
item.Stack -= pair.requiredAmount; //or reduce the stack size.
}
}
}
foreach (var v in removalList)
manager.items.Remove(v);
removalList.Clear();
from = manager.items;
}
///
/// Produces outputs for the crafting recipe.
///
///
///
///
public void produce(ref IList
- to, bool dropToGround = false, bool isPlayerInventory = false)
{
var manager = isPlayerInventory
? new InventoryManager(new List
- ())
: new InventoryManager(to);
foreach (CraftingRecipeComponent pair in this.outputs)
{
Item item = pair.item.getOne();
item.addToStack(pair.requiredAmount - 1);
bool added = manager.addItem(item);
if (!added && dropToGround)
Game1.createItemDebris(item, Game1.player.getStandingPosition(), Game1.player.getDirection());
}
to = manager.items;
}
///
/// Consumes all ingredients in given inventory and adds in outputs to the other given inventory.
///
/// The inventory to take ingredients from.
/// The inventory to put outputs into.
/// Should this item be dropped to the ground when crafted?
/// Checks to see if the invventory is the player's
public void craft(ref IList
- from, ref IList
- to, bool dropToGround = false, bool isPlayerInventory = false)
{
InventoryManager manager = new InventoryManager(to,Game1.player.MaxItems);
if (manager.ItemCount + this.outputs.Count >= manager.capacity)
{
if (isPlayerInventory)
Game1.showRedMessage("Inventory Full");
else return;
}
this.consume(ref from);
this.produce(ref to, dropToGround, isPlayerInventory);
}
///
/// Actually crafts the recipe.
///
public void craft()
{
IList
- playerItems = Game1.player.Items;
IList
- outPutItems = new List
- ();
this.craft(ref playerItems, ref outPutItems, true, true);
Game1.player.Items = playerItems; //Set the items to be post consumption.
foreach (Item I in outPutItems)
{
Item copy = I.getOne();
copy.Stack = I.Stack;
Game1.player.addItemToInventory(copy); //Add all items produced.
}
this.statCost.payCost();
}
public bool PlayerCanCraft()
{
return this.PlayerContainsAllIngredients() && this.statCost.canSafelyAffordCost();
}
public bool CanCraft(IList
- items)
{
if (this.statCost == null)
{
return this.InventoryContainsAllIngredient(items);
}
else
{
return this.InventoryContainsAllIngredient(items) && this.statCost.canSafelyAffordCost();
}
}
}
}