001 package net.minecraft.src; 002 003 import net.minecraftforge.common.ForgeHooks; 004 import net.minecraftforge.common.MinecraftForge; 005 import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; 006 007 public class ItemInWorldManager 008 { 009 /** Forge reach distance */ 010 private double blockReachDistance = 5.0d; 011 /** The world object that this object is connected to. */ 012 public World theWorld; 013 014 /** The EntityPlayerMP object that this object is connected to. */ 015 public EntityPlayerMP thisPlayerMP; 016 private EnumGameType gameType; 017 018 /** 019 * set to true on first call of destroyBlockInWorldPartially, false before any further calls 020 */ 021 private boolean isPartiallyDestroyedBlockWhole; 022 private int initialDamage; 023 private int partiallyDestroyedBlockX; 024 private int partiallyDestroyedBlockY; 025 private int partiallyDestroyedBlockZ; 026 private int curblockDamage; 027 private boolean field_73097_j; 028 private int posX; 029 private int posY; 030 private int posZ; 031 private int field_73093_n; 032 private int durabilityRemainingOnBlock; 033 034 public ItemInWorldManager(World par1World) 035 { 036 this.gameType = EnumGameType.NOT_SET; 037 this.durabilityRemainingOnBlock = -1; 038 this.theWorld = par1World; 039 } 040 041 public void setGameType(EnumGameType par1EnumGameType) 042 { 043 this.gameType = par1EnumGameType; 044 par1EnumGameType.configurePlayerCapabilities(this.thisPlayerMP.capabilities); 045 this.thisPlayerMP.sendPlayerAbilities(); 046 } 047 048 public EnumGameType getGameType() 049 { 050 return this.gameType; 051 } 052 053 /** 054 * Get if we are in creative game mode. 055 */ 056 public boolean isCreative() 057 { 058 return this.gameType.isCreative(); 059 } 060 061 /** 062 * if the gameType is currently NOT_SET then change it to par1 063 */ 064 public void initializeGameType(EnumGameType par1EnumGameType) 065 { 066 if (this.gameType == EnumGameType.NOT_SET) 067 { 068 this.gameType = par1EnumGameType; 069 } 070 071 this.setGameType(this.gameType); 072 } 073 074 public void updateBlockRemoving() 075 { 076 ++this.curblockDamage; 077 int var1; 078 float var4; 079 int var5; 080 081 if (this.field_73097_j) 082 { 083 var1 = this.curblockDamage - this.field_73093_n; 084 int var2 = this.theWorld.getBlockId(this.posX, this.posY, this.posZ); 085 086 if (var2 == 0) 087 { 088 this.field_73097_j = false; 089 } 090 else 091 { 092 Block var3 = Block.blocksList[var2]; 093 var4 = var3.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, this.posX, this.posY, this.posZ) * (float)(var1 + 1); 094 var5 = (int)(var4 * 10.0F); 095 096 if (var5 != this.durabilityRemainingOnBlock) 097 { 098 this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.posX, this.posY, this.posZ, var5); 099 this.durabilityRemainingOnBlock = var5; 100 } 101 102 if (var4 >= 1.0F) 103 { 104 this.field_73097_j = false; 105 this.tryHarvestBlock(this.posX, this.posY, this.posZ); 106 } 107 } 108 } 109 else if (this.isPartiallyDestroyedBlockWhole) 110 { 111 var1 = this.theWorld.getBlockId(this.partiallyDestroyedBlockX, this.partiallyDestroyedBlockY, this.partiallyDestroyedBlockZ); 112 Block var6 = Block.blocksList[var1]; 113 114 if (var6 == null) 115 { 116 this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.partiallyDestroyedBlockX, this.partiallyDestroyedBlockY, this.partiallyDestroyedBlockZ, -1); 117 this.durabilityRemainingOnBlock = -1; 118 this.isPartiallyDestroyedBlockWhole = false; 119 } 120 else 121 { 122 int var7 = this.curblockDamage - this.initialDamage; 123 var4 = var6.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, this.partiallyDestroyedBlockX, this.partiallyDestroyedBlockY, this.partiallyDestroyedBlockZ) * (float)(var7 + 1); 124 var5 = (int)(var4 * 10.0F); 125 126 if (var5 != this.durabilityRemainingOnBlock) 127 { 128 this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.partiallyDestroyedBlockX, this.partiallyDestroyedBlockY, this.partiallyDestroyedBlockZ, var5); 129 this.durabilityRemainingOnBlock = var5; 130 } 131 } 132 } 133 } 134 135 /** 136 * if not creative, it calls destroyBlockInWorldPartially untill the block is broken first. par4 is the specific 137 * side. tryHarvestBlock can also be the result of this call 138 */ 139 public void onBlockClicked(int par1, int par2, int par3, int par4) 140 { 141 if (!this.gameType.isAdventure()) 142 { 143 if (this.isCreative()) 144 { 145 if (!this.theWorld.extinguishFire((EntityPlayer)null, par1, par2, par3, par4)) 146 { 147 this.tryHarvestBlock(par1, par2, par3); 148 } 149 } 150 else 151 { 152 this.theWorld.extinguishFire(this.thisPlayerMP, par1, par2, par3, par4); 153 this.initialDamage = this.curblockDamage; 154 float var5 = 1.0F; 155 int var6 = this.theWorld.getBlockId(par1, par2, par3); 156 157 if (var6 > 0) 158 { 159 Block.blocksList[var6].onBlockClicked(this.theWorld, par1, par2, par3, this.thisPlayerMP); 160 var5 = Block.blocksList[var6].getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, par1, par2, par3); 161 } 162 163 if (var6 > 0 && var5 >= 1.0F) 164 { 165 this.tryHarvestBlock(par1, par2, par3); 166 } 167 else 168 { 169 this.isPartiallyDestroyedBlockWhole = true; 170 this.partiallyDestroyedBlockX = par1; 171 this.partiallyDestroyedBlockY = par2; 172 this.partiallyDestroyedBlockZ = par3; 173 int var7 = (int)(var5 * 10.0F); 174 this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, par1, par2, par3, var7); 175 this.durabilityRemainingOnBlock = var7; 176 } 177 } 178 } 179 } 180 181 public void uncheckedTryHarvestBlock(int par1, int par2, int par3) 182 { 183 if (par1 == this.partiallyDestroyedBlockX && par2 == this.partiallyDestroyedBlockY && par3 == this.partiallyDestroyedBlockZ) 184 { 185 int var4 = this.curblockDamage - this.initialDamage; 186 int var5 = this.theWorld.getBlockId(par1, par2, par3); 187 188 if (var5 != 0) 189 { 190 Block var6 = Block.blocksList[var5]; 191 float var7 = var6.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, par1, par2, par3) * (float)(var4 + 1); 192 193 if (var7 >= 0.7F) 194 { 195 this.isPartiallyDestroyedBlockWhole = false; 196 this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, par1, par2, par3, -1); 197 this.tryHarvestBlock(par1, par2, par3); 198 } 199 else if (!this.field_73097_j) 200 { 201 this.isPartiallyDestroyedBlockWhole = false; 202 this.field_73097_j = true; 203 this.posX = par1; 204 this.posY = par2; 205 this.posZ = par3; 206 this.field_73093_n = this.initialDamage; 207 } 208 } 209 } 210 } 211 212 /** 213 * note: this ignores the pars passed in and continues to destroy the onClickedBlock 214 */ 215 public void destroyBlockInWorldPartially(int par1, int par2, int par3) 216 { 217 this.isPartiallyDestroyedBlockWhole = false; 218 this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.partiallyDestroyedBlockX, this.partiallyDestroyedBlockY, this.partiallyDestroyedBlockZ, -1); 219 } 220 221 /** 222 * Removes a block and triggers the appropriate events 223 */ 224 private boolean removeBlock(int par1, int par2, int par3) 225 { 226 Block var4 = Block.blocksList[this.theWorld.getBlockId(par1, par2, par3)]; 227 int var5 = this.theWorld.getBlockMetadata(par1, par2, par3); 228 229 if (var4 != null) 230 { 231 var4.onBlockHarvested(this.theWorld, par1, par2, par3, var5, this.thisPlayerMP); 232 } 233 234 boolean var6 = (var4 != null && var4.removeBlockByPlayer(theWorld, thisPlayerMP, par1, par2, par3)); 235 236 if (var4 != null && var6) 237 { 238 var4.onBlockDestroyedByPlayer(this.theWorld, par1, par2, par3, var5); 239 } 240 241 return var6; 242 } 243 244 /** 245 * Attempts to harvest a block at the given coordinate 246 */ 247 public boolean tryHarvestBlock(int par1, int par2, int par3) 248 { 249 if (this.gameType.isAdventure()) 250 { 251 return false; 252 } 253 else 254 { 255 ItemStack stack = thisPlayerMP.getCurrentEquippedItem(); 256 if (stack != null && stack.getItem().onBlockStartBreak(stack, par1, par2, par3, thisPlayerMP)) 257 { 258 return false; 259 } 260 int var4 = this.theWorld.getBlockId(par1, par2, par3); 261 int var5 = this.theWorld.getBlockMetadata(par1, par2, par3); 262 this.theWorld.playAuxSFXAtEntity(this.thisPlayerMP, 2001, par1, par2, par3, var4 + (this.theWorld.getBlockMetadata(par1, par2, par3) << 12)); 263 boolean var6 = false; 264 265 if (this.isCreative()) 266 { 267 var6 = this.removeBlock(par1, par2, par3); 268 this.thisPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(par1, par2, par3, this.theWorld)); 269 } 270 else 271 { 272 ItemStack var7 = this.thisPlayerMP.getCurrentEquippedItem(); 273 boolean var8 = false; 274 Block block = Block.blocksList[var4]; 275 if (block != null) 276 { 277 var8 = block.canHarvestBlock(thisPlayerMP, var5); 278 } 279 280 if (var7 != null) 281 { 282 var7.func_77941_a(this.theWorld, var4, par1, par2, par3, this.thisPlayerMP); 283 284 if (var7.stackSize == 0) 285 { 286 this.thisPlayerMP.destroyCurrentEquippedItem(); 287 MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(thisPlayerMP, var7)); 288 } 289 } 290 291 var6 = this.removeBlock(par1, par2, par3); 292 if (var6 && var8) 293 { 294 Block.blocksList[var4].harvestBlock(this.theWorld, this.thisPlayerMP, par1, par2, par3, var5); 295 } 296 } 297 298 return var6; 299 } 300 } 301 302 /** 303 * Attempts to right-click use an item by the given EntityPlayer in the given World 304 */ 305 public boolean tryUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack) 306 { 307 int var4 = par3ItemStack.stackSize; 308 int var5 = par3ItemStack.getItemDamage(); 309 ItemStack var6 = par3ItemStack.useItemRightClick(par2World, par1EntityPlayer); 310 311 if (var6 == par3ItemStack && (var6 == null || var6.stackSize == var4) && (var6 == null || var6.getMaxItemUseDuration() <= 0)) 312 { 313 return false; 314 } 315 else 316 { 317 par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = var6; 318 319 if (this.isCreative()) 320 { 321 var6.stackSize = var4; 322 var6.setItemDamage(var5); 323 } 324 325 if (var6.stackSize == 0) 326 { 327 par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = null; 328 MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(thisPlayerMP, var6)); 329 } 330 331 return true; 332 } 333 } 334 335 /** 336 * Activate the clicked on block, otherwise use the held item. Args: player, world, itemStack, x, y, z, side, 337 * xOffset, yOffset, zOffset 338 */ 339 public boolean activateBlockOrUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack, int par4, int par5, int par6, int par7, float par8, float par9, float par10) 340 { 341 if (par3ItemStack != null && 342 par3ItemStack.getItem() != null && 343 par3ItemStack.getItem().onItemUseFirst(par3ItemStack, par1EntityPlayer, par2World, par4, par5, par6, par7, par8, par9, par10)) 344 { 345 return true; 346 } 347 int var11 = par2World.getBlockId(par4, par5, par6); 348 349 if (var11 > 0 && Block.blocksList[var11].onBlockActivated(par2World, par4, par5, par6, par1EntityPlayer, par7, par8, par9, par10)) 350 { 351 return true; 352 } 353 else if (par3ItemStack == null) 354 { 355 return false; 356 } 357 else if (this.isCreative()) 358 { 359 int var12 = par3ItemStack.getItemDamage(); 360 int var13 = par3ItemStack.stackSize; 361 boolean var14 = par3ItemStack.tryPlaceItemIntoWorld(par1EntityPlayer, par2World, par4, par5, par6, par7, par8, par9, par10); 362 par3ItemStack.setItemDamage(var12); 363 par3ItemStack.stackSize = var13; 364 return var14; 365 } 366 else 367 { 368 if (!par3ItemStack.tryPlaceItemIntoWorld(par1EntityPlayer, par2World, par4, par5, par6, par7, par8, par9, par10)) 369 { 370 return false; 371 } 372 if (par3ItemStack.stackSize <= 0) 373 { 374 MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(thisPlayerMP, par3ItemStack)); 375 } 376 return true; 377 } 378 } 379 380 /** 381 * Sets the world instance. 382 */ 383 public void setWorld(WorldServer par1WorldServer) 384 { 385 this.theWorld = par1WorldServer; 386 } 387 388 public double getBlockReachDistance() 389 { 390 return blockReachDistance; 391 } 392 public void setBlockReachDistance(double distance) 393 { 394 blockReachDistance = distance; 395 } 396 }