001package net.minecraft.item.crafting;
002
003import net.minecraft.inventory.InventoryCrafting;
004import net.minecraft.item.ItemStack;
005import net.minecraft.nbt.NBTTagCompound;
006import net.minecraft.world.World;
007
008public class ShapedRecipes implements IRecipe
009{
010    /** How many horizontal slots this recipe is wide. */
011    public final int recipeWidth;
012
013    /** How many vertical slots this recipe uses. */
014    public final int recipeHeight;
015
016    /** Is a array of ItemStack that composes the recipe. */
017    public final ItemStack[] recipeItems;
018
019    /** Is the ItemStack that you get when craft the recipe. */
020    private ItemStack recipeOutput;
021
022    /** Is the itemID of the output item that you get when craft the recipe. */
023    public final int recipeOutputItemID;
024    private boolean field_92101_f = false;
025
026    public ShapedRecipes(int par1, int par2, ItemStack[] par3ArrayOfItemStack, ItemStack par4ItemStack)
027    {
028        this.recipeOutputItemID = par4ItemStack.itemID;
029        this.recipeWidth = par1;
030        this.recipeHeight = par2;
031        this.recipeItems = par3ArrayOfItemStack;
032        this.recipeOutput = par4ItemStack;
033    }
034
035    public ItemStack getRecipeOutput()
036    {
037        return this.recipeOutput;
038    }
039
040    /**
041     * Used to check if a recipe matches current crafting inventory
042     */
043    public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World)
044    {
045        for (int i = 0; i <= 3 - this.recipeWidth; ++i)
046        {
047            for (int j = 0; j <= 3 - this.recipeHeight; ++j)
048            {
049                if (this.checkMatch(par1InventoryCrafting, i, j, true))
050                {
051                    return true;
052                }
053
054                if (this.checkMatch(par1InventoryCrafting, i, j, false))
055                {
056                    return true;
057                }
058            }
059        }
060
061        return false;
062    }
063
064    /**
065     * Checks if the region of a crafting inventory is match for the recipe.
066     */
067    private boolean checkMatch(InventoryCrafting par1InventoryCrafting, int par2, int par3, boolean par4)
068    {
069        for (int k = 0; k < 3; ++k)
070        {
071            for (int l = 0; l < 3; ++l)
072            {
073                int i1 = k - par2;
074                int j1 = l - par3;
075                ItemStack itemstack = null;
076
077                if (i1 >= 0 && j1 >= 0 && i1 < this.recipeWidth && j1 < this.recipeHeight)
078                {
079                    if (par4)
080                    {
081                        itemstack = this.recipeItems[this.recipeWidth - i1 - 1 + j1 * this.recipeWidth];
082                    }
083                    else
084                    {
085                        itemstack = this.recipeItems[i1 + j1 * this.recipeWidth];
086                    }
087                }
088
089                ItemStack itemstack1 = par1InventoryCrafting.getStackInRowAndColumn(k, l);
090
091                if (itemstack1 != null || itemstack != null)
092                {
093                    if (itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null)
094                    {
095                        return false;
096                    }
097
098                    if (itemstack.itemID != itemstack1.itemID)
099                    {
100                        return false;
101                    }
102
103                    if (itemstack.getItemDamage() != 32767 && itemstack.getItemDamage() != itemstack1.getItemDamage())
104                    {
105                        return false;
106                    }
107                }
108            }
109        }
110
111        return true;
112    }
113
114    /**
115     * Returns an Item that is the result of this recipe
116     */
117    public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting)
118    {
119        ItemStack itemstack = this.getRecipeOutput().copy();
120
121        if (this.field_92101_f)
122        {
123            for (int i = 0; i < par1InventoryCrafting.getSizeInventory(); ++i)
124            {
125                ItemStack itemstack1 = par1InventoryCrafting.getStackInSlot(i);
126
127                if (itemstack1 != null && itemstack1.hasTagCompound())
128                {
129                    itemstack.setTagCompound((NBTTagCompound)itemstack1.stackTagCompound.copy());
130                }
131            }
132        }
133
134        return itemstack;
135    }
136
137    /**
138     * Returns the size of the recipe area
139     */
140    public int getRecipeSize()
141    {
142        return this.recipeWidth * this.recipeHeight;
143    }
144
145    public ShapedRecipes func_92100_c()
146    {
147        this.field_92101_f = true;
148        return this;
149    }
150}