content: package net.minecraft.server;
  
  import com.google.common.collect.Sets;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  
  // CraftBukkit start
  import org.bukkit.entity.Player;
  import org.bukkit.event.player.PlayerVelocityEvent;
  // CraftBukkit end
  
  public class EntityTrackerEntry {
  
      private static final Logger c = LogManager.getLogger();
      private final Entity tracker;
      private final int e;
      private int f;
      private final int g;
      private long xLoc;
      private long yLoc;
      private long zLoc;
      private int yRot;
      private int xRot;
      private int headYaw;
      private double n;
      private double o;
      private double p;
      public int a;
      private double q;
      private double r;
      private double s;
      private boolean isMoving;
      private final boolean u;
      private int v;
      private List<Entity> w = Collections.emptyList();
      private boolean x;
      private boolean y;
      public boolean b;
      // Paper start
      // Replace trackedPlayers Set with a Map. The value is true until the player receives
      // their first update (which is forced to have absolute coordinates), false afterward.
      public java.util.Map<EntityPlayer, Boolean> trackedPlayerMap = new java.util.HashMap<EntityPlayer, Boolean>();
      public Set<EntityPlayer> trackedPlayers = trackedPlayerMap.keySet();
      // Paper end
  
      public EntityTrackerEntry(Entity entity, int i, int j, int k, boolean flag) {
          entity.tracker = this; // Paper
          this.tracker = entity;
          this.e = i;
          this.f = j;
          this.g = k;
          this.u = flag;
          this.xLoc = EntityTracker.a(entity.locX);
          this.yLoc = EntityTracker.a(entity.locY);
          this.zLoc = EntityTracker.a(entity.locZ);
          this.yRot = MathHelper.d(entity.yaw * 256.0F / 360.0F);
          this.xRot = MathHelper.d(entity.pitch * 256.0F / 360.0F);
          this.headYaw = MathHelper.d(entity.getHeadRotation() * 256.0F / 360.0F);
          this.y = entity.onGround;
      }
  
      public boolean equals(Object object) {
          return object instanceof EntityTrackerEntry ? ((EntityTrackerEntry) object).tracker.getId() == this.tracker.getId() : false;
      }
  
      public int hashCode() {
          return this.tracker.getId();
      }
  
      public void track(List<EntityHuman> list) {
          this.b = false;
          if (!this.isMoving || this.tracker.d(this.q, this.r, this.s) > 16.0D) {
              this.q = this.tracker.locX;
              this.r = this.tracker.locY;
              this.s = this.tracker.locZ;
              this.isMoving = true;
              this.b = true;
              this.scanPlayers(list);
          }
  
          List list1 = this.tracker.bF();
  
          if (!list1.equals(this.w)) {
              this.w = list1;
              this.broadcastIncludingSelf(new PacketPlayOutMount(this.tracker)); // CraftBukkit
          }
  
          // PAIL : rename
          if (this.tracker instanceof EntityItemFrame && this.a % 20 == 0) { // Paper
              EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker;
              ItemStack itemstack = entityitemframe.getItem();
  
              if (itemstack != null && itemstack.getItem() instanceof ItemWorldMap) { // Paper - moved back up
                  WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, this.tracker.world);
                  Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit
  
                  while (iterator.hasNext()) {
                      EntityHuman entityhuman = (EntityHuman) iterator.next();
                      EntityPlayer entityplayer = (EntityPlayer) entityhuman;
  
                      worldmap.a(entityplayer, itemstack);
                      Packet packet = Items.FILLED_MAP.a(itemstack, this.tracker.world, (EntityHuman) entityplayer);
  
                      if (packet != null) {
                          entityplayer.playerConnection.sendPacket(packet);
                      }
                  }
              }
  
              this.d();
          }
  
          if (this.a % this.g == 0 || this.tracker.impulse || this.tracker.getDataWatcher().a()) {
              int i;
  
              if (this.tracker.isPassenger()) {
                  i = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F);
                  int j = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F);
                  boolean flag = Math.abs(i - this.yRot) >= 1 || Math.abs(j - this.xRot) >= 1;
  
                  if (flag) {
                      this.broadcast(new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) i, (byte) j, this.tracker.onGround));
                      this.yRot = i;
                      this.xRot = j;
                  }
  
                  this.xLoc = EntityTracker.a(this.tracker.locX);
                  this.yLoc = EntityTracker.a(this.tracker.locY);
                  this.zLoc = EntityTracker.a(this.tracker.locZ);
                  this.d();
                  this.x = true;
              } else {
                  ++this.v;
                  long k = EntityTracker.a(this.tracker.locX);
                  long l = EntityTracker.a(this.tracker.locY);
                  long i1 = EntityTracker.a(this.tracker.locZ);
                  int j1 = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F);
                  int k1 = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F);
                  long l1 = k - this.xLoc;
                  long i2 = l - this.yLoc;
                  long j2 = i1 - this.zLoc;
                  Object object = null;
                  boolean flag1 = l1 * l1 + i2 * i2 + j2 * j2 >= 128L || this.a % 60 == 0;
                  boolean flag2 = Math.abs(j1 - this.yRot) >= 1 || Math.abs(k1 - this.xRot) >= 1;
  
                  if (this.a > 0 || this.tracker instanceof EntityArrow) { // Paper - Moved up
                  // CraftBukkit start - Code moved from below
                  if (flag1) {
                      this.xLoc = k;
                      this.yLoc = l;
                      this.zLoc = i1;
                  }
  
                  if (flag2) {
                      this.yRot = j1;
                      this.xRot = k1;
                  }
                  // CraftBukkit end
  
                      if (l1 >= -32768L && l1 < 32768L && i2 >= -32768L && i2 < 32768L && j2 >= -32768L && j2 < 32768L && this.v <= 400 && !this.x && this.y == this.tracker.onGround) {
                          if ((!flag1 || !flag2) && !(this.tracker instanceof EntityArrow)) {
                              if (flag1) {
                                  object = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(this.tracker.getId(), l1, i2, j2, this.tracker.onGround);
                              } else if (flag2) {
                                  object = new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) j1, (byte) k1, this.tracker.onGround);
                              }
                          } else {
                              object = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.tracker.getId(), l1, i2, j2, (byte) j1, (byte) k1, this.tracker.onGround);
                          }
                      } else {
                          this.y = this.tracker.onGround;
                          this.v = 0;
                          // CraftBukkit start - Refresh list of who can see a player before sending teleport packet
                          if (this.tracker instanceof EntityPlayer) {
                              this.scanPlayers(new java.util.ArrayList(this.trackedPlayers));
                          }
                          // CraftBukkit end
                          this.c();
                          object = new PacketPlayOutEntityTeleport(this.tracker);
                      }
                  }
  
                  boolean flag3 = this.u;
  
                  if (this.tracker instanceof EntityLiving && ((EntityLiving) this.tracker).cP()) {
                      flag3 = true;
                  }
  
                  if (flag3 && this.a > 0) {
                      double d0 = this.tracker.motX - this.n;
                      double d1 = this.tracker.motY - this.o;
                      double d2 = this.tracker.motZ - this.p;
                      double d3 = 0.02D;
                      double d4 = d0 * d0 + d1 * d1 + d2 * d2;
  
                      if (d4 > 4.0E-4D || d4 > 0.0D && this.tracker.motX == 0.0D && this.tracker.motY == 0.0D && this.tracker.motZ == 0.0D) {
                          this.n = this.tracker.motX;
                          this.o = this.tracker.motY;
                          this.p = this.tracker.motZ;
                          this.broadcast(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.n, this.o, this.p));
                      }
                  }
  
                  if (object != null) {
                      // Paper start - ensure fresh viewers get an absolute position on their first update,
                      // since we can't be certain what position they received in the spawn packet.
                      if (object instanceof PacketPlayOutEntityTeleport) {
                          this.broadcast((Packet) object);
                      } else {
                          PacketPlayOutEntityTeleport teleportPacket = null;
  
                          for (java.util.Map.Entry<EntityPlayer, Boolean> viewer : trackedPlayerMap.entrySet()) {
                              if (viewer.getValue()) {
                                  viewer.setValue(false);
                                  if (teleportPacket == null) {
                                      teleportPacket = new PacketPlayOutEntityTeleport(this.tracker);
                                  }
                                  viewer.getKey().playerConnection.sendPacket(teleportPacket);
                              } else {
                                  viewer.getKey().playerConnection.sendPacket((Packet) object);
                              }
                          }
                      }
                      // Paper end
                  }
  
                  this.d();
                  /* CraftBukkit start - Code moved up
                  if (flag1) {
                      this.xLoc = k;
                      this.yLoc = l;
                      this.zLoc = i1;
                  }
  
                  if (flag2) {
                      this.yRot = j1;
                      this.xRot = k1;
                  }
                  // CraftBukkit end */
  
                  this.x = false;
              }
  
              i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
              if (Math.abs(i - this.headYaw) >= 1) {
                  this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i));
                  this.headYaw = i;
              }
  
              this.tracker.impulse = false;
          }
  
          ++this.a;
          if (this.tracker.velocityChanged) {
              // CraftBukkit start - Create PlayerVelocity event
              boolean cancelled = false;
  
              if (this.tracker instanceof EntityPlayer) {
                  Player player = (Player) this.tracker.getBukkitEntity();
                  org.bukkit.util.Vector velocity = player.getVelocity();
  
                  PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone());
                  this.tracker.world.getServer().getPluginManager().callEvent(event);
  
                  if (event.isCancelled()) {
                      cancelled = true;
                  } else if (!velocity.equals(event.getVelocity())) {
                      player.setVelocity(event.getVelocity());
                  }
              }
  
              if (!cancelled) {
                  this.broadcastIncludingSelf(new PacketPlayOutEntityVelocity(this.tracker));
              }
              // CraftBukkit end
              this.tracker.velocityChanged = false;
          }
  
      }
  
      private void d() {
          DataWatcher datawatcher = this.tracker.getDataWatcher();
  
          if (datawatcher.a()) {
              this.broadcastIncludingSelf(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
          }
  
          if (this.tracker instanceof EntityLiving) {
              AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
              Set set = attributemapserver.getAttributes();
  
              if (!set.isEmpty()) {
                  // CraftBukkit start - Send scaled max health
                  if (this.tracker instanceof EntityPlayer) {
                      ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(set, false);
                  }
                  // CraftBukkit end
                  this.broadcastIncludingSelf(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set));
              }
  
              set.clear();
          }
  
      }
  
      public void broadcast(Packet<?> packet) {
          Iterator iterator = this.trackedPlayers.iterator();
  
          while (iterator.hasNext()) {
              EntityPlayer entityplayer = (EntityPlayer) iterator.next();
  
              entityplayer.playerConnection.sendPacket(packet);
          }
  
      }
  
      public void broadcastIncludingSelf(Packet<?> packet) {
          this.broadcast(packet);
          if (this.tracker instanceof EntityPlayer) {
              ((EntityPlayer) this.tracker).playerConnection.sendPacket(packet);
          }
  
      }
  
      public void a() {
          Iterator iterator = this.trackedPlayers.iterator();
  
          while (iterator.hasNext()) {
              EntityPlayer entityplayer = (EntityPlayer) iterator.next();
  
              this.tracker.c(entityplayer);
              entityplayer.c(this.tracker);
          }
  
      }
  
      public void a(EntityPlayer entityplayer) {
          if (this.trackedPlayers.contains(entityplayer)) {
              this.tracker.c(entityplayer);
              entityplayer.c(this.tracker);
              this.trackedPlayers.remove(entityplayer);
          }
  
      }
  
      public void updatePlayer(EntityPlayer entityplayer) {
          org.spigotmc.AsyncCatcher.catchOp( "player tracker update"); // Spigot
          if (entityplayer != this.tracker) {
              if (this.c(entityplayer)) {
                  if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) {
                      // CraftBukkit start - respect vanish API
                      if (this.tracker instanceof EntityPlayer) {
                          Player player = ((EntityPlayer) this.tracker).getBukkitEntity();
                          if (!entityplayer.getBukkitEntity().canSee(player)) {
                              return;
                          }
                      }
  
                      entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.getId()));
                      // CraftBukkit end
                      this.trackedPlayerMap.put(entityplayer, true); // Paper
                      Packet packet = this.e();
  
                      entityplayer.playerConnection.sendPacket(packet);
                      if (!this.tracker.getDataWatcher().d()) {
                          entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(this.tracker.getId(), this.tracker.getDataWatcher(), true));
                      }
  
                      boolean flag = this.u;
  
                      if (this.tracker instanceof EntityLiving) {
                          AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
                          Collection collection = attributemapserver.c();
  
                          // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health
                          if (this.tracker.getId() == entityplayer.getId()) {
                              ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(collection, false);
                          }
                          // CraftBukkit end
  
                          if (!collection.isEmpty()) {
                              entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection));
                          }
  
                          if (((EntityLiving) this.tracker).cP()) {
                              flag = true;
                          }
                      }
  
                      this.n = this.tracker.motX;
                      this.o = this.tracker.motY;
                      this.p = this.tracker.motZ;
                      if (flag && !(packet instanceof PacketPlayOutSpawnEntityLiving)) {
                          entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.tracker.motX, this.tracker.motY, this.tracker.motZ));
                      }
  
                      if (this.tracker instanceof EntityLiving) {
                          EnumItemSlot[] aenumitemslot = EnumItemSlot.values();
                          int i = aenumitemslot.length;
  
                          for (int j = 0; j < i; ++j) {
                              EnumItemSlot enumitemslot = aenumitemslot[j];
                              ItemStack itemstack = ((EntityLiving) this.tracker).getEquipment(enumitemslot);
  
                              if (!itemstack.isEmpty()) {
                                  entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEquipment(this.tracker.getId(), enumitemslot, itemstack));
                              }
                          }
                      }
  
                      if (this.tracker instanceof EntityHuman) {
                          EntityHuman entityhuman = (EntityHuman) this.tracker;
  
                          if (entityhuman.isSleeping()) {
                              entityplayer.playerConnection.sendPacket(new PacketPlayOutBed(entityhuman, new BlockPosition(this.tracker)));
                          }
                      }
  
                      if (this.tracker instanceof EntityLiving) {
  						// CraftBukkit start - Fix for nonsensical head yaw
                          this.headYaw = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
                          this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) headYaw));
  						// CraftBukkit end
                          EntityLiving entityliving = (EntityLiving) this.tracker;
                          Iterator iterator = entityliving.getEffects().iterator();
  
                          while (iterator.hasNext()) {
                              MobEffect mobeffect = (MobEffect) iterator.next();
  
                              entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.tracker.getId(), mobeffect));
                          }
                      }
  
                      if (!this.tracker.bF().isEmpty()) {
                          entityplayer.playerConnection.sendPacket(new PacketPlayOutMount(this.tracker));
                      }
  
                      if (this.tracker.isPassenger()) {
                          entityplayer.playerConnection.sendPacket(new PacketPlayOutMount(this.tracker.bJ()));
                      }
  
                      this.tracker.b(entityplayer);
                      entityplayer.d(this.tracker);
                      updatePassengers(entityplayer); // Paper
                  }
              } else if (this.trackedPlayers.contains(entityplayer)) {
                  this.trackedPlayers.remove(entityplayer);
                  this.tracker.c(entityplayer);
                  entityplayer.c(this.tracker);
                  updatePassengers(entityplayer); // Paper
              }
  
          }
      }
  
      public boolean c(EntityPlayer entityplayer) {
          // Paper start
          if (tracker.isPassenger()) {
              return isTrackedBy(tracker.getVehicle(), entityplayer);
          } else if (hasPassengerInRange(tracker, entityplayer)) {
              return true;
          }
  
          return isInRangeOfPlayer(entityplayer);
      }
      private static boolean hasPassengerInRange(Entity entity, EntityPlayer entityplayer) {
          if (!entity.isVehicle()) {
              return false;
          }
          for (Entity passenger : entity.passengers) {
              if (passenger.tracker != null && passenger.tracker.isInRangeOfPlayer(entityplayer)) {
                  return true;
              }
              if (passenger.isVehicle()) {
                  if (hasPassengerInRange(passenger, entityplayer)) {
                      return true;
                  }
              }
          }
          return false;
      }
      private static boolean isTrackedBy(Entity entity, EntityPlayer entityplayer) {
          return entity == entityplayer || entity.tracker != null && entity.tracker.trackedPlayers.contains(entityplayer);
      }
      private void updatePassengers(EntityPlayer player) {
          if (tracker.isVehicle()) {
              tracker.passengers.forEach((e) -> {
                  if (e.tracker != null) {
                      e.tracker.updatePlayer(player);
                  }
              });
              player.playerConnection.sendPacket(new PacketPlayOutMount(this.tracker));
          }
      }
      private boolean isInRangeOfPlayer(EntityPlayer entityplayer) {
          // Paper end
          double d0 = entityplayer.locX - (double) this.xLoc / 4096.0D;
          double d1 = entityplayer.locZ - (double) this.zLoc / 4096.0D;
          int i = Math.min(this.e, this.f);
  
          return d0 >= (double) (-i) && d0 <= (double) i && d1 >= (double) (-i) && d1 <= (double) i && this.tracker.a(entityplayer);
      }
  
      private boolean e(EntityPlayer entityplayer) {
          return entityplayer.x().getPlayerChunkMap().a(entityplayer, this.tracker.ab, this.tracker.ad);
      }
  
      public void scanPlayers(List<EntityHuman> list) {
          for (int i = 0; i < list.size(); ++i) {
              this.updatePlayer((EntityPlayer) list.get(i));
          }
  
      }
  
      private Packet<?> e() {
          if (this.tracker.dead) {
              // CraftBukkit start - Remove useless error spam, just return
              // EntityTrackerEntry.d.warn("Fetching addPacket for removed entity");
              return null;
              // CraftBukkit end
          }
  
          if (this.tracker instanceof EntityPlayer) {
              return new PacketPlayOutNamedEntitySpawn((EntityHuman) this.tracker);
          } else if (this.tracker instanceof IAnimal) {
              this.headYaw = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
              return new PacketPlayOutSpawnEntityLiving((EntityLiving) this.tracker);
          } else if (this.tracker instanceof EntityPainting) {
              return new PacketPlayOutSpawnEntityPainting((EntityPainting) this.tracker);
          } else if (this.tracker instanceof EntityItem) {
              return new PacketPlayOutSpawnEntity(this.tracker, 2, 1);
          } else if (this.tracker instanceof EntityMinecartAbstract) {
              EntityMinecartAbstract entityminecartabstract = (EntityMinecartAbstract) this.tracker;
  
              return new PacketPlayOutSpawnEntity(this.tracker, 10, entityminecartabstract.v().a());
          } else if (this.tracker instanceof EntityBoat) {
              return new PacketPlayOutSpawnEntity(this.tracker, 1);
          } else if (this.tracker instanceof EntityExperienceOrb) {
              return new PacketPlayOutSpawnEntityExperienceOrb((EntityExperienceOrb) this.tracker);
          } else if (this.tracker instanceof EntityFishingHook) {
              EntityHuman entityhuman = ((EntityFishingHook) this.tracker).l();
  
              return new PacketPlayOutSpawnEntity(this.tracker, 90, entityhuman == null ? this.tracker.getId() : entityhuman.getId());
          } else {
              Entity entity;
  
              if (this.tracker instanceof EntitySpectralArrow) {
                  entity = ((EntitySpectralArrow) this.tracker).shooter;
                  return new PacketPlayOutSpawnEntity(this.tracker, 91, 1 + (entity == null ? this.tracker.getId() : entity.getId()));
              } else if (this.tracker instanceof EntityTippedArrow) {
                  entity = ((EntityArrow) this.tracker).shooter;
                  return new PacketPlayOutSpawnEntity(this.tracker, 60, 1 + (entity == null ? this.tracker.getId() : entity.getId()));
              } else if (this.tracker instanceof EntitySnowball) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 61);
              } else if (this.tracker instanceof EntityLlamaSpit) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 68);
              } else if (this.tracker instanceof EntityPotion) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 73);
              } else if (this.tracker instanceof EntityThrownExpBottle) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 75);
              } else if (this.tracker instanceof EntityEnderPearl) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 65);
              } else if (this.tracker instanceof EntityEnderSignal) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 72);
              } else if (this.tracker instanceof EntityFireworks) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 76);
              } else if (this.tracker instanceof EntityFireball) {
                  EntityFireball entityfireball = (EntityFireball) this.tracker;
                  PacketPlayOutSpawnEntity packetplayoutspawnentity = null;
                  byte b0 = 63;
  
                  if (this.tracker instanceof EntitySmallFireball) {
                      b0 = 64;
                  } else if (this.tracker instanceof EntityDragonFireball) {
                      b0 = 93;
                  } else if (this.tracker instanceof EntityWitherSkull) {
                      b0 = 66;
                  }
  
                  if (entityfireball.shooter != null) {
                      packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, b0, ((EntityFireball) this.tracker).shooter.getId());
                  } else {
                      packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, b0, 0);
                  }
  
                  packetplayoutspawnentity.a((int) (entityfireball.dirX * 8000.0D));
                  packetplayoutspawnentity.b((int) (entityfireball.dirY * 8000.0D));
                  packetplayoutspawnentity.c((int) (entityfireball.dirZ * 8000.0D));
                  return packetplayoutspawnentity;
              } else if (this.tracker instanceof EntityShulkerBullet) {
                  PacketPlayOutSpawnEntity packetplayoutspawnentity1 = new PacketPlayOutSpawnEntity(this.tracker, 67, 0);
  
                  packetplayoutspawnentity1.a((int) (this.tracker.motX * 8000.0D));
                  packetplayoutspawnentity1.b((int) (this.tracker.motY * 8000.0D));
                  packetplayoutspawnentity1.c((int) (this.tracker.motZ * 8000.0D));
                  return packetplayoutspawnentity1;
              } else if (this.tracker instanceof EntityEgg) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 62);
              } else if (this.tracker instanceof EntityEvokerFangs) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 79);
              } else if (this.tracker instanceof EntityTNTPrimed) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 50);
              } else if (this.tracker instanceof EntityEnderCrystal) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 51);
              } else if (this.tracker instanceof EntityFallingBlock) {
                  EntityFallingBlock entityfallingblock = (EntityFallingBlock) this.tracker;
  
                  return new PacketPlayOutSpawnEntity(this.tracker, 70, Block.getCombinedId(entityfallingblock.getBlock()));
              } else if (this.tracker instanceof EntityArmorStand) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 78);
              } else if (this.tracker instanceof EntityItemFrame) {
                  EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker;
  
                  return new PacketPlayOutSpawnEntity(this.tracker, 71, entityitemframe.direction.get2DRotationValue(), entityitemframe.getBlockPosition());
              } else if (this.tracker instanceof EntityLeash) {
                  EntityLeash entityleash = (EntityLeash) this.tracker;
  
                  return new PacketPlayOutSpawnEntity(this.tracker, 77, 0, entityleash.getBlockPosition());
              } else if (this.tracker instanceof EntityAreaEffectCloud) {
                  return new PacketPlayOutSpawnEntity(this.tracker, 3);
              } else {
                  throw new IllegalArgumentException("Don\'t know how to add " + this.tracker.getClass() + "!");
              }
          }
      }
  
      public void clear(EntityPlayer entityplayer) {
          org.spigotmc.AsyncCatcher.catchOp( "player tracker clear"); // Spigot
          if (this.trackedPlayers.contains(entityplayer)) {
              this.trackedPlayers.remove(entityplayer);
              this.tracker.c(entityplayer);
              entityplayer.c(this.tracker);
              updatePassengers(entityplayer); // Paper
          }
  
      }
  
      public Entity b() {
          return this.tracker;
      }
  
      public void a(int i) {
          this.f = i;
      }
  
      public void c() {
          this.isMoving = false;
      }
  }
  