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 i = 0; i <= 3 - this.recipeWidth; ++i) 046 { 047 for (int j = 0; j <= 3 - this.recipeHeight; ++j) 048 { 049 if (this.checkMatch(par1InventoryCrafting, i, j, true)) 050 { 051 return true; 052 } 053 054 if (this.checkMatch(par1InventoryCrafting, i, j, 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 k = 0; k < 3; ++k) 070 { 071 for (int l = 0; l < 3; ++l) 072 { 073 int i1 = k - par2; 074 int j1 = l - par3; 075 ItemStack itemstack = null; 076 077 if (i1 >= 0 && j1 >= 0 && i1 < this.recipeWidth && j1 < this.recipeHeight) 078 { 079 if (par4) 080 { 081 itemstack = this.recipeItems[this.recipeWidth - i1 - 1 + j1 * this.recipeWidth]; 082 } 083 else 084 { 085 itemstack = this.recipeItems[i1 + j1 * this.recipeWidth]; 086 } 087 } 088 089 ItemStack itemstack1 = par1InventoryCrafting.getStackInRowAndColumn(k, l); 090 091 if (itemstack1 != null || itemstack != null) 092 { 093 if (itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null) 094 { 095 return false; 096 } 097 098 if (itemstack.itemID != itemstack1.itemID) 099 { 100 return false; 101 } 102 103 if (itemstack.getItemDamage() != 32767 && itemstack.getItemDamage() != itemstack1.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 itemstack = this.getRecipeOutput().copy(); 120 121 if (this.field_92101_f) 122 { 123 for (int i = 0; i < par1InventoryCrafting.getSizeInventory(); ++i) 124 { 125 ItemStack itemstack1 = par1InventoryCrafting.getStackInSlot(i); 126 127 if (itemstack1 != null && itemstack1.hasTagCompound()) 128 { 129 itemstack.setTagCompound((NBTTagCompound)itemstack1.stackTagCompound.copy()); 130 } 131 } 132 } 133 134 return itemstack; 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}