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