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