package net.minecraft.server.management; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.WorldSettings; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.MinecraftForge; import cpw.mods.fml.common.eventhandler.Event; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; import net.minecraftforge.event.world.BlockEvent; public class ItemInWorldManager { /** Forge reach distance */ private double blockReachDistance = 5.0d; /** The world object that this object is connected to. */ public World theWorld; /** The EntityPlayerMP object that this object is connected to. */ public EntityPlayerMP thisPlayerMP; private WorldSettings.GameType gameType; /** True if the player is destroying a block */ private boolean isDestroyingBlock; private int initialDamage; private int curBlockX; private int curBlockY; private int curBlockZ; private int curblockDamage; /** * Set to true when the "finished destroying block" packet is received but the block wasn't fully damaged yet. The * block will not be destroyed while this is false. */ private boolean receivedFinishDiggingPacket; private int posX; private int posY; private int posZ; private int initialBlockDamage; private int durabilityRemainingOnBlock; private static final String __OBFID = "CL_00001442"; public ItemInWorldManager(World p_i1524_1_) { this.gameType = WorldSettings.GameType.NOT_SET; this.durabilityRemainingOnBlock = -1; this.theWorld = p_i1524_1_; } public void setGameType(WorldSettings.GameType p_73076_1_) { this.gameType = p_73076_1_; p_73076_1_.configurePlayerCapabilities(this.thisPlayerMP.capabilities); this.thisPlayerMP.sendPlayerAbilities(); } public WorldSettings.GameType getGameType() { return this.gameType; } /** * Get if we are in creative game mode. */ public boolean isCreative() { return this.gameType.isCreative(); } /** * if the gameType is currently NOT_SET then change it to par1 */ public void initializeGameType(WorldSettings.GameType p_73077_1_) { if (this.gameType == WorldSettings.GameType.NOT_SET) { this.gameType = p_73077_1_; } this.setGameType(this.gameType); } public void updateBlockRemoving() { ++this.curblockDamage; float f; int j; if (this.receivedFinishDiggingPacket) { int i = this.curblockDamage - this.initialBlockDamage; Block block = this.theWorld.getBlock(this.posX, this.posY, this.posZ); if (block.getMaterial() == Material.air) { this.receivedFinishDiggingPacket = false; } else { f = block.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, this.posX, this.posY, this.posZ) * (float)(i + 1); j = (int)(f * 10.0F); if (j != this.durabilityRemainingOnBlock) { this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.getEntityId(), this.posX, this.posY, this.posZ, j); this.durabilityRemainingOnBlock = j; } if (f >= 1.0F) { this.receivedFinishDiggingPacket = false; this.tryHarvestBlock(this.posX, this.posY, this.posZ); } } } else if (this.isDestroyingBlock) { Block block1 = this.theWorld.getBlock(this.curBlockX, this.curBlockY, this.curBlockZ); if (block1.getMaterial() == Material.air) { this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.getEntityId(), this.curBlockX, this.curBlockY, this.curBlockZ, -1); this.durabilityRemainingOnBlock = -1; this.isDestroyingBlock = false; } else { int k = this.curblockDamage - this.initialDamage; f = block1.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, this.curBlockX, this.curBlockY, this.curBlockZ) * (float)(k + 1); j = (int)(f * 10.0F); if (j != this.durabilityRemainingOnBlock) { this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.getEntityId(), this.curBlockX, this.curBlockY, this.curBlockZ, j); this.durabilityRemainingOnBlock = j; } } } } /** * if not creative, it calls destroyBlockInWorldPartially untill the block is broken first. par4 is the specific * side. tryHarvestBlock can also be the result of this call */ public void onBlockClicked(int p_73074_1_, int p_73074_2_, int p_73074_3_, int p_73074_4_) { if (!this.gameType.isAdventure() || this.thisPlayerMP.isCurrentToolAdventureModeExempt(p_73074_1_, p_73074_2_, p_73074_3_)) { PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(thisPlayerMP, Action.LEFT_CLICK_BLOCK, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_, theWorld); if (event.isCanceled()) { thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, theWorld)); return; } if (this.isCreative()) { if (!this.theWorld.extinguishFire((EntityPlayer)null, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_)) { this.tryHarvestBlock(p_73074_1_, p_73074_2_, p_73074_3_); } } else { this.initialDamage = this.curblockDamage; float f = 1.0F; Block block = this.theWorld.getBlock(p_73074_1_, p_73074_2_, p_73074_3_); if (!block.isAir(theWorld, p_73074_1_, p_73074_2_, p_73074_3_)) { if (event.useBlock != Event.Result.DENY) { block.onBlockClicked(theWorld, p_73074_1_, p_73074_2_, p_73074_3_, thisPlayerMP); theWorld.extinguishFire(null, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_); } else { thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, theWorld)); } f = block.getPlayerRelativeBlockHardness(thisPlayerMP, thisPlayerMP.worldObj, p_73074_1_, p_73074_2_, p_73074_3_); } if (event.useItem == Event.Result.DENY) { if (f >= 1.0f) { thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, theWorld)); } return; } if (!block.isAir(theWorld, p_73074_1_, p_73074_2_, p_73074_3_) && f >= 1.0F) { this.tryHarvestBlock(p_73074_1_, p_73074_2_, p_73074_3_); } else { this.isDestroyingBlock = true; this.curBlockX = p_73074_1_; this.curBlockY = p_73074_2_; this.curBlockZ = p_73074_3_; int i1 = (int)(f * 10.0F); this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.getEntityId(), p_73074_1_, p_73074_2_, p_73074_3_, i1); this.durabilityRemainingOnBlock = i1; } } } } public void blockRemoving(int p_73082_1_, int p_73082_2_, int p_73082_3_) { if (p_73082_1_ == this.curBlockX && p_73082_2_ == this.curBlockY && p_73082_3_ == this.curBlockZ) { int l = this.curblockDamage - this.initialDamage; Block block = this.theWorld.getBlock(p_73082_1_, p_73082_2_, p_73082_3_); if (!block.isAir(theWorld, p_73082_1_, p_73082_2_, p_73082_3_)) { float f = block.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, p_73082_1_, p_73082_2_, p_73082_3_) * (float)(l + 1); if (f >= 0.7F) { this.isDestroyingBlock = false; this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.getEntityId(), p_73082_1_, p_73082_2_, p_73082_3_, -1); this.tryHarvestBlock(p_73082_1_, p_73082_2_, p_73082_3_); } else if (!this.receivedFinishDiggingPacket) { this.isDestroyingBlock = false; this.receivedFinishDiggingPacket = true; this.posX = p_73082_1_; this.posY = p_73082_2_; this.posZ = p_73082_3_; this.initialBlockDamage = this.initialDamage; } } } } /** * note: this ignores the pars passed in and continues to destroy the onClickedBlock */ public void cancelDestroyingBlock(int p_73073_1_, int p_73073_2_, int p_73073_3_) { this.isDestroyingBlock = false; this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.getEntityId(), this.curBlockX, this.curBlockY, this.curBlockZ, -1); } /** * Removes a block and triggers the appropriate events */ private boolean removeBlock(int p_73079_1_, int p_73079_2_, int p_73079_3_) { return removeBlock(p_73079_1_, p_73079_2_, p_73079_3_, false); } private boolean removeBlock(int p_73079_1_, int p_73079_2_, int p_73079_3_, boolean canHarvest) { Block block = this.theWorld.getBlock(p_73079_1_, p_73079_2_, p_73079_3_); int l = this.theWorld.getBlockMetadata(p_73079_1_, p_73079_2_, p_73079_3_); block.onBlockHarvested(this.theWorld, p_73079_1_, p_73079_2_, p_73079_3_, l, this.thisPlayerMP); boolean flag = block.removedByPlayer(theWorld, thisPlayerMP, p_73079_1_, p_73079_2_, p_73079_3_, canHarvest); if (flag) { block.onBlockDestroyedByPlayer(this.theWorld, p_73079_1_, p_73079_2_, p_73079_3_, l); } return flag; } /** * Attempts to harvest a block at the given coordinate */ public boolean tryHarvestBlock(int p_73084_1_, int p_73084_2_, int p_73084_3_) { BlockEvent.BreakEvent event = ForgeHooks.onBlockBreakEvent(theWorld, gameType, thisPlayerMP, p_73084_1_, p_73084_2_, p_73084_3_); if (event.isCanceled()) { return false; } else { ItemStack stack = thisPlayerMP.getCurrentEquippedItem(); if (stack != null && stack.getItem().onBlockStartBreak(stack, p_73084_1_, p_73084_2_, p_73084_3_, thisPlayerMP)) { return false; } Block block = this.theWorld.getBlock(p_73084_1_, p_73084_2_, p_73084_3_); int l = this.theWorld.getBlockMetadata(p_73084_1_, p_73084_2_, p_73084_3_); this.theWorld.playAuxSFXAtEntity(this.thisPlayerMP, 2001, p_73084_1_, p_73084_2_, p_73084_3_, Block.getIdFromBlock(block) + (this.theWorld.getBlockMetadata(p_73084_1_, p_73084_2_, p_73084_3_) << 12)); boolean flag = false; if (this.isCreative()) { flag = this.removeBlock(p_73084_1_, p_73084_2_, p_73084_3_); this.thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73084_1_, p_73084_2_, p_73084_3_, this.theWorld)); } else { ItemStack itemstack = this.thisPlayerMP.getCurrentEquippedItem(); boolean flag1 = block.canHarvestBlock(thisPlayerMP, l); if (itemstack != null) { itemstack.onBlockDestroyed(this.theWorld, block, p_73084_1_, p_73084_2_, p_73084_3_, this.thisPlayerMP); if (itemstack.stackSize == 0) { this.thisPlayerMP.destroyCurrentEquippedItem(); } } flag = this.removeBlock(p_73084_1_, p_73084_2_, p_73084_3_, flag1); if (flag && flag1) { block.harvestBlock(this.theWorld, this.thisPlayerMP, p_73084_1_, p_73084_2_, p_73084_3_, l); } } // Drop experience if (!this.isCreative() && flag && event != null) { block.dropXpOnBlockBreak(this.theWorld, p_73084_1_, p_73084_2_, p_73084_3_, event.getExpToDrop()); } return flag; } } /** * Attempts to right-click use an item by the given EntityPlayer in the given World */ public boolean tryUseItem(EntityPlayer p_73085_1_, World p_73085_2_, ItemStack p_73085_3_) { int i = p_73085_3_.stackSize; int j = p_73085_3_.getMetadata(); ItemStack itemstack1 = p_73085_3_.useItemRightClick(p_73085_2_, p_73085_1_); if (itemstack1 == p_73085_3_ && (itemstack1 == null || itemstack1.stackSize == i && itemstack1.getMaxItemUseDuration() <= 0 && itemstack1.getMetadata() == j)) { return false; } else { p_73085_1_.inventory.mainInventory[p_73085_1_.inventory.currentItem] = itemstack1; if (this.isCreative()) { itemstack1.stackSize = i; if (itemstack1.isItemStackDamageable()) { itemstack1.setMetadata(j); } } if (itemstack1.stackSize == 0) { p_73085_1_.inventory.mainInventory[p_73085_1_.inventory.currentItem] = null; MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(thisPlayerMP, itemstack1)); } if (!p_73085_1_.isUsingItem()) { ((EntityPlayerMP)p_73085_1_).sendContainerToPlayer(p_73085_1_.inventoryContainer); } return true; } } /** * Activate the clicked on block, otherwise use the held item. Args: player, world, itemStack, x, y, z, side, * xOffset, yOffset, zOffset */ public boolean activateBlockOrUseItem(EntityPlayer player, World worldIn, ItemStack stack, int p_73078_4_, int p_73078_5_, int p_73078_6_, int p_73078_7_, float p_73078_8_, float p_73078_9_, float p_73078_10_) { PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(player, Action.RIGHT_CLICK_BLOCK, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, worldIn); if (event.isCanceled()) { thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73078_4_, p_73078_5_, p_73078_6_, theWorld)); return false; } if (stack != null && stack.getItem().onItemUseFirst(stack, player, worldIn, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_)) { if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(thisPlayerMP, stack); return true; } Block block = worldIn.getBlock(p_73078_4_, p_73078_5_, p_73078_6_); boolean isAir = block.isAir(worldIn, p_73078_4_, p_73078_5_, p_73078_6_); boolean useBlock = !player.isSneaking() || player.getHeldItem() == null; if (!useBlock) useBlock = player.getHeldItem().getItem().doesSneakBypassUse(worldIn, p_73078_4_, p_73078_5_, p_73078_6_, player); boolean result = false; if (useBlock) { if (event.useBlock != Event.Result.DENY) { result = block.onBlockActivated(worldIn, p_73078_4_, p_73078_5_, p_73078_6_, player, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_); } else { thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73078_4_, p_73078_5_, p_73078_6_, theWorld)); result = event.useItem != Event.Result.ALLOW; } } if (stack != null && !result && event.useItem != Event.Result.DENY) { int meta = stack.getMetadata(); int size = stack.stackSize; result = stack.tryPlaceItemIntoWorld(player, worldIn, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_); if (isCreative()) { stack.setMetadata(meta); stack.stackSize = size; } if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(thisPlayerMP, stack); } /* Re-enable if this causes bukkit incompatibility, or re-write client side to only send a single packet per right click. if (par3ItemStack != null && ((!result && event.useItem != Event.Result.DENY) || event.useItem == Event.Result.ALLOW)) { this.tryUseItem(thisPlayerMP, par2World, par3ItemStack); }*/ return result; } /** * Sets the world instance. */ public void setWorld(WorldServer p_73080_1_) { this.theWorld = p_73080_1_; } public double getBlockReachDistance() { return blockReachDistance; } public void setBlockReachDistance(double distance) { blockReachDistance = distance; } }