    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}