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