package net.minecraft.entity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Callable;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.EntityWither;
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.EntityFallingBlock;
import net.minecraft.entity.item.EntityFireworkRocket;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.passive.EntityBat;
import net.minecraft.entity.passive.EntitySquid;
import net.minecraft.entity.passive.IAnimals;
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.network.Packet;
import net.minecraft.util.IntHashMap;
import net.minecraft.util.ReportedException;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cpw.mods.fml.common.registry.EntityRegistry;
public class EntityTracker
{
private static final Logger logger = LogManager.getLogger();
private final WorldServer theWorld;
/** List of tracked entities, used for iteration operations on tracked entities. */
private Set trackedEntities = new HashSet();
/** Used for identity lookup of tracked entities. */
private IntHashMap trackedEntityHashTable = new IntHashMap();
private int maxTrackingDistanceThreshold;
private static final String __OBFID = "CL_00001431";
public EntityTracker(WorldServer p_i1516_1_)
{
this.theWorld = p_i1516_1_;
this.maxTrackingDistanceThreshold = p_i1516_1_.func_73046_m().getConfigurationManager().getEntityViewDistance();
}
public void trackEntity(Entity p_72786_1_)
{
if (EntityRegistry.instance().tryTrackingEntity(this, p_72786_1_))
{
return;
}
if (p_72786_1_ instanceof EntityPlayerMP)
{
this.trackEntity(p_72786_1_, 512, 2);
EntityPlayerMP entityplayermp = (EntityPlayerMP)p_72786_1_;
Iterator iterator = this.trackedEntities.iterator();
while (iterator.hasNext())
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
if (entitytrackerentry.trackedEntity != entityplayermp)
{
entitytrackerentry.updatePlayerEntity(entityplayermp);
}
}
}
else if (p_72786_1_ instanceof EntityFishHook)
{
this.addEntityToTracker(p_72786_1_, 64, 5, true);
}
else if (p_72786_1_ instanceof EntityArrow)
{
this.addEntityToTracker(p_72786_1_, 64, 20, false);
}
else if (p_72786_1_ instanceof EntitySmallFireball)
{
this.addEntityToTracker(p_72786_1_, 64, 10, false);
}
else if (p_72786_1_ instanceof EntityFireball)
{
this.addEntityToTracker(p_72786_1_, 64, 10, false);
}
else if (p_72786_1_ instanceof EntitySnowball)
{
this.addEntityToTracker(p_72786_1_, 64, 10, true);
}
else if (p_72786_1_ instanceof EntityEnderPearl)
{
this.addEntityToTracker(p_72786_1_, 64, 10, true);
}
else if (p_72786_1_ instanceof EntityEnderEye)
{
this.addEntityToTracker(p_72786_1_, 64, 4, true);
}
else if (p_72786_1_ instanceof EntityEgg)
{
this.addEntityToTracker(p_72786_1_, 64, 10, true);
}
else if (p_72786_1_ instanceof EntityPotion)
{
this.addEntityToTracker(p_72786_1_, 64, 10, true);
}
else if (p_72786_1_ instanceof EntityExpBottle)
{
this.addEntityToTracker(p_72786_1_, 64, 10, true);
}
else if (p_72786_1_ instanceof EntityFireworkRocket)
{
this.addEntityToTracker(p_72786_1_, 64, 10, true);
}
else if (p_72786_1_ instanceof EntityItem)
{
this.addEntityToTracker(p_72786_1_, 64, 20, true);
}
else if (p_72786_1_ instanceof EntityMinecart)
{
this.addEntityToTracker(p_72786_1_, 80, 3, true);
}
else if (p_72786_1_ instanceof EntityBoat)
{
this.addEntityToTracker(p_72786_1_, 80, 3, true);
}
else if (p_72786_1_ instanceof EntitySquid)
{
this.addEntityToTracker(p_72786_1_, 64, 3, true);
}
else if (p_72786_1_ instanceof EntityWither)
{
this.addEntityToTracker(p_72786_1_, 80, 3, false);
}
else if (p_72786_1_ instanceof EntityBat)
{
this.addEntityToTracker(p_72786_1_, 80, 3, false);
}
else if (p_72786_1_ instanceof IAnimals)
{
this.addEntityToTracker(p_72786_1_, 80, 3, true);
}
else if (p_72786_1_ instanceof EntityDragon)
{
this.addEntityToTracker(p_72786_1_, 160, 3, true);
}
else if (p_72786_1_ instanceof EntityTNTPrimed)
{
this.addEntityToTracker(p_72786_1_, 160, 10, true);
}
else if (p_72786_1_ instanceof EntityFallingBlock)
{
this.addEntityToTracker(p_72786_1_, 160, 20, true);
}
else if (p_72786_1_ instanceof EntityHanging)
{
this.addEntityToTracker(p_72786_1_, 160, Integer.MAX_VALUE, false);
}
else if (p_72786_1_ instanceof EntityXPOrb)
{
this.addEntityToTracker(p_72786_1_, 160, 20, true);
}
else if (p_72786_1_ instanceof EntityEnderCrystal)
{
this.addEntityToTracker(p_72786_1_, 256, Integer.MAX_VALUE, false);
}
}
public void trackEntity(Entity p_72791_1_, int p_72791_2_, int p_72791_3_)
{
this.addEntityToTracker(p_72791_1_, p_72791_2_, p_72791_3_, false);
}
/**
* Args : Entity, trackingRange, updateFrequency, sendVelocityUpdates
*/
public void addEntityToTracker(Entity p_72785_1_, int p_72785_2_, final int p_72785_3_, boolean p_72785_4_)
{
if (p_72785_2_ > this.maxTrackingDistanceThreshold)
{
p_72785_2_ = this.maxTrackingDistanceThreshold;
}
try
{
if (this.trackedEntityHashTable.containsItem(p_72785_1_.getEntityId()))
{
throw new IllegalStateException("Entity is already tracked!");
}
EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(p_72785_1_, p_72785_2_, p_72785_3_, p_72785_4_);
this.trackedEntities.add(entitytrackerentry);
this.trackedEntityHashTable.addKey(p_72785_1_.getEntityId(), entitytrackerentry);
entitytrackerentry.updatePlayerEntities(this.theWorld.playerEntities);
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Adding entity to track");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity To Track");
crashreportcategory.addCrashSection("Tracking range", p_72785_2_ + " blocks");
crashreportcategory.addCrashSectionCallable("Update interval", new Callable()
{
private static final String __OBFID = "CL_00001432";
public String call()
{
String s = "Once per " + p_72785_3_ + " ticks";
if (p_72785_3_ == Integer.MAX_VALUE)
{
s = "Maximum (" + s + ")";
}
return s;
}
});
p_72785_1_.addEntityCrashInfo(crashreportcategory);
CrashReportCategory crashreportcategory1 = crashreport.makeCategory("Entity That Is Already Tracked");
((EntityTrackerEntry)this.trackedEntityHashTable.lookup(p_72785_1_.getEntityId())).trackedEntity.addEntityCrashInfo(crashreportcategory1);
try
{
throw new ReportedException(crashreport);
}
catch (ReportedException reportedexception)
{
logger.error("\"Silently\" catching entity tracking error.", reportedexception);
}
}
}
public void untrackEntity(Entity p_72790_1_)
{
if (p_72790_1_ instanceof EntityPlayerMP)
{
EntityPlayerMP entityplayermp = (EntityPlayerMP)p_72790_1_;
Iterator iterator = this.trackedEntities.iterator();
while (iterator.hasNext())
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
entitytrackerentry.removeFromTrackedPlayers(entityplayermp);
}
}
EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry)this.trackedEntityHashTable.removeObject(p_72790_1_.getEntityId());
if (entitytrackerentry1 != null)
{
this.trackedEntities.remove(entitytrackerentry1);
entitytrackerentry1.sendDestroyEntityPacketToTrackedPlayers();
}
}
public void updateTrackedEntities()
{
ArrayList arraylist = new ArrayList();
Iterator iterator = this.trackedEntities.iterator();
while (iterator.hasNext())
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
entitytrackerentry.updatePlayerList(this.theWorld.playerEntities);
if (entitytrackerentry.playerEntitiesUpdated && entitytrackerentry.trackedEntity instanceof EntityPlayerMP)
{
arraylist.add((EntityPlayerMP)entitytrackerentry.trackedEntity);
}
}
for (int i = 0; i < arraylist.size(); ++i)
{
EntityPlayerMP entityplayermp = (EntityPlayerMP)arraylist.get(i);
Iterator iterator1 = this.trackedEntities.iterator();
while (iterator1.hasNext())
{
EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry)iterator1.next();
if (entitytrackerentry1.trackedEntity != entityplayermp)
{
entitytrackerentry1.updatePlayerEntity(entityplayermp);
}
}
}
}
public void sendToAllTrackingEntity(Entity p_151247_1_, Packet p_151247_2_)
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)this.trackedEntityHashTable.lookup(p_151247_1_.getEntityId());
if (entitytrackerentry != null)
{
entitytrackerentry.func_151259_a(p_151247_2_);
}
}
public void func_151248_b(Entity p_151248_1_, Packet p_151248_2_)
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)this.trackedEntityHashTable.lookup(p_151248_1_.getEntityId());
if (entitytrackerentry != null)
{
entitytrackerentry.func_151261_b(p_151248_2_);
}
}
public void removePlayerFromTrackers(EntityPlayerMP p_72787_1_)
{
Iterator iterator = this.trackedEntities.iterator();
while (iterator.hasNext())
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
entitytrackerentry.removeTrackedPlayerSymmetric(p_72787_1_);
}
}
public void func_85172_a(EntityPlayerMP p_85172_1_, Chunk p_85172_2_)
{
Iterator iterator = this.trackedEntities.iterator();
while (iterator.hasNext())
{
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
if (entitytrackerentry.trackedEntity != p_85172_1_ && entitytrackerentry.trackedEntity.chunkCoordX == p_85172_2_.xPosition && entitytrackerentry.trackedEntity.chunkCoordZ == p_85172_2_.zPosition)
{
entitytrackerentry.updatePlayerEntity(p_85172_1_);
}
}
}
/* ======================================== FORGE START =====================================*/
// don't expose the EntityTrackerEntry directly so mods can't mess with the data in there as easily
/**
* Get all players tracking the given Entity. The Entity must be part of the World that this Tracker belongs to.
* @param entity the Entity
* @return all players tracking the Entity
*/
public Set<net.minecraft.entity.player.EntityPlayer> getTrackingPlayers(Entity entity)
{
EntityTrackerEntry entry = (EntityTrackerEntry) trackedEntityHashTable.lookup(entity.getEntityId());
if (entry == null)
return java.util.Collections.emptySet();
else
return java.util.Collections.unmodifiableSet(entry.trackingPlayers);
}
/* ======================================== FORGE END =====================================*/
}