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}