001    package net.minecraft.entity;
002    
003    import java.util.ArrayList;
004    import java.util.HashSet;
005    import java.util.Iterator;
006    import java.util.Set;
007    
008    import cpw.mods.fml.common.registry.EntityRegistry;
009    import net.minecraft.entity.boss.EntityDragon;
010    import net.minecraft.entity.boss.EntityWither;
011    import net.minecraft.entity.item.EntityBoat;
012    import net.minecraft.entity.item.EntityEnderCrystal;
013    import net.minecraft.entity.item.EntityEnderEye;
014    import net.minecraft.entity.item.EntityEnderPearl;
015    import net.minecraft.entity.item.EntityExpBottle;
016    import net.minecraft.entity.item.EntityFallingSand;
017    import net.minecraft.entity.item.EntityFireworkRocket;
018    import net.minecraft.entity.item.EntityItem;
019    import net.minecraft.entity.item.EntityItemFrame;
020    import net.minecraft.entity.item.EntityMinecart;
021    import net.minecraft.entity.item.EntityPainting;
022    import net.minecraft.entity.item.EntityTNTPrimed;
023    import net.minecraft.entity.item.EntityXPOrb;
024    import net.minecraft.entity.passive.EntityBat;
025    import net.minecraft.entity.passive.EntitySquid;
026    import net.minecraft.entity.passive.IAnimals;
027    import net.minecraft.entity.player.EntityPlayerMP;
028    import net.minecraft.entity.projectile.EntityArrow;
029    import net.minecraft.entity.projectile.EntityEgg;
030    import net.minecraft.entity.projectile.EntityFireball;
031    import net.minecraft.entity.projectile.EntityFishHook;
032    import net.minecraft.entity.projectile.EntityPotion;
033    import net.minecraft.entity.projectile.EntitySmallFireball;
034    import net.minecraft.entity.projectile.EntitySnowball;
035    import net.minecraft.network.packet.Packet;
036    import net.minecraft.util.IntHashMap;
037    import net.minecraft.world.WorldServer;
038    import net.minecraft.world.chunk.Chunk;
039    
040    public 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    }