001package net.minecraft.inventory; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.Iterator; 006import java.util.Map; 007import net.minecraft.block.Block; 008import net.minecraft.enchantment.Enchantment; 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.ItemEnchantedBook; 014import net.minecraft.item.ItemStack; 015import net.minecraft.world.World; 016 017public class ContainerRepair extends Container 018{ 019 /** Here comes out item you merged and/or renamed. */ 020 private IInventory outputSlot = new InventoryCraftResult(); 021 022 /** 023 * The 2slots where you put your items in that you want to merge and/or rename. 024 */ 025 private IInventory inputSlots = new InventoryRepair(this, "Repair", true, 2); 026 private World theWorld; 027 private int field_82861_i; 028 private int field_82858_j; 029 private int field_82859_k; 030 031 /** The maximum cost of repairing/renaming in the anvil. */ 032 public int maximumCost = 0; 033 034 /** determined by damage of input item and stackSize of repair materials */ 035 private int stackSizeToBeUsedInRepair = 0; 036 private String repairedItemName; 037 038 /** The player that has this container open. */ 039 private final EntityPlayer thePlayer; 040 041 public ContainerRepair(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) 042 { 043 this.theWorld = par2World; 044 this.field_82861_i = par3; 045 this.field_82858_j = par4; 046 this.field_82859_k = par5; 047 this.thePlayer = par6EntityPlayer; 048 this.addSlotToContainer(new Slot(this.inputSlots, 0, 27, 47)); 049 this.addSlotToContainer(new Slot(this.inputSlots, 1, 76, 47)); 050 this.addSlotToContainer(new SlotRepair(this, this.outputSlot, 2, 134, 47, par2World, par3, par4, par5)); 051 int l; 052 053 for (l = 0; l < 3; ++l) 054 { 055 for (int i1 = 0; i1 < 9; ++i1) 056 { 057 this.addSlotToContainer(new Slot(par1InventoryPlayer, i1 + l * 9 + 9, 8 + i1 * 18, 84 + l * 18)); 058 } 059 } 060 061 for (l = 0; l < 9; ++l) 062 { 063 this.addSlotToContainer(new Slot(par1InventoryPlayer, l, 8 + l * 18, 142)); 064 } 065 } 066 067 /** 068 * Callback for when the crafting matrix is changed. 069 */ 070 public void onCraftMatrixChanged(IInventory par1IInventory) 071 { 072 super.onCraftMatrixChanged(par1IInventory); 073 074 if (par1IInventory == this.inputSlots) 075 { 076 this.updateRepairOutput(); 077 } 078 } 079 080 /** 081 * called when the Anvil Input Slot changes, calculates the new result and puts it in the output slot 082 */ 083 public void updateRepairOutput() 084 { 085 ItemStack itemstack = this.inputSlots.getStackInSlot(0); 086 this.maximumCost = 0; 087 int i = 0; 088 byte b0 = 0; 089 int j = 0; 090 091 if (itemstack == null) 092 { 093 this.outputSlot.setInventorySlotContents(0, (ItemStack)null); 094 this.maximumCost = 0; 095 } 096 else 097 { 098 ItemStack itemstack1 = itemstack.copy(); 099 ItemStack itemstack2 = this.inputSlots.getStackInSlot(1); 100 Map map = EnchantmentHelper.getEnchantments(itemstack1); 101 boolean flag = false; 102 int k = b0 + itemstack.getRepairCost() + (itemstack2 == null ? 0 : itemstack2.getRepairCost()); 103 this.stackSizeToBeUsedInRepair = 0; 104 int l; 105 int i1; 106 int j1; 107 int k1; 108 int l1; 109 Iterator iterator; 110 Enchantment enchantment; 111 112 if (itemstack2 != null) 113 { 114 flag = itemstack2.itemID == Item.enchantedBook.itemID && Item.enchantedBook.func_92110_g(itemstack2).tagCount() > 0; 115 116 if (itemstack1.isItemStackDamageable() && Item.itemsList[itemstack1.itemID].getIsRepairable(itemstack, itemstack2)) 117 { 118 l = Math.min(itemstack1.getItemDamageForDisplay(), itemstack1.getMaxDamage() / 4); 119 120 if (l <= 0) 121 { 122 this.outputSlot.setInventorySlotContents(0, (ItemStack)null); 123 this.maximumCost = 0; 124 return; 125 } 126 127 for (i1 = 0; l > 0 && i1 < itemstack2.stackSize; ++i1) 128 { 129 j1 = itemstack1.getItemDamageForDisplay() - l; 130 itemstack1.setItemDamage(j1); 131 i += Math.max(1, l / 100) + map.size(); 132 l = Math.min(itemstack1.getItemDamageForDisplay(), itemstack1.getMaxDamage() / 4); 133 } 134 135 this.stackSizeToBeUsedInRepair = i1; 136 } 137 else 138 { 139 if (!flag && (itemstack1.itemID != itemstack2.itemID || !itemstack1.isItemStackDamageable())) 140 { 141 this.outputSlot.setInventorySlotContents(0, (ItemStack)null); 142 this.maximumCost = 0; 143 return; 144 } 145 146 if (itemstack1.isItemStackDamageable() && !flag) 147 { 148 l = itemstack.getMaxDamage() - itemstack.getItemDamageForDisplay(); 149 i1 = itemstack2.getMaxDamage() - itemstack2.getItemDamageForDisplay(); 150 j1 = i1 + itemstack1.getMaxDamage() * 12 / 100; 151 int i2 = l + j1; 152 k1 = itemstack1.getMaxDamage() - i2; 153 154 if (k1 < 0) 155 { 156 k1 = 0; 157 } 158 159 if (k1 < itemstack1.getItemDamage()) 160 { 161 itemstack1.setItemDamage(k1); 162 i += Math.max(1, j1 / 100); 163 } 164 } 165 166 Map map1 = EnchantmentHelper.getEnchantments(itemstack2); 167 iterator = map1.keySet().iterator(); 168 169 while (iterator.hasNext()) 170 { 171 j1 = ((Integer)iterator.next()).intValue(); 172 enchantment = Enchantment.enchantmentsList[j1]; 173 k1 = map.containsKey(Integer.valueOf(j1)) ? ((Integer)map.get(Integer.valueOf(j1))).intValue() : 0; 174 l1 = ((Integer)map1.get(Integer.valueOf(j1))).intValue(); 175 int j2; 176 177 if (k1 == l1) 178 { 179 ++l1; 180 j2 = l1; 181 } 182 else 183 { 184 j2 = Math.max(l1, k1); 185 } 186 187 l1 = j2; 188 int k2 = l1 - k1; 189 boolean flag1 = enchantment.func_92089_a(itemstack); 190 191 if (this.thePlayer.capabilities.isCreativeMode || itemstack.itemID == ItemEnchantedBook.enchantedBook.itemID) 192 { 193 flag1 = true; 194 } 195 196 Iterator iterator1 = map.keySet().iterator(); 197 198 while (iterator1.hasNext()) 199 { 200 int l2 = ((Integer)iterator1.next()).intValue(); 201 202 if (l2 != j1 && !enchantment.canApplyTogether(Enchantment.enchantmentsList[l2])) 203 { 204 flag1 = false; 205 i += k2; 206 } 207 } 208 209 if (flag1) 210 { 211 if (l1 > enchantment.getMaxLevel()) 212 { 213 l1 = enchantment.getMaxLevel(); 214 } 215 216 map.put(Integer.valueOf(j1), Integer.valueOf(l1)); 217 int i3 = 0; 218 219 switch (enchantment.getWeight()) 220 { 221 case 1: 222 i3 = 8; 223 break; 224 case 2: 225 i3 = 4; 226 case 3: 227 case 4: 228 case 6: 229 case 7: 230 case 8: 231 case 9: 232 default: 233 break; 234 case 5: 235 i3 = 2; 236 break; 237 case 10: 238 i3 = 1; 239 } 240 241 if (flag) 242 { 243 i3 = Math.max(1, i3 / 2); 244 } 245 246 i += i3 * k2; 247 } 248 } 249 } 250 } 251 252 if (this.repairedItemName != null && !this.repairedItemName.equalsIgnoreCase(itemstack.getDisplayName()) && this.repairedItemName.length() > 0) 253 { 254 j = itemstack.isItemStackDamageable() ? 7 : itemstack.stackSize * 5; 255 i += j; 256 257 if (itemstack.hasDisplayName()) 258 { 259 k += j / 2; 260 } 261 262 itemstack1.setItemName(this.repairedItemName); 263 } 264 265 l = 0; 266 267 for (iterator = map.keySet().iterator(); iterator.hasNext(); k += l + k1 * l1) 268 { 269 j1 = ((Integer)iterator.next()).intValue(); 270 enchantment = Enchantment.enchantmentsList[j1]; 271 k1 = ((Integer)map.get(Integer.valueOf(j1))).intValue(); 272 l1 = 0; 273 ++l; 274 275 switch (enchantment.getWeight()) 276 { 277 case 1: 278 l1 = 8; 279 break; 280 case 2: 281 l1 = 4; 282 case 3: 283 case 4: 284 case 6: 285 case 7: 286 case 8: 287 case 9: 288 default: 289 break; 290 case 5: 291 l1 = 2; 292 break; 293 case 10: 294 l1 = 1; 295 } 296 297 if (flag) 298 { 299 l1 = Math.max(1, l1 / 2); 300 } 301 } 302 303 if (flag) 304 { 305 k = Math.max(1, k / 2); 306 } 307 308 this.maximumCost = k + i; 309 310 if (i <= 0) 311 { 312 itemstack1 = null; 313 } 314 315 if (j == i && j > 0 && this.maximumCost >= 40) 316 { 317 this.theWorld.getWorldLogAgent().logInfo("Naming an item only, cost too high; giving discount to cap cost to 39 levels"); 318 this.maximumCost = 39; 319 } 320 321 if (this.maximumCost >= 40 && !this.thePlayer.capabilities.isCreativeMode) 322 { 323 itemstack1 = null; 324 } 325 326 if (itemstack1 != null) 327 { 328 i1 = itemstack1.getRepairCost(); 329 330 if (itemstack2 != null && i1 < itemstack2.getRepairCost()) 331 { 332 i1 = itemstack2.getRepairCost(); 333 } 334 335 if (itemstack1.hasDisplayName()) 336 { 337 i1 -= 9; 338 } 339 340 if (i1 < 0) 341 { 342 i1 = 0; 343 } 344 345 i1 += 2; 346 itemstack1.setRepairCost(i1); 347 EnchantmentHelper.setEnchantments(map, itemstack1); 348 } 349 350 this.outputSlot.setInventorySlotContents(0, itemstack1); 351 this.detectAndSendChanges(); 352 } 353 } 354 355 public void addCraftingToCrafters(ICrafting par1ICrafting) 356 { 357 super.addCraftingToCrafters(par1ICrafting); 358 par1ICrafting.sendProgressBarUpdate(this, 0, this.maximumCost); 359 } 360 361 @SideOnly(Side.CLIENT) 362 public void updateProgressBar(int par1, int par2) 363 { 364 if (par1 == 0) 365 { 366 this.maximumCost = par2; 367 } 368 } 369 370 /** 371 * Callback for when the crafting gui is closed. 372 */ 373 public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) 374 { 375 super.onCraftGuiClosed(par1EntityPlayer); 376 377 if (!this.theWorld.isRemote) 378 { 379 for (int i = 0; i < this.inputSlots.getSizeInventory(); ++i) 380 { 381 ItemStack itemstack = this.inputSlots.getStackInSlotOnClosing(i); 382 383 if (itemstack != null) 384 { 385 par1EntityPlayer.dropPlayerItem(itemstack); 386 } 387 } 388 } 389 } 390 391 public boolean canInteractWith(EntityPlayer par1EntityPlayer) 392 { 393 return this.theWorld.getBlockId(this.field_82861_i, this.field_82858_j, this.field_82859_k) != Block.anvil.blockID ? false : par1EntityPlayer.getDistanceSq((double)this.field_82861_i + 0.5D, (double)this.field_82858_j + 0.5D, (double)this.field_82859_k + 0.5D) <= 64.0D; 394 } 395 396 /** 397 * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that. 398 */ 399 public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) 400 { 401 ItemStack itemstack = null; 402 Slot slot = (Slot)this.inventorySlots.get(par2); 403 404 if (slot != null && slot.getHasStack()) 405 { 406 ItemStack itemstack1 = slot.getStack(); 407 itemstack = itemstack1.copy(); 408 409 if (par2 == 2) 410 { 411 if (!this.mergeItemStack(itemstack1, 3, 39, true)) 412 { 413 return null; 414 } 415 416 slot.onSlotChange(itemstack1, itemstack); 417 } 418 else if (par2 != 0 && par2 != 1) 419 { 420 if (par2 >= 3 && par2 < 39 && !this.mergeItemStack(itemstack1, 0, 2, false)) 421 { 422 return null; 423 } 424 } 425 else if (!this.mergeItemStack(itemstack1, 3, 39, false)) 426 { 427 return null; 428 } 429 430 if (itemstack1.stackSize == 0) 431 { 432 slot.putStack((ItemStack)null); 433 } 434 else 435 { 436 slot.onSlotChanged(); 437 } 438 439 if (itemstack1.stackSize == itemstack.stackSize) 440 { 441 return null; 442 } 443 444 slot.onPickupFromSlot(par1EntityPlayer, itemstack1); 445 } 446 447 return itemstack; 448 } 449 450 /** 451 * used by the Anvil GUI to update the Item Name being typed by the player 452 */ 453 public void updateItemName(String par1Str) 454 { 455 this.repairedItemName = par1Str; 456 457 if (this.getSlot(2).getHasStack()) 458 { 459 this.getSlot(2).getStack().setItemName(this.repairedItemName); 460 } 461 462 this.updateRepairOutput(); 463 } 464 465 static IInventory getRepairInputInventory(ContainerRepair par0ContainerRepair) 466 { 467 return par0ContainerRepair.inputSlots; 468 } 469 470 static int getStackSizeUsedInRepair(ContainerRepair par0ContainerRepair) 471 { 472 return par0ContainerRepair.stackSizeToBeUsedInRepair; 473 } 474}