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 }