package net.minecraft.entity;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import cpw.mods.fml.common.network.FMLNetworkHandler;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.item.EntityBoat;
import net.minecraft.entity.item.EntityEnderCrystal;
import net.minecraft.entity.item.EntityEnderEye;
import net.minecraft.entity.item.EntityEnderPearl;
import net.minecraft.entity.item.EntityExpBottle;
import net.minecraft.entity.item.EntityFallingSand;
import net.minecraft.entity.item.EntityFireworkRocket;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.item.EntityPainting;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.passive.IAnimals;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.entity.projectile.EntityEgg;
import net.minecraft.entity.projectile.EntityFireball;
import net.minecraft.entity.projectile.EntityFishHook;
import net.minecraft.entity.projectile.EntityPotion;
import net.minecraft.entity.projectile.EntitySmallFireball;
import net.minecraft.entity.projectile.EntitySnowball;
import net.minecraft.entity.projectile.EntityWitherSkull;
import net.minecraft.item.Item;
import net.minecraft.item.ItemMap;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet17Sleep;
import net.minecraft.network.packet.Packet20NamedEntitySpawn;
import net.minecraft.network.packet.Packet23VehicleSpawn;
import net.minecraft.network.packet.Packet24MobSpawn;
import net.minecraft.network.packet.Packet25EntityPainting;
import net.minecraft.network.packet.Packet26EntityExpOrb;
import net.minecraft.network.packet.Packet28EntityVelocity;
import net.minecraft.network.packet.Packet31RelEntityMove;
import net.minecraft.network.packet.Packet32EntityLook;
import net.minecraft.network.packet.Packet33RelEntityMoveLook;
import net.minecraft.network.packet.Packet34EntityTeleport;
import net.minecraft.network.packet.Packet35EntityHeadRotation;
import net.minecraft.network.packet.Packet39AttachEntity;
import net.minecraft.network.packet.Packet40EntityMetadata;
import net.minecraft.network.packet.Packet41EntityEffect;
import net.minecraft.network.packet.Packet5PlayerInventory;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.MathHelper;
import net.minecraft.world.storage.MapData;
public class EntityTrackerEntry
{
public Entity myEntity;
public int blocksDistanceThreshold;
/** check for sync when ticks % updateFrequency==0 */
public int updateFrequency;
public int lastScaledXPosition;
public int lastScaledYPosition;
public int lastScaledZPosition;
public int lastYaw;
public int lastPitch;
public int lastHeadMotion;
public double motionX;
public double motionY;
public double motionZ;
public int ticks = 0;
private double posX;
private double posY;
private double posZ;
/** set to true on first sendLocationToClients */
private boolean isDataInitialized = false;
private boolean sendVelocityUpdates;
/**
* every 400 ticks a full teleport packet is sent, rather than just a "move me +x" command, so that position
* remains fully synced.
*/
private int ticksSinceLastForcedTeleport = 0;
private Entity field_85178_v;
private boolean ridingEntity = false;
public boolean playerEntitiesUpdated = false;
public Set trackedPlayers = new HashSet();
public EntityTrackerEntry(Entity par1Entity, int par2, int par3, boolean par4)
{
this.myEntity = par1Entity;
this.blocksDistanceThreshold = par2;
this.updateFrequency = par3;
this.sendVelocityUpdates = par4;
this.lastScaledXPosition = MathHelper.floor_double(par1Entity.posX * 32.0D);
this.lastScaledYPosition = MathHelper.floor_double(par1Entity.posY * 32.0D);
this.lastScaledZPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D);
this.lastYaw = MathHelper.floor_float(par1Entity.rotationYaw * 256.0F / 360.0F);
this.lastPitch = MathHelper.floor_float(par1Entity.rotationPitch * 256.0F / 360.0F);
this.lastHeadMotion = MathHelper.floor_float(par1Entity.setRotationYawHead() * 256.0F / 360.0F);
}
public boolean equals(Object par1Obj)
{
return par1Obj instanceof EntityTrackerEntry ? ((EntityTrackerEntry)par1Obj).myEntity.entityId == this.myEntity.entityId : false;
}
public int hashCode()
{
return this.myEntity.entityId;
}
/**
* also sends velocity, rotation, and riding info.
*/
public void sendLocationToAllClients(List par1List)
{
this.playerEntitiesUpdated = false;
if (!this.isDataInitialized || this.myEntity.getDistanceSq(this.posX, this.posY, this.posZ) > 16.0D)
{
this.posX = this.myEntity.posX;
this.posY = this.myEntity.posY;
this.posZ = this.myEntity.posZ;
this.isDataInitialized = true;
this.playerEntitiesUpdated = true;
this.sendEventsToPlayers(par1List);
}
if (this.field_85178_v != this.myEntity.ridingEntity)
{
this.field_85178_v = this.myEntity.ridingEntity;
this.sendPacketToAllTrackingPlayers(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity));
}
if (this.myEntity instanceof EntityItemFrame && this.ticks % 10 == 0)
{
EntityItemFrame var23 = (EntityItemFrame)this.myEntity;
ItemStack var24 = var23.getDisplayedItem();
if (var24 != null && var24.getItem() instanceof ItemMap)
{
MapData var26 = Item.map.getMapData(var24, this.myEntity.worldObj);
Iterator var29 = par1List.iterator();
while (var29.hasNext())
{
EntityPlayer var30 = (EntityPlayer)var29.next();
EntityPlayerMP var31 = (EntityPlayerMP)var30;
var26.updateVisiblePlayers(var31, var24);
if (var31.playerNetServerHandler.packetSize() <= 5)
{
Packet var32 = Item.map.createMapDataPacket(var24, this.myEntity.worldObj, var31);
if (var32 != null)
{
var31.playerNetServerHandler.sendPacketToPlayer(var32);
}
}
}
}
DataWatcher var28 = this.myEntity.getDataWatcher();
if (var28.hasChanges())
{
this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, var28, false));
}
}
else if (this.ticks++ % this.updateFrequency == 0 || this.myEntity.isAirBorne)
{
int var2;
int var3;
if (this.myEntity.ridingEntity == null)
{
++this.ticksSinceLastForcedTeleport;
var2 = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX);
var3 = MathHelper.floor_double(this.myEntity.posY * 32.0D);
int var4 = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ);
int var5 = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F);
int var6 = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F);
int var7 = var2 - this.lastScaledXPosition;
int var8 = var3 - this.lastScaledYPosition;
int var9 = var4 - this.lastScaledZPosition;
Object var10 = null;
boolean var11 = Math.abs(var7) >= 4 || Math.abs(var8) >= 4 || Math.abs(var9) >= 4 || this.ticks % 60 == 0;
boolean var12 = Math.abs(var5 - this.lastYaw) >= 4 || Math.abs(var6 - this.lastPitch) >= 4;
if (var7 >= -128 && var7 < 128 && var8 >= -128 && var8 < 128 && var9 >= -128 && var9 < 128 && this.ticksSinceLastForcedTeleport <= 400 && !this.ridingEntity)
{
if (var11 && var12)
{
var10 = new Packet33RelEntityMoveLook(this.myEntity.entityId, (byte)var7, (byte)var8, (byte)var9, (byte)var5, (byte)var6);
}
else if (var11)
{
var10 = new Packet31RelEntityMove(this.myEntity.entityId, (byte)var7, (byte)var8, (byte)var9);
}
else if (var12)
{
var10 = new Packet32EntityLook(this.myEntity.entityId, (byte)var5, (byte)var6);
}
}
else
{
this.ticksSinceLastForcedTeleport = 0;
var10 = new Packet34EntityTeleport(this.myEntity.entityId, var2, var3, var4, (byte)var5, (byte)var6);
}
if (this.sendVelocityUpdates)
{
double var13 = this.myEntity.motionX - this.motionX;
double var15 = this.myEntity.motionY - this.motionY;
double var17 = this.myEntity.motionZ - this.motionZ;
double var19 = 0.02D;
double var21 = var13 * var13 + var15 * var15 + var17 * var17;
if (var21 > var19 * var19 || var21 > 0.0D && this.myEntity.motionX == 0.0D && this.myEntity.motionY == 0.0D && this.myEntity.motionZ == 0.0D)
{
this.motionX = this.myEntity.motionX;
this.motionY = this.myEntity.motionY;
this.motionZ = this.myEntity.motionZ;
this.sendPacketToAllTrackingPlayers(new Packet28EntityVelocity(this.myEntity.entityId, this.motionX, this.motionY, this.motionZ));
}
}
if (var10 != null)
{
this.sendPacketToAllTrackingPlayers((Packet)var10);
}
DataWatcher var33 = this.myEntity.getDataWatcher();
if (var33.hasChanges())
{
this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, var33, false));
}
if (var11)
{
this.lastScaledXPosition = var2;
this.lastScaledYPosition = var3;
this.lastScaledZPosition = var4;
}
if (var12)
{
this.lastYaw = var5;
this.lastPitch = var6;
}
this.ridingEntity = false;
}
else
{
var2 = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F);
var3 = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F);
boolean var25 = Math.abs(var2 - this.lastYaw) >= 4 || Math.abs(var3 - this.lastPitch) >= 4;
if (var25)
{
this.sendPacketToAllTrackingPlayers(new Packet32EntityLook(this.myEntity.entityId, (byte)var2, (byte)var3));
this.lastYaw = var2;
this.lastPitch = var3;
}
this.lastScaledXPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX);
this.lastScaledYPosition = MathHelper.floor_double(this.myEntity.posY * 32.0D);
this.lastScaledZPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ);
DataWatcher var27 = this.myEntity.getDataWatcher();
if (var27.hasChanges())
{
this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, var27, false));
}
this.ridingEntity = true;
}
var2 = MathHelper.floor_float(this.myEntity.setRotationYawHead() * 256.0F / 360.0F);
if (Math.abs(var2 - this.lastHeadMotion) >= 4)
{
this.sendPacketToAllTrackingPlayers(new Packet35EntityHeadRotation(this.myEntity.entityId, (byte)var2));
this.lastHeadMotion = var2;
}
this.myEntity.isAirBorne = false;
}
if (this.myEntity.velocityChanged)
{
this.sendPacketToAllAssociatedPlayers(new Packet28EntityVelocity(this.myEntity));
this.myEntity.velocityChanged = false;
}
}
/**
* if this is a player, then it is not informed
*/
public void sendPacketToAllTrackingPlayers(Packet par1Packet)
{
Iterator var2 = this.trackedPlayers.iterator();
while (var2.hasNext())
{
EntityPlayerMP var3 = (EntityPlayerMP)var2.next();
var3.playerNetServerHandler.sendPacketToPlayer(par1Packet);
}
}
/**
* if this is a player, then it recieves the message also
*/
public void sendPacketToAllAssociatedPlayers(Packet par1Packet)
{
this.sendPacketToAllTrackingPlayers(par1Packet);
if (this.myEntity instanceof EntityPlayerMP)
{
((EntityPlayerMP)this.myEntity).playerNetServerHandler.sendPacketToPlayer(par1Packet);
}
}
public void informAllAssociatedPlayersOfItemDestruction()
{
Iterator var1 = this.trackedPlayers.iterator();
while (var1.hasNext())
{
EntityPlayerMP var2 = (EntityPlayerMP)var1.next();
var2.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
}
}
public void removeFromWatchingList(EntityPlayerMP par1EntityPlayerMP)
{
if (this.trackedPlayers.contains(par1EntityPlayerMP))
{
par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
this.trackedPlayers.remove(par1EntityPlayerMP);
}
}
/**
* if the player is more than the distance threshold (typically 64) then the player is removed instead
*/
public void tryStartWachingThis(EntityPlayerMP par1EntityPlayerMP)
{
if (par1EntityPlayerMP != this.myEntity)
{
double var2 = par1EntityPlayerMP.posX - (double)(this.lastScaledXPosition / 32);
double var4 = par1EntityPlayerMP.posZ - (double)(this.lastScaledZPosition / 32);
if (var2 >= (double)(-this.blocksDistanceThreshold) && var2 <= (double)this.blocksDistanceThreshold && var4 >= (double)(-this.blocksDistanceThreshold) && var4 <= (double)this.blocksDistanceThreshold)
{
if (!this.trackedPlayers.contains(par1EntityPlayerMP) && this.isPlayerWatchingThisChunk(par1EntityPlayerMP))
{
this.trackedPlayers.add(par1EntityPlayerMP);
Packet var6 = this.getPacketForThisEntity();
par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(var6);
if (!this.myEntity.getDataWatcher().func_92034_d())
{
par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet40EntityMetadata(this.myEntity.entityId, this.myEntity.getDataWatcher(), true));
}
this.motionX = this.myEntity.motionX;
this.motionY = this.myEntity.motionY;
this.motionZ = this.myEntity.motionZ;
int posX = MathHelper.floor_double(this.myEntity.posX * 32.0D);
int posY = MathHelper.floor_double(this.myEntity.posY * 32.0D);
int posZ = MathHelper.floor_double(this.myEntity.posZ * 32.0D);
if (posX != this.lastScaledXPosition || posY != this.lastScaledYPosition || posZ != this.lastScaledZPosition)
{
FMLNetworkHandler.makeEntitySpawnAdjustment(this.myEntity.entityId, par1EntityPlayerMP, this.lastScaledXPosition, this.lastScaledYPosition, this.lastScaledZPosition);
}
if (this.sendVelocityUpdates && !(var6 instanceof Packet24MobSpawn))
{
par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet28EntityVelocity(this.myEntity.entityId, this.myEntity.motionX, this.myEntity.motionY, this.myEntity.motionZ));
}
if (this.myEntity.ridingEntity != null)
{
par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity));
}
if (this.myEntity instanceof EntityLiving)
{
for (int var7 = 0; var7 < 5; ++var7)
{
ItemStack var8 = ((EntityLiving)this.myEntity).getCurrentItemOrArmor(var7);
if (var8 != null)
{
par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet5PlayerInventory(this.myEntity.entityId, var7, var8));
}
}
}
if (this.myEntity instanceof EntityPlayer)
{
EntityPlayer var11 = (EntityPlayer)this.myEntity;
if (var11.isPlayerSleeping())
{
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)));
}
}
if (this.myEntity instanceof EntityLiving)
{
EntityLiving var10 = (EntityLiving)this.myEntity;
Iterator var12 = var10.getActivePotionEffects().iterator();
while (var12.hasNext())
{
PotionEffect var9 = (PotionEffect)var12.next();
par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(this.myEntity.entityId, var9));
}
}
}
}
else if (this.trackedPlayers.contains(par1EntityPlayerMP))
{
this.trackedPlayers.remove(par1EntityPlayerMP);
par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
}
}
}
private boolean isPlayerWatchingThisChunk(EntityPlayerMP par1EntityPlayerMP)
{
return par1EntityPlayerMP.getServerForPlayer().getPlayerManager().isPlayerWatchingChunk(par1EntityPlayerMP, this.myEntity.chunkCoordX, this.myEntity.chunkCoordZ);
}
public void sendEventsToPlayers(List par1List)
{
for (int var2 = 0; var2 < par1List.size(); ++var2)
{
this.tryStartWachingThis((EntityPlayerMP)par1List.get(var2));
}
}
private Packet getPacketForThisEntity()
{
if (this.myEntity.isDead)
{
System.out.println("Fetching addPacket for removed entity");
}
Packet pkt = FMLNetworkHandler.getEntitySpawningPacket(this.myEntity);
if (pkt != null)
{
return pkt;
}
if (this.myEntity instanceof EntityItem)
{
return new Packet23VehicleSpawn(this.myEntity, 2, 1);
}
else if (this.myEntity instanceof EntityPlayerMP)
{
return new Packet20NamedEntitySpawn((EntityPlayer)this.myEntity);
}
else
{
if (this.myEntity instanceof EntityMinecart)
{
EntityMinecart var1 = (EntityMinecart)this.myEntity;
if (var1.minecartType == 0)
{
return new Packet23VehicleSpawn(this.myEntity, 10);
}
if (var1.minecartType == 1)
{
return new Packet23VehicleSpawn(this.myEntity, 11);
}
if (var1.minecartType == 2)
{
return new Packet23VehicleSpawn(this.myEntity, 12);
}
}
if (this.myEntity instanceof EntityBoat)
{
return new Packet23VehicleSpawn(this.myEntity, 1);
}
else if (!(this.myEntity instanceof IAnimals) && !(this.myEntity instanceof EntityDragon))
{
if (this.myEntity instanceof EntityFishHook)
{
EntityPlayer var8 = ((EntityFishHook)this.myEntity).angler;
return new Packet23VehicleSpawn(this.myEntity, 90, var8 != null ? var8.entityId : this.myEntity.entityId);
}
else if (this.myEntity instanceof EntityArrow)
{
Entity var7 = ((EntityArrow)this.myEntity).shootingEntity;
return new Packet23VehicleSpawn(this.myEntity, 60, var7 != null ? var7.entityId : this.myEntity.entityId);
}
else if (this.myEntity instanceof EntitySnowball)
{
return new Packet23VehicleSpawn(this.myEntity, 61);
}
else if (this.myEntity instanceof EntityPotion)
{
return new Packet23VehicleSpawn(this.myEntity, 73, ((EntityPotion)this.myEntity).getPotionDamage());
}
else if (this.myEntity instanceof EntityExpBottle)
{
return new Packet23VehicleSpawn(this.myEntity, 75);
}
else if (this.myEntity instanceof EntityEnderPearl)
{
return new Packet23VehicleSpawn(this.myEntity, 65);
}
else if (this.myEntity instanceof EntityEnderEye)
{
return new Packet23VehicleSpawn(this.myEntity, 72);
}
else if (this.myEntity instanceof EntityFireworkRocket)
{
return new Packet23VehicleSpawn(this.myEntity, 76);
}
else
{
Packet23VehicleSpawn var2;
if (this.myEntity instanceof EntityFireball)
{
EntityFireball var6 = (EntityFireball)this.myEntity;
var2 = null;
byte var3 = 63;
if (this.myEntity instanceof EntitySmallFireball)
{
var3 = 64;
}
else if (this.myEntity instanceof EntityWitherSkull)
{
var3 = 66;
}
if (var6.shootingEntity != null)
{
var2 = new Packet23VehicleSpawn(this.myEntity, var3, ((EntityFireball)this.myEntity).shootingEntity.entityId);
}
else
{
var2 = new Packet23VehicleSpawn(this.myEntity, var3, 0);
}
var2.speedX = (int)(var6.accelerationX * 8000.0D);
var2.speedY = (int)(var6.accelerationY * 8000.0D);
var2.speedZ = (int)(var6.accelerationZ * 8000.0D);
return var2;
}
else if (this.myEntity instanceof EntityEgg)
{
return new Packet23VehicleSpawn(this.myEntity, 62);
}
else if (this.myEntity instanceof EntityTNTPrimed)
{
return new Packet23VehicleSpawn(this.myEntity, 50);
}
else if (this.myEntity instanceof EntityEnderCrystal)
{
return new Packet23VehicleSpawn(this.myEntity, 51);
}
else if (this.myEntity instanceof EntityFallingSand)
{
EntityFallingSand var5 = (EntityFallingSand)this.myEntity;
return new Packet23VehicleSpawn(this.myEntity, 70, var5.blockID | var5.metadata << 16);
}
else if (this.myEntity instanceof EntityPainting)
{
return new Packet25EntityPainting((EntityPainting)this.myEntity);
}
else if (this.myEntity instanceof EntityItemFrame)
{
EntityItemFrame var4 = (EntityItemFrame)this.myEntity;
var2 = new Packet23VehicleSpawn(this.myEntity, 71, var4.hangingDirection);
var2.xPosition = MathHelper.floor_float((float)(var4.xPosition * 32));
var2.yPosition = MathHelper.floor_float((float)(var4.yPosition * 32));
var2.zPosition = MathHelper.floor_float((float)(var4.zPosition * 32));
return var2;
}
else if (this.myEntity instanceof EntityXPOrb)
{
return new Packet26EntityExpOrb((EntityXPOrb)this.myEntity);
}
else
{
throw new IllegalArgumentException("Don\'t know how to add " + this.myEntity.getClass() + "!");
}
}
}
else
{
this.lastHeadMotion = MathHelper.floor_float(this.myEntity.setRotationYawHead() * 256.0F / 360.0F);
return new Packet24MobSpawn((EntityLiving)this.myEntity);
}
}
}
public void removePlayerFromTracker(EntityPlayerMP par1EntityPlayerMP)
{
if (this.trackedPlayers.contains(par1EntityPlayerMP))
{
this.trackedPlayers.remove(par1EntityPlayerMP);
par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
}
}
}