001    package net.minecraft.item.crafting;
002    
003    import net.minecraft.inventory.InventoryCrafting;
004    import net.minecraft.item.ItemStack;
005    import net.minecraft.nbt.NBTTagCompound;
006    import net.minecraft.world.World;
007    
008    public 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_92049_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 var3 = 0; var3 <= 3 - this.recipeWidth; ++var3)
046            {
047                for (int var4 = 0; var4 <= 3 - this.recipeHeight; ++var4)
048                {
049                    if (this.checkMatch(par1InventoryCrafting, var3, var4, true))
050                    {
051                        return true;
052                    }
053    
054                    if (this.checkMatch(par1InventoryCrafting, var3, var4, 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 var5 = 0; var5 < 3; ++var5)
070            {
071                for (int var6 = 0; var6 < 3; ++var6)
072                {
073                    int var7 = var5 - par2;
074                    int var8 = var6 - par3;
075                    ItemStack var9 = null;
076    
077                    if (var7 >= 0 && var8 >= 0 && var7 < this.recipeWidth && var8 < this.recipeHeight)
078                    {
079                        if (par4)
080                        {
081                            var9 = this.recipeItems[this.recipeWidth - var7 - 1 + var8 * this.recipeWidth];
082                        }
083                        else
084                        {
085                            var9 = this.recipeItems[var7 + var8 * this.recipeWidth];
086                        }
087                    }
088    
089                    ItemStack var10 = par1InventoryCrafting.getStackInRowAndColumn(var5, var6);
090    
091                    if (var10 != null || var9 != null)
092                    {
093                        if (var10 == null && var9 != null || var10 != null && var9 == null)
094                        {
095                            return false;
096                        }
097    
098                        if (var9.itemID != var10.itemID)
099                        {
100                            return false;
101                        }
102    
103                        if (var9.getItemDamage() != -1 && var9.getItemDamage() != var10.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 var2 = this.getRecipeOutput().copy();
120    
121            if (this.field_92049_f)
122            {
123                for (int var3 = 0; var3 < par1InventoryCrafting.getSizeInventory(); ++var3)
124                {
125                    ItemStack var4 = par1InventoryCrafting.getStackInSlot(var3);
126    
127                    if (var4 != null && var4.hasTagCompound())
128                    {
129                        var2.setTagCompound((NBTTagCompound)var4.stackTagCompound.copy());
130                    }
131                }
132            }
133    
134            return var2;
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_92048_c()
146        {
147            this.field_92049_f = true;
148            return this;
149        }
150    }