    001package net.minecraft.entity;
    002
    003import java.util.ArrayList;
    004import java.util.HashSet;
    005import java.util.Iterator;
    006import java.util.Set;
    007
    008import cpw.mods.fml.common.registry.EntityRegistry;
    009import net.minecraft.entity.boss.EntityDragon;
    010import net.minecraft.entity.boss.EntityWither;
    011import net.minecraft.entity.item.EntityBoat;
    012import net.minecraft.entity.item.EntityEnderCrystal;
    013import net.minecraft.entity.item.EntityEnderEye;
    014import net.minecraft.entity.item.EntityEnderPearl;
    015import net.minecraft.entity.item.EntityExpBottle;
    016import net.minecraft.entity.item.EntityFallingSand;
    017import net.minecraft.entity.item.EntityFireworkRocket;
    018import net.minecraft.entity.item.EntityItem;
    019import net.minecraft.entity.item.EntityItemFrame;
    020import net.minecraft.entity.item.EntityMinecart;
    021import net.minecraft.entity.item.EntityPainting;
    022import net.minecraft.entity.item.EntityTNTPrimed;
    023import net.minecraft.entity.item.EntityXPOrb;
    024import net.minecraft.entity.passive.EntityBat;
    025import net.minecraft.entity.passive.EntitySquid;
    026import net.minecraft.entity.passive.IAnimals;
    027import net.minecraft.entity.player.EntityPlayerMP;
    028import net.minecraft.entity.projectile.EntityArrow;
    029import net.minecraft.entity.projectile.EntityEgg;
    030import net.minecraft.entity.projectile.EntityFireball;
    031import net.minecraft.entity.projectile.EntityFishHook;
    032import net.minecraft.entity.projectile.EntityPotion;
    033import net.minecraft.entity.projectile.EntitySmallFireball;
    034import net.minecraft.entity.projectile.EntitySnowball;
    035import net.minecraft.network.packet.Packet;
    036import net.minecraft.util.IntHashMap;
    037import net.minecraft.world.WorldServer;
    038import net.minecraft.world.chunk.Chunk;
    039
    040public class EntityTracker
    041{
    042    private final WorldServer theWorld;
    043    private Set trackedEntities = new HashSet();
    044    private IntHashMap trackedEntityIDs = new IntHashMap();
    045    private int entityViewDistance;
    046
    047    public EntityTracker(WorldServer par1WorldServer)
    048    {
    049        this.theWorld = par1WorldServer;
    050        this.entityViewDistance = par1WorldServer.getMinecraftServer().getConfigurationManager().getEntityViewDistance();
    051    }
    052
    053    /**
    054     * if entity is a player sends all tracked events to the player, otherwise, adds with a visibility and update arate
    055     * based on the class type
    056     */
    057    public void addEntityToTracker(Entity par1Entity)
    058    {
    059        if (EntityRegistry.instance().tryTrackingEntity(this, par1Entity))
    060        {
    061            return;
    062        }
    063
    064        if (par1Entity instanceof EntityPlayerMP)
    065        {
    066            this.addEntityToTracker(par1Entity, 512, 2);
    067            EntityPlayerMP var2 = (EntityPlayerMP)par1Entity;
    068            Iterator var3 = this.trackedEntities.iterator();
    069
    070            while (var3.hasNext())
    071            {
    072                EntityTrackerEntry var4 = (EntityTrackerEntry)var3.next();
    073
    074                if (var4.myEntity != var2)
    075                {
    076                    var4.tryStartWachingThis(var2);
    077                }
    078            }
    079        }
    080        else if (par1Entity instanceof EntityFishHook)
    081        {
    082            this.addEntityToTracker(par1Entity, 64, 5, true);
    083        }
    084        else if (par1Entity instanceof EntityArrow)
    085        {
    086            this.addEntityToTracker(par1Entity, 64, 20, false);
    087        }
    088        else if (par1Entity instanceof EntitySmallFireball)
    089        {
    090            this.addEntityToTracker(par1Entity, 64, 10, false);
    091        }
    092        else if (par1Entity instanceof EntityFireball)
    093        {
    094            this.addEntityToTracker(par1Entity, 64, 10, false);
    095        }
    096        else if (par1Entity instanceof EntitySnowball)
    097        {
    098            this.addEntityToTracker(par1Entity, 64, 10, true);
    099        }
    100        else if (par1Entity instanceof EntityEnderPearl)
    101        {
    102            this.addEntityToTracker(par1Entity, 64, 10, true);
    103        }
    104        else if (par1Entity instanceof EntityEnderEye)
    105        {
    106            this.addEntityToTracker(par1Entity, 64, 4, true);
    107        }
    108        else if (par1Entity instanceof EntityEgg)
    109        {
    110            this.addEntityToTracker(par1Entity, 64, 10, true);
    111        }
    112        else if (par1Entity instanceof EntityPotion)
    113        {
    114            this.addEntityToTracker(par1Entity, 64, 10, true);
    115        }
    116        else if (par1Entity instanceof EntityExpBottle)
    117        {
    118            this.addEntityToTracker(par1Entity, 64, 10, true);
    119        }
    120        else if (par1Entity instanceof EntityFireworkRocket)
    121        {
    122            this.addEntityToTracker(par1Entity, 64, 10, true);
    123        }
    124        else if (par1Entity instanceof EntityItem)
    125        {
    126            this.addEntityToTracker(par1Entity, 64, 20, true);
    127        }
    128        else if (par1Entity instanceof EntityMinecart)
    129        {
    130            this.addEntityToTracker(par1Entity, 80, 3, true);
    131        }
    132        else if (par1Entity instanceof EntityBoat)
    133        {
    134            this.addEntityToTracker(par1Entity, 80, 3, true);
    135        }
    136        else if (par1Entity instanceof EntitySquid)
    137        {
    138            this.addEntityToTracker(par1Entity, 64, 3, true);
    139        }
    140        else if (par1Entity instanceof EntityWither)
    141        {
    142            this.addEntityToTracker(par1Entity, 80, 3, false);
    143        }
    144        else if (par1Entity instanceof EntityBat)
    145        {
    146            this.addEntityToTracker(par1Entity, 80, 3, false);
    147        }
    148        else if (par1Entity instanceof IAnimals)
    149        {
    150            this.addEntityToTracker(par1Entity, 80, 3, true);
    151        }
    152        else if (par1Entity instanceof EntityDragon)
    153        {
    154            this.addEntityToTracker(par1Entity, 160, 3, true);
    155        }
    156        else if (par1Entity instanceof EntityTNTPrimed)
    157        {
    158            this.addEntityToTracker(par1Entity, 160, 10, true);
    159        }
    160        else if (par1Entity instanceof EntityFallingSand)
    161        {
    162            this.addEntityToTracker(par1Entity, 160, 20, true);
    163        }
    164        else if (par1Entity instanceof EntityPainting)
    165        {
    166            this.addEntityToTracker(par1Entity, 160, Integer.MAX_VALUE, false);
    167        }
    168        else if (par1Entity instanceof EntityXPOrb)
    169        {
    170            this.addEntityToTracker(par1Entity, 160, 20, true);
    171        }
    172        else if (par1Entity instanceof EntityEnderCrystal)
    173        {
    174            this.addEntityToTracker(par1Entity, 256, Integer.MAX_VALUE, false);
    175        }
    176        else if (par1Entity instanceof EntityItemFrame)
    177        {
    178            this.addEntityToTracker(par1Entity, 160, Integer.MAX_VALUE, false);
    179        }
    180    }
    181
    182    public void addEntityToTracker(Entity par1Entity, int par2, int par3)
    183    {
    184        this.addEntityToTracker(par1Entity, par2, par3, false);
    185    }
    186
    187    public void addEntityToTracker(Entity par1Entity, int par2, int par3, boolean par4)
    188    {
    189        if (par2 > this.entityViewDistance)
    190        {
    191            par2 = this.entityViewDistance;
    192        }
    193
    194        if (this.trackedEntityIDs.containsItem(par1Entity.entityId))
    195        {
    196            throw new IllegalStateException("Entity is already tracked!");
    197        }
    198        else
    199        {
    200            EntityTrackerEntry var5 = new EntityTrackerEntry(par1Entity, par2, par3, par4);
    201            this.trackedEntities.add(var5);
    202            this.trackedEntityIDs.addKey(par1Entity.entityId, var5);
    203            var5.sendEventsToPlayers(this.theWorld.playerEntities);
    204        }
    205    }
    206
    207    public void removeEntityFromAllTrackingPlayers(Entity par1Entity)
    208    {
    209        if (par1Entity instanceof EntityPlayerMP)
    210        {
    211            EntityPlayerMP var2 = (EntityPlayerMP)par1Entity;
    212            Iterator var3 = this.trackedEntities.iterator();
    213
    214            while (var3.hasNext())
    215            {
    216                EntityTrackerEntry var4 = (EntityTrackerEntry)var3.next();
    217                var4.removeFromWatchingList(var2);
    218            }
    219        }
    220
    221        EntityTrackerEntry var5 = (EntityTrackerEntry)this.trackedEntityIDs.removeObject(par1Entity.entityId);
    222
    223        if (var5 != null)
    224        {
    225            this.trackedEntities.remove(var5);
    226            var5.informAllAssociatedPlayersOfItemDestruction();
    227        }
    228    }
    229
    230    public void updateTrackedEntities()
    231    {
    232        ArrayList var1 = new ArrayList();
    233        Iterator var2 = this.trackedEntities.iterator();
    234
    235        while (var2.hasNext())
    236        {
    237            EntityTrackerEntry var3 = (EntityTrackerEntry)var2.next();
    238            var3.sendLocationToAllClients(this.theWorld.playerEntities);
    239
    240            if (var3.playerEntitiesUpdated && var3.myEntity instanceof EntityPlayerMP)
    241            {
    242                var1.add((EntityPlayerMP)var3.myEntity);
    243            }
    244        }
    245
    246        for (int var6 = 0; var6 < var1.size(); ++var6)
    247        {
    248            EntityPlayerMP var7 = (EntityPlayerMP)var1.get(var6);
    249            Iterator var4 = this.trackedEntities.iterator();
    250
    251            while (var4.hasNext())
    252            {
    253                EntityTrackerEntry var5 = (EntityTrackerEntry)var4.next();
    254
    255                if (var5.myEntity != var7)
    256                {
    257                    var5.tryStartWachingThis(var7);
    258                }
    259            }
    260        }
    261    }
    262
    263    /**
    264     * does not send the packet to the entity if the entity is a player
    265     */
    266    public void sendPacketToAllPlayersTrackingEntity(Entity par1Entity, Packet par2Packet)
    267    {
    268        EntityTrackerEntry var3 = (EntityTrackerEntry)this.trackedEntityIDs.lookup(par1Entity.entityId);
    269
    270        if (var3 != null)
    271        {
    272            var3.sendPacketToAllTrackingPlayers(par2Packet);
    273        }
    274    }
    275
    276    /**
    277     * sends to the entity if the entity is a player
    278     */
    279    public void sendPacketToAllAssociatedPlayers(Entity par1Entity, Packet par2Packet)
    280    {
    281        EntityTrackerEntry var3 = (EntityTrackerEntry)this.trackedEntityIDs.lookup(par1Entity.entityId);
    282
    283        if (var3 != null)
    284        {
    285            var3.sendPacketToAllAssociatedPlayers(par2Packet);
    286        }
    287    }
    288
    289    public void removeAllTrackingPlayers(EntityPlayerMP par1EntityPlayerMP)
    290    {
    291        Iterator var2 = this.trackedEntities.iterator();
    292
    293        while (var2.hasNext())
    294        {
    295            EntityTrackerEntry var3 = (EntityTrackerEntry)var2.next();
    296            var3.removePlayerFromTracker(par1EntityPlayerMP);
    297        }
    298    }
    299
    300    public void func_85172_a(EntityPlayerMP par1EntityPlayerMP, Chunk par2Chunk)
    301    {
    302        Iterator var3 = this.trackedEntities.iterator();
    303
    304        while (var3.hasNext())
    305        {
    306            EntityTrackerEntry var4 = (EntityTrackerEntry)var3.next();
    307
    308            if (var4.myEntity != par1EntityPlayerMP && var4.myEntity.chunkCoordX == par2Chunk.xPosition && var4.myEntity.chunkCoordZ == par2Chunk.zPosition)
    309            {
    310                var4.tryStartWachingThis(par1EntityPlayerMP);
    311            }
    312        }
    313    }
    314}