package eiteam.esteemedinnovation.tools.steam.upgrades; import eiteam.esteemedinnovation.api.tool.SteamTool; import eiteam.esteemedinnovation.api.tool.SteamToolSlot; import eiteam.esteemedinnovation.api.tool.SteamToolUpgrade; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryEnderChest; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ITickable; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; import static eiteam.esteemedinnovation.tools.ToolsModule.upgradeResource; public class ItemTheVoidUpgrade extends Item implements SteamToolUpgrade { private ResourceLocation baseOverlay; public ItemTheVoidUpgrade() { baseOverlay = new ResourceLocation(upgradeResource("void")); MinecraftForge.EVENT_BUS.register(this); } @Override public SteamToolSlot getToolSlot() { return SteamToolSlot.TOOL_CORE; } @Override public String getInformation(ItemStack me, ItemStack tool) { if (tool.hasTagCompound() && tool.getTagCompound().hasKey("voidInventory")) { NBTTagCompound nbt = tool.getTagCompound().getCompoundTag("voidInventory"); int x = nbt.getInteger("x"); int y = nbt.getInteger("y"); int z = nbt.getInteger("z"); return I18n.format("esteemedinnovation.void.desc", x, y, z); } return null; } @Override public ResourceLocation getBaseIcon() { return baseOverlay; } @Override public boolean isUniversal() { return true; } /** * Plays the sounds and particles that indicate a void inventory set/unset. * @param world The world * @param pos The position of the inventory */ private static void indicateVoidSet(World world, BlockPos pos) { int x = pos.getX(); int y = pos.getY(); int z = pos.getZ(); if (world.isRemote) { for (int i = 0; i < world.rand.nextInt(10) + 5; i++) { // Particle spawning code taken from EntityEnderman. world.spawnParticle(EnumParticleTypes.PORTAL, x + (world.rand.nextDouble() - 0.5D), y + world.rand.nextDouble(), z + (world.rand.nextDouble() - 0.5D), (world.rand.nextDouble() - 0.5D) * 2.0D, -world.rand.nextDouble(), (world.rand.nextDouble() - 0.5D) * 2.0D); } } world.playSound(x, y, z, SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 1F, 1F, false); } /** * Sets the X, Y, and Z NBT data for the given NBT compound. * @param nbt The NBTTagCompound to set the data in. * @param x The X coordinate. * @param y The Y coordinate. * @param z The Z coordinate. * @return The modified NBTTagCompound. */ private static NBTTagCompound setVoidInventoryNBT(NBTTagCompound nbt, int x, int y, int z) { nbt.setInteger("x", x); nbt.setInteger("y", y); nbt.setInteger("z", z); return nbt; } @Override public boolean onRightClickBlockWithTool(PlayerInteractEvent.RightClickBlock event, @Nonnull ItemStack toolStack, @Nonnull ItemStack thisUpgradeStack) { EntityPlayer player = event.getEntityPlayer(); if (!player.isSneaking()) { return true; } World world = event.getWorld(); BlockPos pos = event.getPos(); TileEntity tile = world.getTileEntity(pos); if (!(tile instanceof IInventory) || ((IInventory) tile).getSizeInventory() < 1) { return true; } if (!toolStack.hasTagCompound()) { toolStack.setTagCompound(new NBTTagCompound()); } int x = pos.getX(); int y = pos.getY(); int z = pos.getZ(); if (toolStack.getTagCompound().hasKey("voidInventory")) { NBTTagCompound nbt = toolStack.getTagCompound().getCompoundTag("voidInventory"); int existingX = nbt.getInteger("x"); int existingY = nbt.getInteger("y"); int existingZ = nbt.getInteger("z"); if (existingX == x && existingY == y && existingZ == z) { toolStack.getTagCompound().removeTag("voidInventory"); } else { toolStack.getTagCompound().setTag("voidInventory", setVoidInventoryNBT(nbt, x, y, z)); } } else { toolStack.getTagCompound().setTag("voidInventory", setVoidInventoryNBT(new NBTTagCompound(), x, y, z)); } indicateVoidSet(world, pos); return true; } /** * Adds the drops to the inventory. * * @param drops A List of items to add to the inventory. * @param inv The inventory to add items to. * @return The items that did not get added. */ private static List<ItemStack> addToInventory(List<ItemStack> drops, IInventory inv) { List<ItemStack> failures = new ArrayList<>(); for (ItemStack drop : drops) { if (drop == null) { continue; } boolean added = false; for (int i = 0; i < inv.getSizeInventory(); i++) { ItemStack stackInSlot = inv.getStackInSlot(i); if (stackInSlot == null) { inv.setInventorySlotContents(i, drop); added = true; break; } else if (stackInSlot.getItem() == drop.getItem() && stackInSlot.getItemDamage() == drop.getItemDamage() && stackInSlot.stackSize + drop.stackSize < stackInSlot.getMaxStackSize()) { stackInSlot.stackSize += drop.stackSize; inv.setInventorySlotContents(i, stackInSlot); added = true; break; } } if (!added) { failures.add(drop); } } return failures; } @SubscribeEvent(priority = EventPriority.LOWEST) public void sendDropsToVoidInventory(BlockEvent.HarvestDropsEvent event) { EntityPlayer player = event.getHarvester(); if (player == null || event.getState() == null) { return; } World world = event.getWorld(); ItemStack equipped = player.getHeldItemMainhand(); if (equipped == null || player.isSneaking() || !(equipped.getItem() instanceof SteamTool) || !((SteamTool) equipped.getItem()).hasUpgrade(equipped, this) || !((SteamTool) equipped.getItem()).isWound(equipped)) { return; } List<ItemStack> failures; if (equipped.hasTagCompound() && equipped.getTagCompound().hasKey("voidInventory")) { NBTTagCompound nbt = equipped.getTagCompound().getCompoundTag("voidInventory"); int invX = nbt.getInteger("x"); int invY = nbt.getInteger("y"); int invZ = nbt.getInteger("z"); BlockPos blockPos = event.getPos(); BlockPos invPos = new BlockPos(invX, invY, invZ); TileEntity tile = world.getTileEntity(invPos); if (tile == null || invPos == blockPos) { equipped.getTagCompound().removeTag("voidInventory"); indicateVoidSet(world, blockPos); return; } failures = addToInventory(event.getDrops(), (IInventory) tile); if (tile instanceof ITickable) { ((ITickable) tile).update(); } } else { InventoryEnderChest ender = player.getInventoryEnderChest(); failures = addToInventory(event.getDrops(), ender); ender.saveInventoryToNBT(); } event.getDrops().clear(); if (!failures.isEmpty()) { event.getDrops().addAll(failures); } } }