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