    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 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_92101_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_92100_c()
    146    {
    147        this.field_92101_f = true;
    148        return this;
    149    }
    150}