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 (this.ticks > 0) 200 { 201 if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.ticksSinceLastForcedTeleport <= 400 && !this.ridingEntity) 202 { 203 if (flag && flag1) 204 { 205 object = new Packet33RelEntityMoveLook(this.myEntity.entityId, (byte)j1, (byte)k1, (byte)l1, (byte)l, (byte)i1); 206 } 207 else if (flag) 208 { 209 object = new Packet31RelEntityMove(this.myEntity.entityId, (byte)j1, (byte)k1, (byte)l1); 210 } 211 else if (flag1) 212 { 213 object = new Packet32EntityLook(this.myEntity.entityId, (byte)l, (byte)i1); 214 } 215 } 216 else 217 { 218 this.ticksSinceLastForcedTeleport = 0; 219 object = new Packet34EntityTeleport(this.myEntity.entityId, i, j, k, (byte)l, (byte)i1); 220 } 221 } 222 223 if (this.sendVelocityUpdates) 224 { 225 double d0 = this.myEntity.motionX - this.motionX; 226 double d1 = this.myEntity.motionY - this.motionY; 227 double d2 = this.myEntity.motionZ - this.motionZ; 228 double d3 = 0.02D; 229 double d4 = d0 * d0 + d1 * d1 + d2 * d2; 230 231 if (d4 > d3 * d3 || d4 > 0.0D && this.myEntity.motionX == 0.0D && this.myEntity.motionY == 0.0D && this.myEntity.motionZ == 0.0D) 232 { 233 this.motionX = this.myEntity.motionX; 234 this.motionY = this.myEntity.motionY; 235 this.motionZ = this.myEntity.motionZ; 236 this.sendPacketToAllTrackingPlayers(new Packet28EntityVelocity(this.myEntity.entityId, this.motionX, this.motionY, this.motionZ)); 237 } 238 } 239 240 if (object != null) 241 { 242 this.sendPacketToAllTrackingPlayers((Packet)object); 243 } 244 245 DataWatcher datawatcher1 = this.myEntity.getDataWatcher(); 246 247 if (datawatcher1.hasChanges()) 248 { 249 this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, datawatcher1, false)); 250 } 251 252 if (flag) 253 { 254 this.lastScaledXPosition = i; 255 this.lastScaledYPosition = j; 256 this.lastScaledZPosition = k; 257 } 258 259 if (flag1) 260 { 261 this.lastYaw = l; 262 this.lastPitch = i1; 263 } 264 265 this.ridingEntity = false; 266 } 267 else 268 { 269 i = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F); 270 j = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F); 271 boolean flag2 = Math.abs(i - this.lastYaw) >= 4 || Math.abs(j - this.lastPitch) >= 4; 272 273 if (flag2) 274 { 275 this.sendPacketToAllTrackingPlayers(new Packet32EntityLook(this.myEntity.entityId, (byte)i, (byte)j)); 276 this.lastYaw = i; 277 this.lastPitch = j; 278 } 279 280 this.lastScaledXPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX); 281 this.lastScaledYPosition = MathHelper.floor_double(this.myEntity.posY * 32.0D); 282 this.lastScaledZPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ); 283 DataWatcher datawatcher2 = this.myEntity.getDataWatcher(); 284 285 if (datawatcher2.hasChanges()) 286 { 287 this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, datawatcher2, false)); 288 } 289 290 this.ridingEntity = true; 291 } 292 293 i = MathHelper.floor_float(this.myEntity.getRotationYawHead() * 256.0F / 360.0F); 294 295 if (Math.abs(i - this.lastHeadMotion) >= 4) 296 { 297 this.sendPacketToAllTrackingPlayers(new Packet35EntityHeadRotation(this.myEntity.entityId, (byte)i)); 298 this.lastHeadMotion = i; 299 } 300 301 this.myEntity.isAirBorne = false; 302 } 303 304 ++this.ticks; 305 306 if (this.myEntity.velocityChanged) 307 { 308 this.sendPacketToAllAssociatedPlayers(new Packet28EntityVelocity(this.myEntity)); 309 this.myEntity.velocityChanged = false; 310 } 311 } 312 313 /** 314 * if this is a player, then it is not informed 315 */ 316 public void sendPacketToAllTrackingPlayers(Packet par1Packet) 317 { 318 Iterator iterator = this.trackingPlayers.iterator(); 319 320 while (iterator.hasNext()) 321 { 322 EntityPlayerMP entityplayermp = (EntityPlayerMP)iterator.next(); 323 entityplayermp.playerNetServerHandler.sendPacketToPlayer(par1Packet); 324 } 325 } 326 327 /** 328 * if this is a player, then it recieves the message also 329 */ 330 public void sendPacketToAllAssociatedPlayers(Packet par1Packet) 331 { 332 this.sendPacketToAllTrackingPlayers(par1Packet); 333 334 if (this.myEntity instanceof EntityPlayerMP) 335 { 336 ((EntityPlayerMP)this.myEntity).playerNetServerHandler.sendPacketToPlayer(par1Packet); 337 } 338 } 339 340 public void informAllAssociatedPlayersOfItemDestruction() 341 { 342 Iterator iterator = this.trackingPlayers.iterator(); 343 344 while (iterator.hasNext()) 345 { 346 EntityPlayerMP entityplayermp = (EntityPlayerMP)iterator.next(); 347 entityplayermp.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 348 } 349 } 350 351 public void removeFromWatchingList(EntityPlayerMP par1EntityPlayerMP) 352 { 353 if (this.trackingPlayers.contains(par1EntityPlayerMP)) 354 { 355 par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 356 this.trackingPlayers.remove(par1EntityPlayerMP); 357 } 358 } 359 360 /** 361 * if the player is more than the distance threshold (typically 64) then the player is removed instead 362 */ 363 public void tryStartWachingThis(EntityPlayerMP par1EntityPlayerMP) 364 { 365 if (par1EntityPlayerMP != this.myEntity) 366 { 367 double d0 = par1EntityPlayerMP.posX - (double)(this.lastScaledXPosition / 32); 368 double d1 = par1EntityPlayerMP.posZ - (double)(this.lastScaledZPosition / 32); 369 370 if (d0 >= (double)(-this.blocksDistanceThreshold) && d0 <= (double)this.blocksDistanceThreshold && d1 >= (double)(-this.blocksDistanceThreshold) && d1 <= (double)this.blocksDistanceThreshold) 371 { 372 if (!this.trackingPlayers.contains(par1EntityPlayerMP) && (this.isPlayerWatchingThisChunk(par1EntityPlayerMP) || this.myEntity.field_98038_p)) 373 { 374 this.trackingPlayers.add(par1EntityPlayerMP); 375 Packet packet = this.getPacketForThisEntity(); 376 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(packet); 377 378 if (!this.myEntity.getDataWatcher().getIsBlank()) 379 { 380 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet40EntityMetadata(this.myEntity.entityId, this.myEntity.getDataWatcher(), true)); 381 } 382 383 this.motionX = this.myEntity.motionX; 384 this.motionY = this.myEntity.motionY; 385 this.motionZ = this.myEntity.motionZ; 386 387 int posX = MathHelper.floor_double(this.myEntity.posX * 32.0D); 388 int posY = MathHelper.floor_double(this.myEntity.posY * 32.0D); 389 int posZ = MathHelper.floor_double(this.myEntity.posZ * 32.0D); 390 if (posX != this.lastScaledXPosition || posY != this.lastScaledYPosition || posZ != this.lastScaledZPosition) 391 { 392 FMLNetworkHandler.makeEntitySpawnAdjustment(this.myEntity.entityId, par1EntityPlayerMP, this.lastScaledXPosition, this.lastScaledYPosition, this.lastScaledZPosition); 393 } 394 395 if (this.sendVelocityUpdates && !(packet instanceof Packet24MobSpawn)) 396 { 397 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet28EntityVelocity(this.myEntity.entityId, this.myEntity.motionX, this.myEntity.motionY, this.myEntity.motionZ)); 398 } 399 400 if (this.myEntity.ridingEntity != null) 401 { 402 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity)); 403 } 404 405 if (this.myEntity instanceof EntityLiving) 406 { 407 for (int i = 0; i < 5; ++i) 408 { 409 ItemStack itemstack = ((EntityLiving)this.myEntity).getCurrentItemOrArmor(i); 410 411 if (itemstack != null) 412 { 413 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet5PlayerInventory(this.myEntity.entityId, i, itemstack)); 414 } 415 } 416 } 417 418 if (this.myEntity instanceof EntityPlayer) 419 { 420 EntityPlayer entityplayer = (EntityPlayer)this.myEntity; 421 422 if (entityplayer.isPlayerSleeping()) 423 { 424 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))); 425 } 426 } 427 428 if (this.myEntity instanceof EntityLiving) 429 { 430 EntityLiving entityliving = (EntityLiving)this.myEntity; 431 Iterator iterator = entityliving.getActivePotionEffects().iterator(); 432 433 while (iterator.hasNext()) 434 { 435 PotionEffect potioneffect = (PotionEffect)iterator.next(); 436 par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(this.myEntity.entityId, potioneffect)); 437 } 438 } 439 } 440 } 441 else if (this.trackingPlayers.contains(par1EntityPlayerMP)) 442 { 443 this.trackingPlayers.remove(par1EntityPlayerMP); 444 par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 445 } 446 } 447 } 448 449 private boolean isPlayerWatchingThisChunk(EntityPlayerMP par1EntityPlayerMP) 450 { 451 return par1EntityPlayerMP.getServerForPlayer().getPlayerManager().isPlayerWatchingChunk(par1EntityPlayerMP, this.myEntity.chunkCoordX, this.myEntity.chunkCoordZ); 452 } 453 454 public void sendEventsToPlayers(List par1List) 455 { 456 for (int i = 0; i < par1List.size(); ++i) 457 { 458 this.tryStartWachingThis((EntityPlayerMP)par1List.get(i)); 459 } 460 } 461 462 private Packet getPacketForThisEntity() 463 { 464 if (this.myEntity.isDead) 465 { 466 this.myEntity.worldObj.getWorldLogAgent().logWarning("Fetching addPacket for removed entity"); 467 } 468 469 Packet pkt = FMLNetworkHandler.getEntitySpawningPacket(this.myEntity); 470 471 if (pkt != null) 472 { 473 return pkt; 474 } 475 476 if (this.myEntity instanceof EntityItem) 477 { 478 return new Packet23VehicleSpawn(this.myEntity, 2, 1); 479 } 480 else if (this.myEntity instanceof EntityPlayerMP) 481 { 482 return new Packet20NamedEntitySpawn((EntityPlayer)this.myEntity); 483 } 484 else if (this.myEntity instanceof EntityMinecart) 485 { 486 EntityMinecart entityminecart = (EntityMinecart)this.myEntity; 487 return new Packet23VehicleSpawn(this.myEntity, 10, entityminecart.getMinecartType()); 488 } 489 else if (this.myEntity instanceof EntityBoat) 490 { 491 return new Packet23VehicleSpawn(this.myEntity, 1); 492 } 493 else if (!(this.myEntity instanceof IAnimals) && !(this.myEntity instanceof EntityDragon)) 494 { 495 if (this.myEntity instanceof EntityFishHook) 496 { 497 EntityPlayer entityplayer = ((EntityFishHook)this.myEntity).angler; 498 return new Packet23VehicleSpawn(this.myEntity, 90, entityplayer != null ? entityplayer.entityId : this.myEntity.entityId); 499 } 500 else if (this.myEntity instanceof EntityArrow) 501 { 502 Entity entity = ((EntityArrow)this.myEntity).shootingEntity; 503 return new Packet23VehicleSpawn(this.myEntity, 60, entity != null ? entity.entityId : this.myEntity.entityId); 504 } 505 else if (this.myEntity instanceof EntitySnowball) 506 { 507 return new Packet23VehicleSpawn(this.myEntity, 61); 508 } 509 else if (this.myEntity instanceof EntityPotion) 510 { 511 return new Packet23VehicleSpawn(this.myEntity, 73, ((EntityPotion)this.myEntity).getPotionDamage()); 512 } 513 else if (this.myEntity instanceof EntityExpBottle) 514 { 515 return new Packet23VehicleSpawn(this.myEntity, 75); 516 } 517 else if (this.myEntity instanceof EntityEnderPearl) 518 { 519 return new Packet23VehicleSpawn(this.myEntity, 65); 520 } 521 else if (this.myEntity instanceof EntityEnderEye) 522 { 523 return new Packet23VehicleSpawn(this.myEntity, 72); 524 } 525 else if (this.myEntity instanceof EntityFireworkRocket) 526 { 527 return new Packet23VehicleSpawn(this.myEntity, 76); 528 } 529 else 530 { 531 Packet23VehicleSpawn packet23vehiclespawn; 532 533 if (this.myEntity instanceof EntityFireball) 534 { 535 EntityFireball entityfireball = (EntityFireball)this.myEntity; 536 packet23vehiclespawn = null; 537 byte b0 = 63; 538 539 if (this.myEntity instanceof EntitySmallFireball) 540 { 541 b0 = 64; 542 } 543 else if (this.myEntity instanceof EntityWitherSkull) 544 { 545 b0 = 66; 546 } 547 548 if (entityfireball.shootingEntity != null) 549 { 550 packet23vehiclespawn = new Packet23VehicleSpawn(this.myEntity, b0, ((EntityFireball)this.myEntity).shootingEntity.entityId); 551 } 552 else 553 { 554 packet23vehiclespawn = new Packet23VehicleSpawn(this.myEntity, b0, 0); 555 } 556 557 packet23vehiclespawn.speedX = (int)(entityfireball.accelerationX * 8000.0D); 558 packet23vehiclespawn.speedY = (int)(entityfireball.accelerationY * 8000.0D); 559 packet23vehiclespawn.speedZ = (int)(entityfireball.accelerationZ * 8000.0D); 560 return packet23vehiclespawn; 561 } 562 else if (this.myEntity instanceof EntityEgg) 563 { 564 return new Packet23VehicleSpawn(this.myEntity, 62); 565 } 566 else if (this.myEntity instanceof EntityTNTPrimed) 567 { 568 return new Packet23VehicleSpawn(this.myEntity, 50); 569 } 570 else if (this.myEntity instanceof EntityEnderCrystal) 571 { 572 return new Packet23VehicleSpawn(this.myEntity, 51); 573 } 574 else if (this.myEntity instanceof EntityFallingSand) 575 { 576 EntityFallingSand entityfallingsand = (EntityFallingSand)this.myEntity; 577 return new Packet23VehicleSpawn(this.myEntity, 70, entityfallingsand.blockID | entityfallingsand.metadata << 16); 578 } 579 else if (this.myEntity instanceof EntityPainting) 580 { 581 return new Packet25EntityPainting((EntityPainting)this.myEntity); 582 } 583 else if (this.myEntity instanceof EntityItemFrame) 584 { 585 EntityItemFrame entityitemframe = (EntityItemFrame)this.myEntity; 586 packet23vehiclespawn = new Packet23VehicleSpawn(this.myEntity, 71, entityitemframe.hangingDirection); 587 packet23vehiclespawn.xPosition = MathHelper.floor_float((float)(entityitemframe.xPosition * 32)); 588 packet23vehiclespawn.yPosition = MathHelper.floor_float((float)(entityitemframe.yPosition * 32)); 589 packet23vehiclespawn.zPosition = MathHelper.floor_float((float)(entityitemframe.zPosition * 32)); 590 return packet23vehiclespawn; 591 } 592 else if (this.myEntity instanceof EntityXPOrb) 593 { 594 return new Packet26EntityExpOrb((EntityXPOrb)this.myEntity); 595 } 596 else 597 { 598 throw new IllegalArgumentException("Don\'t know how to add " + this.myEntity.getClass() + "!"); 599 } 600 } 601 } 602 else 603 { 604 this.lastHeadMotion = MathHelper.floor_float(this.myEntity.getRotationYawHead() * 256.0F / 360.0F); 605 return new Packet24MobSpawn((EntityLiving)this.myEntity); 606 } 607 } 608 609 public void removePlayerFromTracker(EntityPlayerMP par1EntityPlayerMP) 610 { 611 if (this.trackingPlayers.contains(par1EntityPlayerMP)) 612 { 613 this.trackingPlayers.remove(par1EntityPlayerMP); 614 par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId)); 615 } 616 } 617}