001package net.minecraft.entity; 002 003import java.util.HashSet; 004import java.util.Iterator; 005import java.util.List; 006import java.util.Set; 007 008import cpw.mods.fml.common.network.FMLNetworkHandler; 009import net.minecraft.entity.boss.EntityDragon; 010import net.minecraft.entity.item.EntityBoat; 011import net.minecraft.entity.item.EntityEnderCrystal; 012import net.minecraft.entity.item.EntityEnderEye; 013import net.minecraft.entity.item.EntityEnderPearl; 014import net.minecraft.entity.item.EntityExpBottle; 015import net.minecraft.entity.item.EntityFallingSand; 016import net.minecraft.entity.item.EntityFireworkRocket; 017import net.minecraft.entity.item.EntityItem; 018import net.minecraft.entity.item.EntityItemFrame; 019import net.minecraft.entity.item.EntityMinecart; 020import net.minecraft.entity.item.EntityPainting; 021import net.minecraft.entity.item.EntityTNTPrimed; 022import net.minecraft.entity.item.EntityXPOrb; 023import net.minecraft.entity.passive.IAnimals; 024import net.minecraft.entity.player.EntityPlayer; 025import net.minecraft.entity.player.EntityPlayerMP; 026import net.minecraft.entity.projectile.EntityArrow; 027import net.minecraft.entity.projectile.EntityEgg; 028import net.minecraft.entity.projectile.EntityFireball; 029import net.minecraft.entity.projectile.EntityFishHook; 030import net.minecraft.entity.projectile.EntityPotion; 031import net.minecraft.entity.projectile.EntitySmallFireball; 032import net.minecraft.entity.projectile.EntitySnowball; 033import net.minecraft.entity.projectile.EntityWitherSkull; 034import net.minecraft.item.Item; 035import net.minecraft.item.ItemMap; 036import net.minecraft.item.ItemStack; 037import net.minecraft.network.packet.Packet; 038import net.minecraft.network.packet.Packet17Sleep; 039import net.minecraft.network.packet.Packet20NamedEntitySpawn; 040import net.minecraft.network.packet.Packet23VehicleSpawn; 041import net.minecraft.network.packet.Packet24MobSpawn; 042import net.minecraft.network.packet.Packet25EntityPainting; 043import net.minecraft.network.packet.Packet26EntityExpOrb; 044import net.minecraft.network.packet.Packet28EntityVelocity; 045import net.minecraft.network.packet.Packet31RelEntityMove; 046import net.minecraft.network.packet.Packet32EntityLook; 047import net.minecraft.network.packet.Packet33RelEntityMoveLook; 048import net.minecraft.network.packet.Packet34EntityTeleport; 049import net.minecraft.network.packet.Packet35EntityHeadRotation; 050import net.minecraft.network.packet.Packet39AttachEntity; 051import net.minecraft.network.packet.Packet40EntityMetadata; 052import net.minecraft.network.packet.Packet41EntityEffect; 053import net.minecraft.network.packet.Packet5PlayerInventory; 054import net.minecraft.potion.PotionEffect; 055import net.minecraft.util.MathHelper; 056import net.minecraft.world.storage.MapData; 057 058public class EntityTrackerEntry 059{ 060 public Entity myEntity; 061 public int blocksDistanceThreshold; 062 063 /** check for sync when ticks % updateFrequency==0 */ 064 public int updateFrequency; 065 public int lastScaledXPosition; 066 public int lastScaledYPosition; 067 public int lastScaledZPosition; 068 public int lastYaw; 069 public int lastPitch; 070 public int lastHeadMotion; 071 public double motionX; 072 public double motionY; 073 public double motionZ; 074 public int ticks = 0; 075 private double posX; 076 private double posY; 077 private double posZ; 078 079 /** set to true on first sendLocationToClients */ 080 private boolean isDataInitialized = false; 081 private boolean sendVelocityUpdates; 082 083 /** 084 * every 400 ticks a full teleport packet is sent, rather than just a "move me +x" command, so that position 085 * remains fully synced. 086 */ 087 private int ticksSinceLastForcedTeleport = 0; 088 private Entity field_85178_v; 089 private boolean ridingEntity = false; 090 public boolean playerEntitiesUpdated = false; 091 092 /** 093 * Holds references to all the players that are currently receiving position updates for this entity. 094 */ 095 public Set trackingPlayers = new HashSet(); 096 097 public EntityTrackerEntry(Entity par1Entity, int par2, int par3, boolean par4) 098 { 099 this.myEntity = par1Entity; 100 this.blocksDistanceThreshold = par2; 101 this.updateFrequency = par3; 102 this.sendVelocityUpdates = par4; 103 this.lastScaledXPosition = MathHelper.floor_double(par1Entity.posX * 32.0D); 104 this.lastScaledYPosition = MathHelper.floor_double(par1Entity.posY * 32.0D); 105 this.lastScaledZPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D); 106 this.lastYaw = MathHelper.floor_float(par1Entity.rotationYaw * 256.0F / 360.0F); 107 this.lastPitch = MathHelper.floor_float(par1Entity.rotationPitch * 256.0F / 360.0F); 108 this.lastHeadMotion = MathHelper.floor_float(par1Entity.getRotationYawHead() * 256.0F / 360.0F); 109 } 110 111 public boolean equals(Object par1Obj) 112 { 113 return par1Obj instanceof EntityTrackerEntry ? ((EntityTrackerEntry)par1Obj).myEntity.entityId == this.myEntity.entityId : false; 114 } 115 116 public int hashCode() 117 { 118 return this.myEntity.entityId; 119 } 120 121 /** 122 * also sends velocity, rotation, and riding info. 123 */ 124 public void sendLocationToAllClients(List par1List) 125 { 126 this.playerEntitiesUpdated = false; 127 128 if (!this.isDataInitialized || this.myEntity.getDistanceSq(this.posX, this.posY, this.posZ) > 16.0D) 129 { 130 this.posX = this.myEntity.posX; 131 this.posY = this.myEntity.posY; 132 this.posZ = this.myEntity.posZ; 133 this.isDataInitialized = true; 134 this.playerEntitiesUpdated = true; 135 this.sendEventsToPlayers(par1List); 136 } 137 138 if (this.field_85178_v != this.myEntity.ridingEntity || this.myEntity.ridingEntity != null && this.ticks % 60 == 0) 139 { 140 this.field_85178_v = this.myEntity.ridingEntity; 141 this.sendPacketToAllTrackingPlayers(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity)); 142 } 143 144 if (this.myEntity instanceof EntityItemFrame && this.ticks % 10 == 0) 145 { 146 EntityItemFrame entityitemframe = (EntityItemFrame)this.myEntity; 147 ItemStack itemstack = entityitemframe.getDisplayedItem(); 148 149 if (itemstack != null && itemstack.getItem() instanceof ItemMap) 150 { 151 MapData mapdata = Item.map.getMapData(itemstack, this.myEntity.worldObj); 152 Iterator iterator = par1List.iterator(); 153 154 while (iterator.hasNext()) 155 { 156 EntityPlayer entityplayer = (EntityPlayer)iterator.next(); 157 EntityPlayerMP entityplayermp = (EntityPlayerMP)entityplayer; 158 mapdata.updateVisiblePlayers(entityplayermp, itemstack); 159 160 if (entityplayermp.playerNetServerHandler.packetSize() <= 5) 161 { 162 Packet packet = Item.map.createMapDataPacket(itemstack, this.myEntity.worldObj, entityplayermp); 163 164 if (packet != null) 165 { 166 entityplayermp.playerNetServerHandler.sendPacketToPlayer(packet); 167 } 168 } 169 } 170 } 171 172 DataWatcher datawatcher = this.myEntity.getDataWatcher(); 173 174 if (datawatcher.hasChanges()) 175 { 176 this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, datawatcher, false)); 177 } 178 } 179 else if (this.ticks % this.updateFrequency == 0 || this.myEntity.isAirBorne || this.myEntity.getDataWatcher().hasChanges()) 180 { 181 int i; 182 int j; 183 184 if (this.myEntity.ridingEntity == null) 185 { 186 ++this.ticksSinceLastForcedTeleport; 187 i = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX); 188 j = MathHelper.floor_double(this.myEntity.posY * 32.0D); 189 int k = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ); 190 int l = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F); 191 int i1 = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F); 192 int j1 = i - this.lastScaledXPosition; 193 int k1 = j - this.lastScaledYPosition; 194 int l1 = k - this.lastScaledZPosition; 195 Object object = null; 196 boolean flag = Math.abs(j1) >= 4 || Math.abs(k1) >= 4 || Math.abs(l1) >= 4 || this.ticks % 60 == 0; 197 boolean flag1 = Math.abs(l - this.lastYaw) >= 4 || Math.abs(i1 - this.lastPitch) >= 4; 198 199 if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.ticksSinceLastForcedTeleport <= 400 && !this.ridingEntity) 200 { 201 if (flag && flag1) 202 { 203 object = new Packet33RelEntityMoveLook(this.myEntity.entityId, (byte)j1, (byte)k1, (byte)l1, (byte)l, (byte)i1); 204 } 205 else if (flag) 206 { 207 object = new Packet31RelEntityMove(this.myEntity.entityId, (byte)j1, (byte)k1, (byte)l1); 208 } 209 else if (flag1) 210 { 211 object = new Packet32EntityLook(this.myEntity.entityId, (byte)l, (byte)i1); 212 } 213 } 214 else 215 { 216 this.ticksSinceLastForcedTeleport = 0; 217 object = new Packet34EntityTeleport(this.myEntity.entityId, i, j, k, (byte)l, (byte)i1); 218 } 219 220 if (this.sendVelocityUpdates) 221 { 222 double d0 = this.myEntity.motionX - this.motionX; 223 double d1 = this.myEntity.motionY - this.motionY; 224 double d2 = this.myEntity.motionZ - this.motionZ; 225 double d3 = 0.02D; 226 double d4 = d0 * d0 + d1 * d1 + d2 * d2; 227 228 if (d4 > d3 * d3 || d4 > 0.0D && this.myEntity.motionX == 0.0D && this.myEntity.motionY == 0.0D && this.myEntity.motionZ == 0.0D) 229 { 230 this.motionX = this.myEntity.motionX; 231 this.motionY = this.myEntity.motionY; 232 this.motionZ = this.myEntity.motionZ; 233 this.sendPacketToAllTrackingPlayers(new Packet28EntityVelocity(this.myEntity.entityId, this.motionX, this.motionY, this.motionZ)); 234 } 235 } 236 237 if (object != null) 238 { 239 this.sendPacketToAllTrackingPlayers((Packet)object); 240 } 241 242 DataWatcher datawatcher1 = this.myEntity.getDataWatcher(); 243 244 if (datawatcher1.hasChanges()) 245 { 246 this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, datawatcher1, false)); 247 } 248 249 if (flag) 250 { 251 this.lastScaledXPosition = i; 252 this.lastScaledYPosition = j; 253 this.lastScaledZPosition = k; 254 } 255 256 if (flag1) 257 { 258 this.lastYaw = l; 259 this.lastPitch = i1; 260 } 261 262 this.ridingEntity = false; 263 } 264 else 265 { 266 i = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F); 267 j = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F); 268 boolean flag2 = Math.abs(i - this.lastYaw) >= 4 || Math.abs(j - this.lastPitch) >= 4; 269 270 if (flag2) 271 { 272 this.sendPacketToAllTrackingPlayers(new Packet32EntityLook(this.myEntity.entityId, (byte)i, (byte)j)); 273 this.lastYaw = i; 274 this.lastPitch = j; 275 } 276 277 this.lastScaledXPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX); 278 this.lastScaledYPosition = MathHelper.floor_double(this.myEntity.posY * 32.0D); 279 this.lastScaledZPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ); 280 DataWatcher datawatcher2 = this.myEntity.getDataWatcher(); 281 282 if (datawatcher2.hasChanges()) 283 { 284 this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, datawatcher2, false)); 285 } 286 287 this.ridingEntity = true; 288 } 289 290 i = MathHelper.floor_float(this.myEntity.getRotationYawHead() * 256.0F / 360.0F); 291 292 if (Math.abs(i - this.lastHeadMotion) >= 4) 293 { 294 this.sendPacketToAllTrackingPlayers(new Packet35EntityHeadRotation(this.myEntity.entityId, (byte)i)); 295 this.lastHeadMotion = i; 296 } 297 298 this.myEntity.isAirBorne = false; 299 } 300 301 ++this.ticks; 302 303 if (this.myEntity.velocityChanged) 304 { 305 this.sendPacketToAllAssociatedPlayers(new Packet28EntityVelocity(this.myEntity)); 306 this.myEntity.velocityChanged = false; 307 } 308 } 309 310 /** 311 * if this is a player, then it is not informed 312 */ 313 public void sendPacketToAllTrackingPlayers(Packet par1Packet) 314 { 315 Iterator iterator = this.trackingPlayers.iterator(); 316 317 while (iterator.hasNext()) 318 { 319 EntityPlayerMP entityplayermp = (EntityPlayerMP)iterator.next(); 320 entityplayermp.playerNetServerHandler.sendPacketToPlayer(par1Packet); 321 } 322 } 323 324 /** 325 * if this is a player, then it recieves the message also 326 */ 327 public void sendPacketToAllAssociatedPlayers(Packet par1Packet) 328 { 329 this.sendPacketToAllTrackingPlayers(par1Packet); 330 331 if (this.myEntity instanceof EntityPlayerMP) 332 { 333 ((EntityPlayerMP)this.myEntity).playerNetServerHandler.sendPacketToPlayer(par1Packet); 334 } 335 } 336 337 public void informAllAssociatedPlayersOfItemDestruction() 338 { 339 Iterator iterator = this.trackingPlayers.iterator(); 340 341 while (iterator.hasNext()) 342 { 343 EntityPlayerMP entityplayermp = (EntityPlayerMP)iterator.next(); 344 entityplayermp.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 345 } 346 } 347 348 public void removeFromWatchingList(EntityPlayerMP par1EntityPlayerMP) 349 { 350 if (this.trackingPlayers.contains(par1EntityPlayerMP)) 351 { 352 par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 353 this.trackingPlayers.remove(par1EntityPlayerMP); 354 } 355 } 356 357 /** 358 * if the player is more than the distance threshold (typically 64) then the player is removed instead 359 */ 360 public void tryStartWachingThis(EntityPlayerMP par1EntityPlayerMP) 361 { 362 if (par1EntityPlayerMP != this.myEntity) 363 { 364 double d0 = par1EntityPlayerMP.posX - (double)(this.lastScaledXPosition / 32); 365 double d1 = par1EntityPlayerMP.posZ - (double)(this.lastScaledZPosition / 32); 366 367 if (d0 >= (double)(-this.blocksDistanceThreshold) && d0 <= (double)this.blocksDistanceThreshold && d1 >= (double)(-this.blocksDistanceThreshold) && d1 <= (double)this.blocksDistanceThreshold) 368 { 369 if (!this.trackingPlayers.contains(par1EntityPlayerMP) && (this.isPlayerWatchingThisChunk(par1EntityPlayerMP) || this.myEntity.field_98038_p)) 370 { 371 this.trackingPlayers.add(par1EntityPlayerMP); 372 Packet packet = this.getPacketForThisEntity(); 373 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(packet); 374 375 if (!this.myEntity.getDataWatcher().getIsBlank()) 376 { 377 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet40EntityMetadata(this.myEntity.entityId, this.myEntity.getDataWatcher(), true)); 378 } 379 380 this.motionX = this.myEntity.motionX; 381 this.motionY = this.myEntity.motionY; 382 this.motionZ = this.myEntity.motionZ; 383 384 int posX = MathHelper.floor_double(this.myEntity.posX * 32.0D); 385 int posY = MathHelper.floor_double(this.myEntity.posY * 32.0D); 386 int posZ = MathHelper.floor_double(this.myEntity.posZ * 32.0D); 387 if (posX != this.lastScaledXPosition || posY != this.lastScaledYPosition || posZ != this.lastScaledZPosition) 388 { 389 FMLNetworkHandler.makeEntitySpawnAdjustment(this.myEntity.entityId, par1EntityPlayerMP, this.lastScaledXPosition, this.lastScaledYPosition, this.lastScaledZPosition); 390 } 391 392 if (this.sendVelocityUpdates && !(packet instanceof Packet24MobSpawn)) 393 { 394 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet28EntityVelocity(this.myEntity.entityId, this.myEntity.motionX, this.myEntity.motionY, this.myEntity.motionZ)); 395 } 396 397 if (this.myEntity.ridingEntity != null) 398 { 399 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity)); 400 } 401 402 if (this.myEntity instanceof EntityLiving) 403 { 404 for (int i = 0; i < 5; ++i) 405 { 406 ItemStack itemstack = ((EntityLiving)this.myEntity).getCurrentItemOrArmor(i); 407 408 if (itemstack != null) 409 { 410 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet5PlayerInventory(this.myEntity.entityId, i, itemstack)); 411 } 412 } 413 } 414 415 if (this.myEntity instanceof EntityPlayer) 416 { 417 EntityPlayer entityplayer = (EntityPlayer)this.myEntity; 418 419 if (entityplayer.isPlayerSleeping()) 420 { 421 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet17Sleep(this.myEntity, 0, MathHelper.floor_double(this.myEntity.posX), MathHelper.floor_double(this.myEntity.posY), MathHelper.floor_double(this.myEntity.posZ))); 422 } 423 } 424 425 if (this.myEntity instanceof EntityLiving) 426 { 427 EntityLiving entityliving = (EntityLiving)this.myEntity; 428 Iterator iterator = entityliving.getActivePotionEffects().iterator(); 429 430 while (iterator.hasNext()) 431 { 432 PotionEffect potioneffect = (PotionEffect)iterator.next(); 433 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(this.myEntity.entityId, potioneffect)); 434 } 435 } 436 } 437 } 438 else if (this.trackingPlayers.contains(par1EntityPlayerMP)) 439 { 440 this.trackingPlayers.remove(par1EntityPlayerMP); 441 par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 442 } 443 } 444 } 445 446 private boolean isPlayerWatchingThisChunk(EntityPlayerMP par1EntityPlayerMP) 447 { 448 return par1EntityPlayerMP.getServerForPlayer().getPlayerManager().isPlayerWatchingChunk(par1EntityPlayerMP, this.myEntity.chunkCoordX, this.myEntity.chunkCoordZ); 449 } 450 451 public void sendEventsToPlayers(List par1List) 452 { 453 for (int i = 0; i < par1List.size(); ++i) 454 { 455 this.tryStartWachingThis((EntityPlayerMP)par1List.get(i)); 456 } 457 } 458 459 private Packet getPacketForThisEntity() 460 { 461 if (this.myEntity.isDead) 462 { 463 this.myEntity.worldObj.func_98180_V().func_98236_b("Fetching addPacket for removed entity"); 464 } 465 466 Packet pkt = FMLNetworkHandler.getEntitySpawningPacket(this.myEntity); 467 468 if (pkt != null) 469 { 470 return pkt; 471 } 472 473 if (this.myEntity instanceof EntityItem) 474 { 475 return new Packet23VehicleSpawn(this.myEntity, 2, 1); 476 } 477 else if (this.myEntity instanceof EntityPlayerMP) 478 { 479 return new Packet20NamedEntitySpawn((EntityPlayer)this.myEntity); 480 } 481 else if (this.myEntity instanceof EntityMinecart) 482 { 483 EntityMinecart entityminecart = (EntityMinecart)this.myEntity; 484 return new Packet23VehicleSpawn(this.myEntity, 10, entityminecart.func_94087_l()); 485 } 486 else if (this.myEntity instanceof EntityBoat) 487 { 488 return new Packet23VehicleSpawn(this.myEntity, 1); 489 } 490 else if (!(this.myEntity instanceof IAnimals) && !(this.myEntity instanceof EntityDragon)) 491 { 492 if (this.myEntity instanceof EntityFishHook) 493 { 494 EntityPlayer entityplayer = ((EntityFishHook)this.myEntity).angler; 495 return new Packet23VehicleSpawn(this.myEntity, 90, entityplayer != null ? entityplayer.entityId : this.myEntity.entityId); 496 } 497 else if (this.myEntity instanceof EntityArrow) 498 { 499 Entity entity = ((EntityArrow)this.myEntity).shootingEntity; 500 return new Packet23VehicleSpawn(this.myEntity, 60, entity != null ? entity.entityId : this.myEntity.entityId); 501 } 502 else if (this.myEntity instanceof EntitySnowball) 503 { 504 return new Packet23VehicleSpawn(this.myEntity, 61); 505 } 506 else if (this.myEntity instanceof EntityPotion) 507 { 508 return new Packet23VehicleSpawn(this.myEntity, 73, ((EntityPotion)this.myEntity).getPotionDamage()); 509 } 510 else if (this.myEntity instanceof EntityExpBottle) 511 { 512 return new Packet23VehicleSpawn(this.myEntity, 75); 513 } 514 else if (this.myEntity instanceof EntityEnderPearl) 515 { 516 return new Packet23VehicleSpawn(this.myEntity, 65); 517 } 518 else if (this.myEntity instanceof EntityEnderEye) 519 { 520 return new Packet23VehicleSpawn(this.myEntity, 72); 521 } 522 else if (this.myEntity instanceof EntityFireworkRocket) 523 { 524 return new Packet23VehicleSpawn(this.myEntity, 76); 525 } 526 else 527 { 528 Packet23VehicleSpawn packet23vehiclespawn; 529 530 if (this.myEntity instanceof EntityFireball) 531 { 532 EntityFireball entityfireball = (EntityFireball)this.myEntity; 533 packet23vehiclespawn = null; 534 byte b0 = 63; 535 536 if (this.myEntity instanceof EntitySmallFireball) 537 { 538 b0 = 64; 539 } 540 else if (this.myEntity instanceof EntityWitherSkull) 541 { 542 b0 = 66; 543 } 544 545 if (entityfireball.shootingEntity != null) 546 { 547 packet23vehiclespawn = new Packet23VehicleSpawn(this.myEntity, b0, ((EntityFireball)this.myEntity).shootingEntity.entityId); 548 } 549 else 550 { 551 packet23vehiclespawn = new Packet23VehicleSpawn(this.myEntity, b0, 0); 552 } 553 554 packet23vehiclespawn.speedX = (int)(entityfireball.accelerationX * 8000.0D); 555 packet23vehiclespawn.speedY = (int)(entityfireball.accelerationY * 8000.0D); 556 packet23vehiclespawn.speedZ = (int)(entityfireball.accelerationZ * 8000.0D); 557 return packet23vehiclespawn; 558 } 559 else if (this.myEntity instanceof EntityEgg) 560 { 561 return new Packet23VehicleSpawn(this.myEntity, 62); 562 } 563 else if (this.myEntity instanceof EntityTNTPrimed) 564 { 565 return new Packet23VehicleSpawn(this.myEntity, 50); 566 } 567 else if (this.myEntity instanceof EntityEnderCrystal) 568 { 569 return new Packet23VehicleSpawn(this.myEntity, 51); 570 } 571 else if (this.myEntity instanceof EntityFallingSand) 572 { 573 EntityFallingSand entityfallingsand = (EntityFallingSand)this.myEntity; 574 return new Packet23VehicleSpawn(this.myEntity, 70, entityfallingsand.blockID | entityfallingsand.metadata << 16); 575 } 576 else if (this.myEntity instanceof EntityPainting) 577 { 578 return new Packet25EntityPainting((EntityPainting)this.myEntity); 579 } 580 else if (this.myEntity instanceof EntityItemFrame) 581 { 582 EntityItemFrame entityitemframe = (EntityItemFrame)this.myEntity; 583 packet23vehiclespawn = new Packet23VehicleSpawn(this.myEntity, 71, entityitemframe.hangingDirection); 584 packet23vehiclespawn.xPosition = MathHelper.floor_float((float)(entityitemframe.xPosition * 32)); 585 packet23vehiclespawn.yPosition = MathHelper.floor_float((float)(entityitemframe.yPosition * 32)); 586 packet23vehiclespawn.zPosition = MathHelper.floor_float((float)(entityitemframe.zPosition * 32)); 587 return packet23vehiclespawn; 588 } 589 else if (this.myEntity instanceof EntityXPOrb) 590 { 591 return new Packet26EntityExpOrb((EntityXPOrb)this.myEntity); 592 } 593 else 594 { 595 throw new IllegalArgumentException("Don\'t know how to add " + this.myEntity.getClass() + "!"); 596 } 597 } 598 } 599 else 600 { 601 this.lastHeadMotion = MathHelper.floor_float(this.myEntity.getRotationYawHead() * 256.0F / 360.0F); 602 return new Packet24MobSpawn((EntityLiving)this.myEntity); 603 } 604 } 605 606 public void removePlayerFromTracker(EntityPlayerMP par1EntityPlayerMP) 607 { 608 if (this.trackingPlayers.contains(par1EntityPlayerMP)) 609 { 610 this.trackingPlayers.remove(par1EntityPlayerMP); 611 par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 612 } 613 } 614}