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 else 204 { 205 EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(par1Entity, par2, par3, par4); 206 this.trackedEntities.add(entitytrackerentry); 207 this.trackedEntityIDs.addKey(par1Entity.entityId, entitytrackerentry); 208 entitytrackerentry.sendEventsToPlayers(this.theWorld.playerEntities); 209 } 210 } 211 catch (Throwable throwable) 212 { 213 CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Adding entity to track"); 214 CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity To Track"); 215 crashreportcategory.addCrashSection("Tracking range", par2 + " blocks"); 216 crashreportcategory.addCrashSectionCallable("Update interval", new CallableEntityTracker(this, par3)); 217 par1Entity.func_85029_a(crashreportcategory); 218 throw new ReportedException(crashreport); 219 } 220 } 221 222 public void removeEntityFromAllTrackingPlayers(Entity par1Entity) 223 { 224 if (par1Entity instanceof EntityPlayerMP) 225 { 226 EntityPlayerMP entityplayermp = (EntityPlayerMP)par1Entity; 227 Iterator iterator = this.trackedEntities.iterator(); 228 229 while (iterator.hasNext()) 230 { 231 EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); 232 entitytrackerentry.removeFromWatchingList(entityplayermp); 233 } 234 } 235 236 EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry)this.trackedEntityIDs.removeObject(par1Entity.entityId); 237 238 if (entitytrackerentry1 != null) 239 { 240 this.trackedEntities.remove(entitytrackerentry1); 241 entitytrackerentry1.informAllAssociatedPlayersOfItemDestruction(); 242 } 243 } 244 245 public void updateTrackedEntities() 246 { 247 ArrayList arraylist = new ArrayList(); 248 Iterator iterator = this.trackedEntities.iterator(); 249 250 while (iterator.hasNext()) 251 { 252 EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); 253 entitytrackerentry.sendLocationToAllClients(this.theWorld.playerEntities); 254 255 if (entitytrackerentry.playerEntitiesUpdated && entitytrackerentry.myEntity instanceof EntityPlayerMP) 256 { 257 arraylist.add((EntityPlayerMP)entitytrackerentry.myEntity); 258 } 259 } 260 261 for (int i = 0; i < arraylist.size(); ++i) 262 { 263 EntityPlayerMP entityplayermp = (EntityPlayerMP)arraylist.get(i); 264 Iterator iterator1 = this.trackedEntities.iterator(); 265 266 while (iterator1.hasNext()) 267 { 268 EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry)iterator1.next(); 269 270 if (entitytrackerentry1.myEntity != entityplayermp) 271 { 272 entitytrackerentry1.tryStartWachingThis(entityplayermp); 273 } 274 } 275 } 276 } 277 278 /** 279 * does not send the packet to the entity if the entity is a player 280 */ 281 public void sendPacketToAllPlayersTrackingEntity(Entity par1Entity, Packet par2Packet) 282 { 283 EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)this.trackedEntityIDs.lookup(par1Entity.entityId); 284 285 if (entitytrackerentry != null) 286 { 287 entitytrackerentry.sendPacketToAllTrackingPlayers(par2Packet); 288 } 289 } 290 291 /** 292 * sends to the entity if the entity is a player 293 */ 294 public void sendPacketToAllAssociatedPlayers(Entity par1Entity, Packet par2Packet) 295 { 296 EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)this.trackedEntityIDs.lookup(par1Entity.entityId); 297 298 if (entitytrackerentry != null) 299 { 300 entitytrackerentry.sendPacketToAllAssociatedPlayers(par2Packet); 301 } 302 } 303 304 public void removePlayerFromTrackers(EntityPlayerMP par1EntityPlayerMP) 305 { 306 Iterator iterator = this.trackedEntities.iterator(); 307 308 while (iterator.hasNext()) 309 { 310 EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); 311 entitytrackerentry.removePlayerFromTracker(par1EntityPlayerMP); 312 } 313 } 314 315 public void func_85172_a(EntityPlayerMP par1EntityPlayerMP, Chunk par2Chunk) 316 { 317 Iterator iterator = this.trackedEntities.iterator(); 318 319 while (iterator.hasNext()) 320 { 321 EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); 322 323 if (entitytrackerentry.myEntity != par1EntityPlayerMP && entitytrackerentry.myEntity.chunkCoordX == par2Chunk.xPosition && entitytrackerentry.myEntity.chunkCoordZ == par2Chunk.zPosition) 324 { 325 entitytrackerentry.tryStartWachingThis(par1EntityPlayerMP); 326 } 327 } 328 } 329}