    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    }