/* * Copyright (c) CovertJaguar, 2014 http://railcraft.info * * This code is the property of CovertJaguar * and may only be used with explicit written * permission unless otherwise specified on the * license page at http://railcraft.info/wiki/info:license. */ package mods.railcraft.common.gui.containers; import cpw.mods.fml.common.ObfuscationReflectionHelper; import java.util.Iterator; import java.util.Map; import mods.railcraft.common.gui.slots.SlotRailcraft; import mods.railcraft.common.plugins.forge.WorldPlugin; import net.minecraft.block.BlockAnvil; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; import net.minecraft.inventory.ContainerRepair; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.item.ItemStack; import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import org.apache.commons.lang3.StringUtils; /** * * @author CovertJaguar <http://www.railcraft.info/> */ public class ContainerAnvil extends ContainerRepair { private final IInventory outputSlot = new InventoryCraftResult(); private final World world; private final EntityPlayer player; private final int x, y, z; private int stackSizeToBeUsedInRepair; private String repairedItemName; private final IInventory inputSlots; public ContainerAnvil(InventoryPlayer playerInv, World world, int x, int y, int z, EntityPlayer player) { super(playerInv, world, x, y, z, player); this.world = world; this.player = player; this.x = x; this.y = y; this.z = z; SlotAnvil slot = new SlotAnvil(this, outputSlot, 2, 134, 47, world, x, y, z); slot.slotNumber = 2; inventorySlots.set(2, slot); inputSlots = ObfuscationReflectionHelper.getPrivateValue(ContainerRepair.class, this, 2); } @Override public boolean canInteractWith(EntityPlayer player) { if (!(WorldPlugin.getBlock(world, x, y, z) instanceof BlockAnvil)) return false; return player.getDistanceSq(x + 0.5D, y + 0.5D, z + 0.5D) <= 64.0D; } @Override public void updateRepairOutput() { ItemStack inputA = inputSlots.getStackInSlot(0); this.maximumCost = 0; int i = 0; byte b0 = 0; int j = 0; if (inputA == null) { this.outputSlot.setInventorySlotContents(0, (ItemStack) null); this.maximumCost = 0; } else { ItemStack inputACopy = inputA.copy(); ItemStack inputB = this.inputSlots.getStackInSlot(1); Map enchantments = EnchantmentHelper.getEnchantments(inputACopy); boolean isBook = false; int baseCost = b0 + inputA.getRepairCost() + (inputB == null ? 0 : inputB.getRepairCost()); stackSizeToBeUsedInRepair = 0; int l; int i1; int j1; int k1; int l1; Iterator iterator; Enchantment enchantment; if (inputB != null) { if (!ForgeHooks.onAnvilChange(this, inputA, inputB, outputSlot, repairedItemName, baseCost)) return; isBook = inputB.getItem() == Items.enchanted_book && Items.enchanted_book.func_92110_g(inputB).tagCount() > 0; if (inputACopy.isItemStackDamageable() && inputACopy.getItem().getIsRepairable(inputA, inputB)) { l = Math.min(inputACopy.getItemDamageForDisplay(), inputACopy.getMaxDamage() / 4); if (l <= 0) { this.outputSlot.setInventorySlotContents(0, (ItemStack) null); this.maximumCost = 0; return; } for (i1 = 0; l > 0 && i1 < inputB.stackSize; ++i1) { j1 = inputACopy.getItemDamageForDisplay() - l; inputACopy.setItemDamage(j1); i += Math.max(1, l / 100) + enchantments.size(); l = Math.min(inputACopy.getItemDamageForDisplay(), inputACopy.getMaxDamage() / 4); } this.stackSizeToBeUsedInRepair = i1; } else { if (!isBook && (inputACopy.getItem() != inputB.getItem() || !inputACopy.isItemStackDamageable())) { this.outputSlot.setInventorySlotContents(0, (ItemStack) null); this.maximumCost = 0; return; } if (inputACopy.isItemStackDamageable() && !isBook) { l = inputA.getMaxDamage() - inputA.getItemDamageForDisplay(); i1 = inputB.getMaxDamage() - inputB.getItemDamageForDisplay(); j1 = i1 + inputACopy.getMaxDamage() * 12 / 100; int i2 = l + j1; k1 = inputACopy.getMaxDamage() - i2; if (k1 < 0) k1 = 0; if (k1 < inputACopy.getItemDamage()) { inputACopy.setItemDamage(k1); i += Math.max(1, j1 / 100); } } Map map1 = EnchantmentHelper.getEnchantments(inputB); iterator = map1.keySet().iterator(); while (iterator.hasNext()) { j1 = ((Integer) iterator.next()).intValue(); enchantment = Enchantment.enchantmentsList[j1]; k1 = enchantments.containsKey(Integer.valueOf(j1)) ? ((Integer) enchantments.get(Integer.valueOf(j1))).intValue() : 0; l1 = ((Integer) map1.get(Integer.valueOf(j1))).intValue(); int j2; if (k1 == l1) { ++l1; j2 = l1; } else j2 = Math.max(l1, k1); l1 = j2; int k2 = l1 - k1; boolean isEnchantmentValid = enchantment.canApply(inputA); if (player.capabilities.isCreativeMode || inputA.getItem() == Items.enchanted_book) isEnchantmentValid = true; Iterator iterator1 = enchantments.keySet().iterator(); while (iterator1.hasNext()) { int l2 = ((Integer) iterator1.next()).intValue(); if (l2 != j1 && !enchantment.canApplyTogether(Enchantment.enchantmentsList[l2])) { isEnchantmentValid = false; i += k2; } } if (isEnchantmentValid) { if (l1 > enchantment.getMaxLevel()) l1 = enchantment.getMaxLevel(); enchantments.put(Integer.valueOf(j1), Integer.valueOf(l1)); int i3 = 0; switch (enchantment.getWeight()) { case 1: i3 = 8; break; case 2: i3 = 4; case 3: case 4: case 6: case 7: case 8: case 9: default: break; case 5: i3 = 2; break; case 10: i3 = 1; } if (isBook) i3 = Math.max(1, i3 / 2); i += i3 * k2; } } } } if (StringUtils.isBlank(this.repairedItemName)) { if (inputA.hasDisplayName()) { j = inputA.isItemStackDamageable() ? 7 : inputA.stackSize * 5; i += j; inputACopy.func_135074_t(); } } else if (!this.repairedItemName.equals(inputA.getDisplayName())) { j = inputA.isItemStackDamageable() ? 7 : inputA.stackSize * 5; i += j; if (inputA.hasDisplayName()) baseCost += j / 2; inputACopy.setStackDisplayName(this.repairedItemName); } l = 0; for (iterator = enchantments.keySet().iterator(); iterator.hasNext(); baseCost += l + k1 * l1) { j1 = ((Integer) iterator.next()).intValue(); enchantment = Enchantment.enchantmentsList[j1]; k1 = ((Integer) enchantments.get(Integer.valueOf(j1))).intValue(); l1 = 0; ++l; switch (enchantment.getWeight()) { case 1: l1 = 8; break; case 2: l1 = 4; case 3: case 4: case 6: case 7: case 8: case 9: default: break; case 5: l1 = 2; break; case 10: l1 = 1; } if (isBook) l1 = Math.max(1, l1 / 2); } if (isBook) baseCost = Math.max(1, baseCost / 2); if (isBook && inputACopy != null && !inputACopy.getItem().isBookEnchantable(inputACopy, inputB)) inputACopy = null; this.maximumCost = baseCost + i; if (i <= 0) inputACopy = null; // Railcraft changes max cost from 39 to 50 if (j == i && j > 0 && this.maximumCost > 50) this.maximumCost = 50; // Here too if (this.maximumCost > 50 && !player.capabilities.isCreativeMode) inputACopy = null; if (inputACopy != null) { int repairCost = inputACopy.getRepairCost(); if (inputB != null && repairCost < inputB.getRepairCost()) repairCost = inputB.getRepairCost(); if (inputACopy.hasDisplayName()) repairCost -= 9; if (repairCost < 0) repairCost = 0; repairCost += 2; inputACopy.setRepairCost(repairCost); EnchantmentHelper.setEnchantments(enchantments, inputACopy); } this.outputSlot.setInventorySlotContents(0, inputACopy); this.detectAndSendChanges(); } } /** * used by the Anvil GUI to update the Item Name being typed by the player */ @Override public void updateItemName(String par1Str) { this.repairedItemName = par1Str; if (this.getSlot(2).getHasStack()) { ItemStack itemstack = this.getSlot(2).getStack(); if (StringUtils.isBlank(par1Str)) itemstack.func_135074_t(); else itemstack.setStackDisplayName(this.repairedItemName); } this.updateRepairOutput(); } private class SlotAnvil extends SlotRailcraft { final World world; final int x; final int y; final int z; final ContainerAnvil repairContainer; SlotAnvil(ContainerAnvil container, IInventory inv, int index, int slotX, int slotY, World world, int x, int y, int z) { super(inv, index, slotX, slotY); this.repairContainer = container; this.world = world; this.x = x; this.y = y; this.z = z; } /** * Check if the stack is a valid item for this slot. Always true beside * for the armor slots. */ @Override public boolean isItemValid(ItemStack par1ItemStack) { return false; } /** * Return whether this slot's stack can be taken from this slot. */ @Override public boolean canTakeStack(EntityPlayer par1EntityPlayer) { return (par1EntityPlayer.capabilities.isCreativeMode || par1EntityPlayer.experienceLevel >= this.repairContainer.maximumCost) && this.repairContainer.maximumCost > 0 && this.getHasStack(); } @Override public void onPickupFromSlot(EntityPlayer player, ItemStack stackInSlot) { if (!player.capabilities.isCreativeMode) player.addExperienceLevel(-this.repairContainer.maximumCost); float breakChance = ForgeHooks.onAnvilRepair(player, stackInSlot, repairContainer.inputSlots.getStackInSlot(0), repairContainer.inputSlots.getStackInSlot(1)); repairContainer.inputSlots.setInventorySlotContents(0, (ItemStack) null); if (repairContainer.stackSizeToBeUsedInRepair > 0) { ItemStack itemstack1 = repairContainer.inputSlots.getStackInSlot(1); if (itemstack1 != null && itemstack1.stackSize > repairContainer.stackSizeToBeUsedInRepair) { itemstack1.stackSize -= repairContainer.stackSizeToBeUsedInRepair; repairContainer.inputSlots.setInventorySlotContents(1, itemstack1); } else repairContainer.inputSlots.setInventorySlotContents(1, (ItemStack) null); } else repairContainer.inputSlots.setInventorySlotContents(1, (ItemStack) null); this.repairContainer.maximumCost = 0; // Only Railcraft change is the random chance of damage if (!player.capabilities.isCreativeMode && !this.world.isRemote && WorldPlugin.getBlock(world, x, y, z) instanceof BlockAnvil && player.getRNG().nextFloat() < breakChance) { int i = this.world.getBlockMetadata(this.x, this.y, this.z); int j = i & 3; int k = i >> 2; ++k; if (k > 2) { this.world.setBlockToAir(this.x, this.y, this.z); this.world.playAuxSFX(1020, this.x, this.y, this.z, 0); } else { this.world.setBlockMetadataWithNotify(this.x, this.y, this.z, j | k << 2, 2); this.world.playAuxSFX(1021, this.x, this.y, this.z, 0); } } else if (!this.world.isRemote) this.world.playAuxSFX(1021, this.x, this.y, this.z, 0); } } }