001package net.minecraft.entity;
002
003import java.util.HashSet;
004import java.util.Iterator;
005import java.util.List;
006import java.util.Set;
007
008import cpw.mods.fml.common.network.FMLNetworkHandler;
009import net.minecraft.entity.boss.EntityDragon;
010import net.minecraft.entity.item.EntityBoat;
011import net.minecraft.entity.item.EntityEnderCrystal;
012import net.minecraft.entity.item.EntityEnderEye;
013import net.minecraft.entity.item.EntityEnderPearl;
014import net.minecraft.entity.item.EntityExpBottle;
015import net.minecraft.entity.item.EntityFallingSand;
016import net.minecraft.entity.item.EntityFireworkRocket;
017import net.minecraft.entity.item.EntityItem;
018import net.minecraft.entity.item.EntityItemFrame;
019import net.minecraft.entity.item.EntityMinecart;
020import net.minecraft.entity.item.EntityPainting;
021import net.minecraft.entity.item.EntityTNTPrimed;
022import net.minecraft.entity.item.EntityXPOrb;
023import net.minecraft.entity.passive.IAnimals;
024import net.minecraft.entity.player.EntityPlayer;
025import net.minecraft.entity.player.EntityPlayerMP;
026import net.minecraft.entity.projectile.EntityArrow;
027import net.minecraft.entity.projectile.EntityEgg;
028import net.minecraft.entity.projectile.EntityFireball;
029import net.minecraft.entity.projectile.EntityFishHook;
030import net.minecraft.entity.projectile.EntityPotion;
031import net.minecraft.entity.projectile.EntitySmallFireball;
032import net.minecraft.entity.projectile.EntitySnowball;
033import net.minecraft.entity.projectile.EntityWitherSkull;
034import net.minecraft.item.Item;
035import net.minecraft.item.ItemMap;
036import net.minecraft.item.ItemStack;
037import net.minecraft.network.packet.Packet;
038import net.minecraft.network.packet.Packet17Sleep;
039import net.minecraft.network.packet.Packet20NamedEntitySpawn;
040import net.minecraft.network.packet.Packet23VehicleSpawn;
041import net.minecraft.network.packet.Packet24MobSpawn;
042import net.minecraft.network.packet.Packet25EntityPainting;
043import net.minecraft.network.packet.Packet26EntityExpOrb;
044import net.minecraft.network.packet.Packet28EntityVelocity;
045import net.minecraft.network.packet.Packet31RelEntityMove;
046import net.minecraft.network.packet.Packet32EntityLook;
047import net.minecraft.network.packet.Packet33RelEntityMoveLook;
048import net.minecraft.network.packet.Packet34EntityTeleport;
049import net.minecraft.network.packet.Packet35EntityHeadRotation;
050import net.minecraft.network.packet.Packet39AttachEntity;
051import net.minecraft.network.packet.Packet40EntityMetadata;
052import net.minecraft.network.packet.Packet41EntityEffect;
053import net.minecraft.network.packet.Packet5PlayerInventory;
054import net.minecraft.potion.PotionEffect;
055import net.minecraft.util.MathHelper;
056import net.minecraft.world.storage.MapData;
057
058public class EntityTrackerEntry
059{
060    public Entity myEntity;
061    public int blocksDistanceThreshold;
062
063    /** check for sync when ticks % updateFrequency==0 */
064    public int updateFrequency;
065    public int lastScaledXPosition;
066    public int lastScaledYPosition;
067    public int lastScaledZPosition;
068    public int lastYaw;
069    public int lastPitch;
070    public int lastHeadMotion;
071    public double motionX;
072    public double motionY;
073    public double motionZ;
074    public int ticks = 0;
075    private double posX;
076    private double posY;
077    private double posZ;
078
079    /** set to true on first sendLocationToClients */
080    private boolean isDataInitialized = false;
081    private boolean sendVelocityUpdates;
082
083    /**
084     * every 400 ticks a  full teleport packet is sent, rather than just a "move me +x" command, so that position
085     * remains fully synced.
086     */
087    private int ticksSinceLastForcedTeleport = 0;
088    private Entity field_85178_v;
089    private boolean ridingEntity = false;
090    public boolean playerEntitiesUpdated = false;
091    public Set trackedPlayers = new HashSet();
092
093    public EntityTrackerEntry(Entity par1Entity, int par2, int par3, boolean par4)
094    {
095        this.myEntity = par1Entity;
096        this.blocksDistanceThreshold = par2;
097        this.updateFrequency = par3;
098        this.sendVelocityUpdates = par4;
099        this.lastScaledXPosition = MathHelper.floor_double(par1Entity.posX * 32.0D);
100        this.lastScaledYPosition = MathHelper.floor_double(par1Entity.posY * 32.0D);
101        this.lastScaledZPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D);
102        this.lastYaw = MathHelper.floor_float(par1Entity.rotationYaw * 256.0F / 360.0F);
103        this.lastPitch = MathHelper.floor_float(par1Entity.rotationPitch * 256.0F / 360.0F);
104        this.lastHeadMotion = MathHelper.floor_float(par1Entity.setRotationYawHead() * 256.0F / 360.0F);
105    }
106
107    public boolean equals(Object par1Obj)
108    {
109        return par1Obj instanceof EntityTrackerEntry ? ((EntityTrackerEntry)par1Obj).myEntity.entityId == this.myEntity.entityId : false;
110    }
111
112    public int hashCode()
113    {
114        return this.myEntity.entityId;
115    }
116
117    /**
118     * also sends velocity, rotation, and riding info.
119     */
120    public void sendLocationToAllClients(List par1List)
121    {
122        this.playerEntitiesUpdated = false;
123
124        if (!this.isDataInitialized || this.myEntity.getDistanceSq(this.posX, this.posY, this.posZ) > 16.0D)
125        {
126            this.posX = this.myEntity.posX;
127            this.posY = this.myEntity.posY;
128            this.posZ = this.myEntity.posZ;
129            this.isDataInitialized = true;
130            this.playerEntitiesUpdated = true;
131            this.sendEventsToPlayers(par1List);
132        }
133
134        if (this.field_85178_v != this.myEntity.ridingEntity)
135        {
136            this.field_85178_v = this.myEntity.ridingEntity;
137            this.sendPacketToAllTrackingPlayers(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity));
138        }
139
140        if (this.myEntity instanceof EntityItemFrame && this.ticks % 10 == 0)
141        {
142            EntityItemFrame var23 = (EntityItemFrame)this.myEntity;
143            ItemStack var24 = var23.getDisplayedItem();
144
145            if (var24 != null && var24.getItem() instanceof ItemMap)
146            {
147                MapData var26 = Item.map.getMapData(var24, this.myEntity.worldObj);
148                Iterator var29 = par1List.iterator();
149
150                while (var29.hasNext())
151                {
152                    EntityPlayer var30 = (EntityPlayer)var29.next();
153                    EntityPlayerMP var31 = (EntityPlayerMP)var30;
154                    var26.updateVisiblePlayers(var31, var24);
155
156                    if (var31.playerNetServerHandler.packetSize() <= 5)
157                    {
158                        Packet var32 = Item.map.createMapDataPacket(var24, this.myEntity.worldObj, var31);
159
160                        if (var32 != null)
161                        {
162                            var31.playerNetServerHandler.sendPacketToPlayer(var32);
163                        }
164                    }
165                }
166            }
167
168            DataWatcher var28 = this.myEntity.getDataWatcher();
169
170            if (var28.hasChanges())
171            {
172                this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, var28, false));
173            }
174        }
175        else if (this.ticks++ % this.updateFrequency == 0 || this.myEntity.isAirBorne)
176        {
177            int var2;
178            int var3;
179
180            if (this.myEntity.ridingEntity == null)
181            {
182                ++this.ticksSinceLastForcedTeleport;
183                var2 = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX);
184                var3 = MathHelper.floor_double(this.myEntity.posY * 32.0D);
185                int var4 = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ);
186                int var5 = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F);
187                int var6 = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F);
188                int var7 = var2 - this.lastScaledXPosition;
189                int var8 = var3 - this.lastScaledYPosition;
190                int var9 = var4 - this.lastScaledZPosition;
191                Object var10 = null;
192                boolean var11 = Math.abs(var7) >= 4 || Math.abs(var8) >= 4 || Math.abs(var9) >= 4 || this.ticks % 60 == 0;
193                boolean var12 = Math.abs(var5 - this.lastYaw) >= 4 || Math.abs(var6 - this.lastPitch) >= 4;
194
195                if (var7 >= -128 && var7 < 128 && var8 >= -128 && var8 < 128 && var9 >= -128 && var9 < 128 && this.ticksSinceLastForcedTeleport <= 400 && !this.ridingEntity)
196                {
197                    if (var11 && var12)
198                    {
199                        var10 = new Packet33RelEntityMoveLook(this.myEntity.entityId, (byte)var7, (byte)var8, (byte)var9, (byte)var5, (byte)var6);
200                    }
201                    else if (var11)
202                    {
203                        var10 = new Packet31RelEntityMove(this.myEntity.entityId, (byte)var7, (byte)var8, (byte)var9);
204                    }
205                    else if (var12)
206                    {
207                        var10 = new Packet32EntityLook(this.myEntity.entityId, (byte)var5, (byte)var6);
208                    }
209                }
210                else
211                {
212                    this.ticksSinceLastForcedTeleport = 0;
213                    var10 = new Packet34EntityTeleport(this.myEntity.entityId, var2, var3, var4, (byte)var5, (byte)var6);
214                }
215
216                if (this.sendVelocityUpdates)
217                {
218                    double var13 = this.myEntity.motionX - this.motionX;
219                    double var15 = this.myEntity.motionY - this.motionY;
220                    double var17 = this.myEntity.motionZ - this.motionZ;
221                    double var19 = 0.02D;
222                    double var21 = var13 * var13 + var15 * var15 + var17 * var17;
223
224                    if (var21 > var19 * var19 || var21 > 0.0D && this.myEntity.motionX == 0.0D && this.myEntity.motionY == 0.0D && this.myEntity.motionZ == 0.0D)
225                    {
226                        this.motionX = this.myEntity.motionX;
227                        this.motionY = this.myEntity.motionY;
228                        this.motionZ = this.myEntity.motionZ;
229                        this.sendPacketToAllTrackingPlayers(new Packet28EntityVelocity(this.myEntity.entityId, this.motionX, this.motionY, this.motionZ));
230                    }
231                }
232
233                if (var10 != null)
234                {
235                    this.sendPacketToAllTrackingPlayers((Packet)var10);
236                }
237
238                DataWatcher var33 = this.myEntity.getDataWatcher();
239
240                if (var33.hasChanges())
241                {
242                    this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, var33, false));
243                }
244
245                if (var11)
246                {
247                    this.lastScaledXPosition = var2;
248                    this.lastScaledYPosition = var3;
249                    this.lastScaledZPosition = var4;
250                }
251
252                if (var12)
253                {
254                    this.lastYaw = var5;
255                    this.lastPitch = var6;
256                }
257
258                this.ridingEntity = false;
259            }
260            else
261            {
262                var2 = MathHelper.floor_float(this.myEntity.rotationYaw * 256.0F / 360.0F);
263                var3 = MathHelper.floor_float(this.myEntity.rotationPitch * 256.0F / 360.0F);
264                boolean var25 = Math.abs(var2 - this.lastYaw) >= 4 || Math.abs(var3 - this.lastPitch) >= 4;
265
266                if (var25)
267                {
268                    this.sendPacketToAllTrackingPlayers(new Packet32EntityLook(this.myEntity.entityId, (byte)var2, (byte)var3));
269                    this.lastYaw = var2;
270                    this.lastPitch = var3;
271                }
272
273                this.lastScaledXPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posX);
274                this.lastScaledYPosition = MathHelper.floor_double(this.myEntity.posY * 32.0D);
275                this.lastScaledZPosition = this.myEntity.myEntitySize.multiplyBy32AndRound(this.myEntity.posZ);
276                DataWatcher var27 = this.myEntity.getDataWatcher();
277
278                if (var27.hasChanges())
279                {
280                    this.sendPacketToAllAssociatedPlayers(new Packet40EntityMetadata(this.myEntity.entityId, var27, false));
281                }
282
283                this.ridingEntity = true;
284            }
285
286            var2 = MathHelper.floor_float(this.myEntity.setRotationYawHead() * 256.0F / 360.0F);
287
288            if (Math.abs(var2 - this.lastHeadMotion) >= 4)
289            {
290                this.sendPacketToAllTrackingPlayers(new Packet35EntityHeadRotation(this.myEntity.entityId, (byte)var2));
291                this.lastHeadMotion = var2;
292            }
293
294            this.myEntity.isAirBorne = false;
295        }
296
297        if (this.myEntity.velocityChanged)
298        {
299            this.sendPacketToAllAssociatedPlayers(new Packet28EntityVelocity(this.myEntity));
300            this.myEntity.velocityChanged = false;
301        }
302    }
303
304    /**
305     * if this is a player, then it is not informed
306     */
307    public void sendPacketToAllTrackingPlayers(Packet par1Packet)
308    {
309        Iterator var2 = this.trackedPlayers.iterator();
310
311        while (var2.hasNext())
312        {
313            EntityPlayerMP var3 = (EntityPlayerMP)var2.next();
314            var3.playerNetServerHandler.sendPacketToPlayer(par1Packet);
315        }
316    }
317
318    /**
319     * if this is a player, then it recieves the message also
320     */
321    public void sendPacketToAllAssociatedPlayers(Packet par1Packet)
322    {
323        this.sendPacketToAllTrackingPlayers(par1Packet);
324
325        if (this.myEntity instanceof EntityPlayerMP)
326        {
327            ((EntityPlayerMP)this.myEntity).playerNetServerHandler.sendPacketToPlayer(par1Packet);
328        }
329    }
330
331    public void informAllAssociatedPlayersOfItemDestruction()
332    {
333        Iterator var1 = this.trackedPlayers.iterator();
334
335        while (var1.hasNext())
336        {
337            EntityPlayerMP var2 = (EntityPlayerMP)var1.next();
338            var2.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
339        }
340    }
341
342    public void removeFromWatchingList(EntityPlayerMP par1EntityPlayerMP)
343    {
344        if (this.trackedPlayers.contains(par1EntityPlayerMP))
345        {
346            par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
347            this.trackedPlayers.remove(par1EntityPlayerMP);
348        }
349    }
350
351    /**
352     * if the player is more than the distance threshold (typically 64) then the player is removed instead
353     */
354    public void tryStartWachingThis(EntityPlayerMP par1EntityPlayerMP)
355    {
356        if (par1EntityPlayerMP != this.myEntity)
357        {
358            double var2 = par1EntityPlayerMP.posX - (double)(this.lastScaledXPosition / 32);
359            double var4 = par1EntityPlayerMP.posZ - (double)(this.lastScaledZPosition / 32);
360
361            if (var2 >= (double)(-this.blocksDistanceThreshold) && var2 <= (double)this.blocksDistanceThreshold && var4 >= (double)(-this.blocksDistanceThreshold) && var4 <= (double)this.blocksDistanceThreshold)
362            {
363                if (!this.trackedPlayers.contains(par1EntityPlayerMP) && this.isPlayerWatchingThisChunk(par1EntityPlayerMP))
364                {
365                    this.trackedPlayers.add(par1EntityPlayerMP);
366                    Packet var6 = this.getPacketForThisEntity();
367                    par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(var6);
368
369                    if (!this.myEntity.getDataWatcher().func_92085_d())
370                    {
371                        par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet40EntityMetadata(this.myEntity.entityId, this.myEntity.getDataWatcher(), true));
372                    }
373
374                    this.motionX = this.myEntity.motionX;
375                    this.motionY = this.myEntity.motionY;
376                    this.motionZ = this.myEntity.motionZ;
377                    
378                    int posX = MathHelper.floor_double(this.myEntity.posX * 32.0D);
379                    int posY = MathHelper.floor_double(this.myEntity.posY * 32.0D);
380                    int posZ = MathHelper.floor_double(this.myEntity.posZ * 32.0D);
381                    if (posX != this.lastScaledXPosition || posY != this.lastScaledYPosition || posZ != this.lastScaledZPosition)
382                    {
383                        FMLNetworkHandler.makeEntitySpawnAdjustment(this.myEntity.entityId, par1EntityPlayerMP, this.lastScaledXPosition, this.lastScaledYPosition, this.lastScaledZPosition);
384                    }
385
386                    if (this.sendVelocityUpdates && !(var6 instanceof Packet24MobSpawn))
387                    {
388                        par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet28EntityVelocity(this.myEntity.entityId, this.myEntity.motionX, this.myEntity.motionY, this.myEntity.motionZ));
389                    }
390
391                    if (this.myEntity.ridingEntity != null)
392                    {
393                        par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet39AttachEntity(this.myEntity, this.myEntity.ridingEntity));
394                    }
395
396                    if (this.myEntity instanceof EntityLiving)
397                    {
398                        for (int var7 = 0; var7 < 5; ++var7)
399                        {
400                            ItemStack var8 = ((EntityLiving)this.myEntity).getCurrentItemOrArmor(var7);
401
402                            if (var8 != null)
403                            {
404                                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet5PlayerInventory(this.myEntity.entityId, var7, var8));
405                            }
406                        }
407                    }
408
409                    if (this.myEntity instanceof EntityPlayer)
410                    {
411                        EntityPlayer var11 = (EntityPlayer)this.myEntity;
412
413                        if (var11.isPlayerSleeping())
414                        {
415                            par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet17Sleep(this.myEntity, 0, MathHelper.floor_double(this.myEntity.posX), MathHelper.floor_double(this.myEntity.posY), MathHelper.floor_double(this.myEntity.posZ)));
416                        }
417                    }
418
419                    if (this.myEntity instanceof EntityLiving)
420                    {
421                        EntityLiving var10 = (EntityLiving)this.myEntity;
422                        Iterator var12 = var10.getActivePotionEffects().iterator();
423
424                        while (var12.hasNext())
425                        {
426                            PotionEffect var9 = (PotionEffect)var12.next();
427                            par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(this.myEntity.entityId, var9));
428                        }
429                    }
430                }
431            }
432            else if (this.trackedPlayers.contains(par1EntityPlayerMP))
433            {
434                this.trackedPlayers.remove(par1EntityPlayerMP);
435                par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
436            }
437        }
438    }
439
440    private boolean isPlayerWatchingThisChunk(EntityPlayerMP par1EntityPlayerMP)
441    {
442        return par1EntityPlayerMP.getServerForPlayer().getPlayerManager().isPlayerWatchingChunk(par1EntityPlayerMP, this.myEntity.chunkCoordX, this.myEntity.chunkCoordZ);
443    }
444
445    public void sendEventsToPlayers(List par1List)
446    {
447        for (int var2 = 0; var2 < par1List.size(); ++var2)
448        {
449            this.tryStartWachingThis((EntityPlayerMP)par1List.get(var2));
450        }
451    }
452
453    private Packet getPacketForThisEntity()
454    {
455        if (this.myEntity.isDead)
456        {
457            System.out.println("Fetching addPacket for removed entity");
458        }
459
460        Packet pkt = FMLNetworkHandler.getEntitySpawningPacket(this.myEntity);
461
462        if (pkt != null)
463        {
464            return pkt;
465        }
466
467        if (this.myEntity instanceof EntityItem)
468        {
469            return new Packet23VehicleSpawn(this.myEntity, 2, 1);
470        }
471        else if (this.myEntity instanceof EntityPlayerMP)
472        {
473            return new Packet20NamedEntitySpawn((EntityPlayer)this.myEntity);
474        }
475        else
476        {
477            if (this.myEntity instanceof EntityMinecart)
478            {
479                EntityMinecart var1 = (EntityMinecart)this.myEntity;
480
481                if (var1.minecartType == 0)
482                {
483                    return new Packet23VehicleSpawn(this.myEntity, 10);
484                }
485
486                if (var1.minecartType == 1)
487                {
488                    return new Packet23VehicleSpawn(this.myEntity, 11);
489                }
490
491                if (var1.minecartType == 2)
492                {
493                    return new Packet23VehicleSpawn(this.myEntity, 12);
494                }
495            }
496
497            if (this.myEntity instanceof EntityBoat)
498            {
499                return new Packet23VehicleSpawn(this.myEntity, 1);
500            }
501            else if (!(this.myEntity instanceof IAnimals) && !(this.myEntity instanceof EntityDragon))
502            {
503                if (this.myEntity instanceof EntityFishHook)
504                {
505                    EntityPlayer var8 = ((EntityFishHook)this.myEntity).angler;
506                    return new Packet23VehicleSpawn(this.myEntity, 90, var8 != null ? var8.entityId : this.myEntity.entityId);
507                }
508                else if (this.myEntity instanceof EntityArrow)
509                {
510                    Entity var7 = ((EntityArrow)this.myEntity).shootingEntity;
511                    return new Packet23VehicleSpawn(this.myEntity, 60, var7 != null ? var7.entityId : this.myEntity.entityId);
512                }
513                else if (this.myEntity instanceof EntitySnowball)
514                {
515                    return new Packet23VehicleSpawn(this.myEntity, 61);
516                }
517                else if (this.myEntity instanceof EntityPotion)
518                {
519                    return new Packet23VehicleSpawn(this.myEntity, 73, ((EntityPotion)this.myEntity).getPotionDamage());
520                }
521                else if (this.myEntity instanceof EntityExpBottle)
522                {
523                    return new Packet23VehicleSpawn(this.myEntity, 75);
524                }
525                else if (this.myEntity instanceof EntityEnderPearl)
526                {
527                    return new Packet23VehicleSpawn(this.myEntity, 65);
528                }
529                else if (this.myEntity instanceof EntityEnderEye)
530                {
531                    return new Packet23VehicleSpawn(this.myEntity, 72);
532                }
533                else if (this.myEntity instanceof EntityFireworkRocket)
534                {
535                    return new Packet23VehicleSpawn(this.myEntity, 76);
536                }
537                else
538                {
539                    Packet23VehicleSpawn var2;
540
541                    if (this.myEntity instanceof EntityFireball)
542                    {
543                        EntityFireball var6 = (EntityFireball)this.myEntity;
544                        var2 = null;
545                        byte var3 = 63;
546
547                        if (this.myEntity instanceof EntitySmallFireball)
548                        {
549                            var3 = 64;
550                        }
551                        else if (this.myEntity instanceof EntityWitherSkull)
552                        {
553                            var3 = 66;
554                        }
555
556                        if (var6.shootingEntity != null)
557                        {
558                            var2 = new Packet23VehicleSpawn(this.myEntity, var3, ((EntityFireball)this.myEntity).shootingEntity.entityId);
559                        }
560                        else
561                        {
562                            var2 = new Packet23VehicleSpawn(this.myEntity, var3, 0);
563                        }
564
565                        var2.speedX = (int)(var6.accelerationX * 8000.0D);
566                        var2.speedY = (int)(var6.accelerationY * 8000.0D);
567                        var2.speedZ = (int)(var6.accelerationZ * 8000.0D);
568                        return var2;
569                    }
570                    else if (this.myEntity instanceof EntityEgg)
571                    {
572                        return new Packet23VehicleSpawn(this.myEntity, 62);
573                    }
574                    else if (this.myEntity instanceof EntityTNTPrimed)
575                    {
576                        return new Packet23VehicleSpawn(this.myEntity, 50);
577                    }
578                    else if (this.myEntity instanceof EntityEnderCrystal)
579                    {
580                        return new Packet23VehicleSpawn(this.myEntity, 51);
581                    }
582                    else if (this.myEntity instanceof EntityFallingSand)
583                    {
584                        EntityFallingSand var5 = (EntityFallingSand)this.myEntity;
585                        return new Packet23VehicleSpawn(this.myEntity, 70, var5.blockID | var5.metadata << 16);
586                    }
587                    else if (this.myEntity instanceof EntityPainting)
588                    {
589                        return new Packet25EntityPainting((EntityPainting)this.myEntity);
590                    }
591                    else if (this.myEntity instanceof EntityItemFrame)
592                    {
593                        EntityItemFrame var4 = (EntityItemFrame)this.myEntity;
594                        var2 = new Packet23VehicleSpawn(this.myEntity, 71, var4.hangingDirection);
595                        var2.xPosition = MathHelper.floor_float((float)(var4.xPosition * 32));
596                        var2.yPosition = MathHelper.floor_float((float)(var4.yPosition * 32));
597                        var2.zPosition = MathHelper.floor_float((float)(var4.zPosition * 32));
598                        return var2;
599                    }
600                    else if (this.myEntity instanceof EntityXPOrb)
601                    {
602                        return new Packet26EntityExpOrb((EntityXPOrb)this.myEntity);
603                    }
604                    else
605                    {
606                        throw new IllegalArgumentException("Don\'t know how to add " + this.myEntity.getClass() + "!");
607                    }
608                }
609            }
610            else
611            {
612                this.lastHeadMotion = MathHelper.floor_float(this.myEntity.setRotationYawHead() * 256.0F / 360.0F);
613                return new Packet24MobSpawn((EntityLiving)this.myEntity);
614            }
615        }
616    }
617
618    public void removePlayerFromTracker(EntityPlayerMP par1EntityPlayerMP)
619    {
620        if (this.trackedPlayers.contains(par1EntityPlayerMP))
621        {
622            this.trackedPlayers.remove(par1EntityPlayerMP);
623            par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.myEntity.entityId));
624        }
625    }
626}