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