001package net.minecraft.inventory; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.List; 006import java.util.Random; 007import net.minecraft.block.Block; 008import net.minecraft.enchantment.EnchantmentData; 009import net.minecraft.enchantment.EnchantmentHelper; 010import net.minecraft.entity.player.EntityPlayer; 011import net.minecraft.entity.player.InventoryPlayer; 012import net.minecraft.item.Item; 013import net.minecraft.item.ItemStack; 014import net.minecraft.world.World; 015 016public class ContainerEnchantment extends Container 017{ 018 /** SlotEnchantmentTable object with ItemStack to be enchanted */ 019 public IInventory tableInventory = new SlotEnchantmentTable(this, "Enchant", true, 1); 020 021 /** current world (for bookshelf counting) */ 022 private World worldPointer; 023 private int posX; 024 private int posY; 025 private int posZ; 026 private Random rand = new Random(); 027 028 /** used as seed for EnchantmentNameParts (see GuiEnchantment) */ 029 public long nameSeed; 030 031 /** 3-member array storing the enchantment levels of each slot */ 032 public int[] enchantLevels = new int[3]; 033 034 public ContainerEnchantment(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) 035 { 036 this.worldPointer = par2World; 037 this.posX = par3; 038 this.posY = par4; 039 this.posZ = par5; 040 this.addSlotToContainer(new SlotEnchantment(this, this.tableInventory, 0, 25, 47)); 041 int l; 042 043 for (l = 0; l < 3; ++l) 044 { 045 for (int i1 = 0; i1 < 9; ++i1) 046 { 047 this.addSlotToContainer(new Slot(par1InventoryPlayer, i1 + l * 9 + 9, 8 + i1 * 18, 84 + l * 18)); 048 } 049 } 050 051 for (l = 0; l < 9; ++l) 052 { 053 this.addSlotToContainer(new Slot(par1InventoryPlayer, l, 8 + l * 18, 142)); 054 } 055 } 056 057 public void addCraftingToCrafters(ICrafting par1ICrafting) 058 { 059 super.addCraftingToCrafters(par1ICrafting); 060 par1ICrafting.sendProgressBarUpdate(this, 0, this.enchantLevels[0]); 061 par1ICrafting.sendProgressBarUpdate(this, 1, this.enchantLevels[1]); 062 par1ICrafting.sendProgressBarUpdate(this, 2, this.enchantLevels[2]); 063 } 064 065 /** 066 * Looks for changes made in the container, sends them to every listener. 067 */ 068 public void detectAndSendChanges() 069 { 070 super.detectAndSendChanges(); 071 072 for (int i = 0; i < this.crafters.size(); ++i) 073 { 074 ICrafting icrafting = (ICrafting)this.crafters.get(i); 075 icrafting.sendProgressBarUpdate(this, 0, this.enchantLevels[0]); 076 icrafting.sendProgressBarUpdate(this, 1, this.enchantLevels[1]); 077 icrafting.sendProgressBarUpdate(this, 2, this.enchantLevels[2]); 078 } 079 } 080 081 @SideOnly(Side.CLIENT) 082 public void updateProgressBar(int par1, int par2) 083 { 084 if (par1 >= 0 && par1 <= 2) 085 { 086 this.enchantLevels[par1] = par2; 087 } 088 else 089 { 090 super.updateProgressBar(par1, par2); 091 } 092 } 093 094 /** 095 * Callback for when the crafting matrix is changed. 096 */ 097 public void onCraftMatrixChanged(IInventory par1IInventory) 098 { 099 if (par1IInventory == this.tableInventory) 100 { 101 ItemStack itemstack = par1IInventory.getStackInSlot(0); 102 int i; 103 104 if (itemstack != null && itemstack.isItemEnchantable()) 105 { 106 this.nameSeed = this.rand.nextLong(); 107 108 if (!this.worldPointer.isRemote) 109 { 110 i = 0; 111 int j; 112 113 for (j = -1; j <= 1; ++j) 114 { 115 for (int k = -1; k <= 1; ++k) 116 { 117 if ((j != 0 || k != 0) && this.worldPointer.isAirBlock(this.posX + k, this.posY, this.posZ + j) && this.worldPointer.isAirBlock(this.posX + k, this.posY + 1, this.posZ + j)) 118 { 119 if (this.worldPointer.getBlockId(this.posX + k * 2, this.posY, this.posZ + j * 2) == Block.bookShelf.blockID) 120 { 121 ++i; 122 } 123 124 if (this.worldPointer.getBlockId(this.posX + k * 2, this.posY + 1, this.posZ + j * 2) == Block.bookShelf.blockID) 125 { 126 ++i; 127 } 128 129 if (k != 0 && j != 0) 130 { 131 if (this.worldPointer.getBlockId(this.posX + k * 2, this.posY, this.posZ + j) == Block.bookShelf.blockID) 132 { 133 ++i; 134 } 135 136 if (this.worldPointer.getBlockId(this.posX + k * 2, this.posY + 1, this.posZ + j) == Block.bookShelf.blockID) 137 { 138 ++i; 139 } 140 141 if (this.worldPointer.getBlockId(this.posX + k, this.posY, this.posZ + j * 2) == Block.bookShelf.blockID) 142 { 143 ++i; 144 } 145 146 if (this.worldPointer.getBlockId(this.posX + k, this.posY + 1, this.posZ + j * 2) == Block.bookShelf.blockID) 147 { 148 ++i; 149 } 150 } 151 } 152 } 153 } 154 155 for (j = 0; j < 3; ++j) 156 { 157 this.enchantLevels[j] = EnchantmentHelper.calcItemStackEnchantability(this.rand, j, i, itemstack); 158 } 159 160 this.detectAndSendChanges(); 161 } 162 } 163 else 164 { 165 for (i = 0; i < 3; ++i) 166 { 167 this.enchantLevels[i] = 0; 168 } 169 } 170 } 171 } 172 173 /** 174 * enchants the item on the table using the specified slot; also deducts XP from player 175 */ 176 public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2) 177 { 178 ItemStack itemstack = this.tableInventory.getStackInSlot(0); 179 180 if (this.enchantLevels[par2] > 0 && itemstack != null && (par1EntityPlayer.experienceLevel >= this.enchantLevels[par2] || par1EntityPlayer.capabilities.isCreativeMode)) 181 { 182 if (!this.worldPointer.isRemote) 183 { 184 List list = EnchantmentHelper.buildEnchantmentList(this.rand, itemstack, this.enchantLevels[par2]); 185 boolean flag = itemstack.itemID == Item.book.itemID; 186 187 if (list != null) 188 { 189 par1EntityPlayer.addExperienceLevel(-this.enchantLevels[par2]); 190 191 if (flag) 192 { 193 itemstack.itemID = Item.enchantedBook.itemID; 194 } 195 196 int j = flag ? this.rand.nextInt(list.size()) : -1; 197 198 for (int k = 0; k < list.size(); ++k) 199 { 200 EnchantmentData enchantmentdata = (EnchantmentData)list.get(k); 201 202 if (!flag || k == j) 203 { 204 if (flag) 205 { 206 Item.enchantedBook.func_92115_a(itemstack, enchantmentdata); 207 } 208 else 209 { 210 itemstack.addEnchantment(enchantmentdata.enchantmentobj, enchantmentdata.enchantmentLevel); 211 } 212 } 213 } 214 215 this.onCraftMatrixChanged(this.tableInventory); 216 } 217 } 218 219 return true; 220 } 221 else 222 { 223 return false; 224 } 225 } 226 227 /** 228 * Callback for when the crafting gui is closed. 229 */ 230 public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) 231 { 232 super.onCraftGuiClosed(par1EntityPlayer); 233 234 if (!this.worldPointer.isRemote) 235 { 236 ItemStack itemstack = this.tableInventory.getStackInSlotOnClosing(0); 237 238 if (itemstack != null) 239 { 240 par1EntityPlayer.dropPlayerItem(itemstack); 241 } 242 } 243 } 244 245 public boolean canInteractWith(EntityPlayer par1EntityPlayer) 246 { 247 return this.worldPointer.getBlockId(this.posX, this.posY, this.posZ) != Block.enchantmentTable.blockID ? false : par1EntityPlayer.getDistanceSq((double)this.posX + 0.5D, (double)this.posY + 0.5D, (double)this.posZ + 0.5D) <= 64.0D; 248 } 249 250 /** 251 * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that. 252 */ 253 public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) 254 { 255 ItemStack itemstack = null; 256 Slot slot = (Slot)this.inventorySlots.get(par2); 257 258 if (slot != null && slot.getHasStack()) 259 { 260 ItemStack itemstack1 = slot.getStack(); 261 itemstack = itemstack1.copy(); 262 263 if (par2 == 0) 264 { 265 if (!this.mergeItemStack(itemstack1, 1, 37, true)) 266 { 267 return null; 268 } 269 } 270 else 271 { 272 if (((Slot)this.inventorySlots.get(0)).getHasStack() || !((Slot)this.inventorySlots.get(0)).isItemValid(itemstack1)) 273 { 274 return null; 275 } 276 277 if (itemstack1.hasTagCompound() && itemstack1.stackSize == 1) 278 { 279 ((Slot)this.inventorySlots.get(0)).putStack(itemstack1.copy()); 280 itemstack1.stackSize = 0; 281 } 282 else if (itemstack1.stackSize >= 1) 283 { 284 ((Slot)this.inventorySlots.get(0)).putStack(new ItemStack(itemstack1.itemID, 1, itemstack1.getItemDamage())); 285 --itemstack1.stackSize; 286 } 287 } 288 289 if (itemstack1.stackSize == 0) 290 { 291 slot.putStack((ItemStack)null); 292 } 293 else 294 { 295 slot.onSlotChanged(); 296 } 297 298 if (itemstack1.stackSize == itemstack.stackSize) 299 { 300 return null; 301 } 302 303 slot.onPickupFromSlot(par1EntityPlayer, itemstack1); 304 } 305 306 return itemstack; 307 } 308}