    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.FMLCommonHandler;
    004    import cpw.mods.fml.common.Side;
    005    import cpw.mods.fml.common.asm.SideOnly;
    006    import cpw.mods.fml.common.network.FMLNetworkHandler;
    007
    008    import java.util.Iterator;
    009    import java.util.List;
    010
    011    import net.minecraftforge.common.ForgeHooks;
    012    import net.minecraftforge.common.ISpecialArmor.ArmorProperties;
    013    import net.minecraftforge.common.MinecraftForge;
    014    import net.minecraftforge.event.ForgeEventFactory;
    015    import net.minecraftforge.event.entity.living.LivingHurtEvent;
    016    import net.minecraftforge.event.entity.player.AttackEntityEvent;
    017    import net.minecraftforge.event.entity.player.EntityInteractEvent;
    018    import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
    019    import net.minecraftforge.event.entity.player.PlayerDropsEvent;
    020    import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent;
    021
    022    public abstract class EntityPlayer extends EntityLiving implements ICommandSender
    023    {
    024        /** Inventory of the player */
    025        public InventoryPlayer inventory = new InventoryPlayer(this);
    026        private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest();
    027
    028        /** the crafting inventory in you get when opening your inventory */
    029        public Container inventorySlots;
    030
    031        /** the crafting inventory you are currently using */
    032        public Container craftingInventory;
    033
    034        /** The player's food stats. (See class FoodStats) */
    035        protected FoodStats foodStats = new FoodStats();
    036
    037        /**
    038         * Used to tell if the player pressed jump twice. If this is at 0 and it's pressed (And they are allowed to fly, as
    039         * defined in the player's movementInput) it sets this to 7. If it's pressed and it's greater than 0 enable fly.
    040         */
    041        protected int flyToggleTimer = 0;
    042        public byte field_71098_bD = 0;
    043        public int score = 0;
    044        public float prevCameraYaw;
    045        public float cameraYaw;
    046
    047        /** Whether the player is swinging the current item in their hand. */
    048        public boolean isSwinging = false;
    049        public int swingProgressInt = 0;
    050        public String username;
    051
    052        /** Which dimension the player is in (-1 = the Nether, 0 = normal world) */
    053        public int dimension;
    054        @SideOnly(Side.CLIENT)
    055        public String playerCloakUrl;
    056
    057        /**
    058         * Used by EntityPlayer to prevent too many xp orbs from getting absorbed at once.
    059         */
    060        public int xpCooldown = 0;
    061        public double field_71091_bM;
    062        public double field_71096_bN;
    063        public double field_71097_bO;
    064        public double field_71094_bP;
    065        public double field_71095_bQ;
    066        public double field_71085_bR;
    067
    068        /** Boolean value indicating weather a player is sleeping or not */
    069        protected boolean sleeping;
    070
    071        /**
    072         * The chunk coordinates of the bed the player is in (null if player isn't in a bed).
    073         */
    074        public ChunkCoordinates playerLocation;
    075        private int sleepTimer;
    076        public float field_71079_bU;
    077        @SideOnly(Side.CLIENT)
    078        public float field_71082_cx;
    079        public float field_71089_bV;
    080
    081        /**
    082         * Holds the last coordinate to spawn based on last bed that the player sleep.
    083         */
    084        private ChunkCoordinates spawnChunk;
    085
    086        /** Holds the coordinate of the player when enter a minecraft to ride. */
    087        private ChunkCoordinates startMinecartRidingCoordinate;
    088        public int timeUntilPortal = 20;
    089
    090        /** Whether the entity is inside a Portal */
    091        protected boolean inPortal = false;
    092
    093        /** The amount of time an entity has been in a Portal */
    094        public float timeInPortal;
    095        @SideOnly(Side.CLIENT)
    096
    097        /** The amount of time an entity has been in a Portal the previous tick */
    098        public float prevTimeInPortal;
    099
    100        /** The player's capabilities. (See class PlayerCapabilities) */
    101        public PlayerCapabilities capabilities = new PlayerCapabilities();
    102
    103        /** The current experience level the player is on. */
    104        public int experienceLevel;
    105
    106        /**
    107         * The total amount of experience the player has. This also includes the amount of experience within their
    108         * Experience Bar.
    109         */
    110        public int experienceTotal;
    111
    112        /**
    113         * The current amount of experience the player has within their Experience Bar.
    114         */
    115        public float experience;
    116
    117        /**
    118         * This is the item that is in use when the player is holding down the useItemButton (e.g., bow, food, sword)
    119         */
    120        private ItemStack itemInUse;
    121
    122        /**
    123         * This field starts off equal to getMaxItemUseDuration and is decremented on each tick
    124         */
    125        private int itemInUseCount;
    126        protected float speedOnGround = 0.1F;
    127        protected float speedInAir = 0.02F;
    128
    129        /**
    130         * An instance of a fishing rod's hook. If this isn't null, the icon image of the fishing rod is slightly different
    131         */
    132        public EntityFishHook fishEntity = null;
    133
    134        public EntityPlayer(World par1World)
    135        {
    136            super(par1World);
    137            this.inventorySlots = new ContainerPlayer(this.inventory, !par1World.isRemote);
    138            this.craftingInventory = this.inventorySlots;
    139            this.yOffset = 1.62F;
    140            ChunkCoordinates var2 = par1World.getSpawnPoint();
    141            this.setLocationAndAngles((double)var2.posX + 0.5D, (double)(var2.posY + 1), (double)var2.posZ + 0.5D, 0.0F, 0.0F);
    142            this.entityType = "humanoid";
    143            this.field_70741_aB = 180.0F;
    144            this.fireResistance = 20;
    145            this.texture = "/mob/char.png";
    146        }
    147
    148        public int getMaxHealth()
    149        {
    150            return 20;
    151        }
    152
    153        protected void entityInit()
    154        {
    155            super.entityInit();
    156            this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
    157            this.dataWatcher.addObject(17, Byte.valueOf((byte)0));
    158        }
    159
    160        @SideOnly(Side.CLIENT)
    161
    162        /**
    163         * returns the ItemStack containing the itemInUse
    164         */
    165        public ItemStack getItemInUse()
    166        {
    167            return this.itemInUse;
    168        }
    169
    170        @SideOnly(Side.CLIENT)
    171
    172        /**
    173         * Returns the item in use count
    174         */
    175        public int getItemInUseCount()
    176        {
    177            return this.itemInUseCount;
    178        }
    179
    180        /**
    181         * Checks if the entity is currently using an item (e.g., bow, food, sword) by holding down the useItemButton
    182         */
    183        public boolean isUsingItem()
    184        {
    185            return this.itemInUse != null;
    186        }
    187
    188        @SideOnly(Side.CLIENT)
    189
    190        /**
    191         * gets the duration for how long the current itemInUse has been in use
    192         */
    193        public int getItemInUseDuration()
    194        {
    195            return this.isUsingItem() ? this.itemInUse.getMaxItemUseDuration() - this.itemInUseCount : 0;
    196        }
    197
    198        public void stopUsingItem()
    199        {
    200            if (this.itemInUse != null)
    201            {
    202                this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount);
    203            }
    204
    205            this.clearItemInUse();
    206        }
    207
    208        public void clearItemInUse()
    209        {
    210            this.itemInUse = null;
    211            this.itemInUseCount = 0;
    212
    213            if (!this.worldObj.isRemote)
    214            {
    215                this.setEating(false);
    216            }
    217        }
    218
    219        public boolean isBlocking()
    220        {
    221            return this.isUsingItem() && Item.itemsList[this.itemInUse.itemID].getItemUseAction(this.itemInUse) == EnumAction.block;
    222        }
    223
    224        /**
    225         * Called to update the entity's position/logic.
    226         */
    227        public void onUpdate()
    228        {
    229            FMLCommonHandler.instance().onPlayerPreTick(this);
    230            if (this.itemInUse != null)
    231            {
    232                ItemStack var1 = this.inventory.getCurrentItem();
    233
    234                if (var1 == this.itemInUse)
    235                {
    236                    itemInUse.getItem().onUsingItemTick(itemInUse, this, itemInUseCount);
    237                    if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0)
    238                    {
    239                        this.updateItemUse(var1, 5);
    240                    }
    241
    242                    if (--this.itemInUseCount == 0 && !this.worldObj.isRemote)
    243                    {
    244                        this.onItemUseFinish();
    245                    }
    246                }
    247                else
    248                {
    249                    this.clearItemInUse();
    250                }
    251            }
    252
    253            if (this.xpCooldown > 0)
    254            {
    255                --this.xpCooldown;
    256            }
    257
    258            if (this.isPlayerSleeping())
    259            {
    260                ++this.sleepTimer;
    261
    262                if (this.sleepTimer > 100)
    263                {
    264                    this.sleepTimer = 100;
    265                }
    266
    267                if (!this.worldObj.isRemote)
    268                {
    269                    if (!this.isInBed())
    270                    {
    271                        this.wakeUpPlayer(true, true, false);
    272                    }
    273                    else if (this.worldObj.isDaytime())
    274                    {
    275                        this.wakeUpPlayer(false, true, true);
    276                    }
    277                }
    278            }
    279            else if (this.sleepTimer > 0)
    280            {
    281                ++this.sleepTimer;
    282
    283                if (this.sleepTimer >= 110)
    284                {
    285                    this.sleepTimer = 0;
    286                }
    287            }
    288
    289            super.onUpdate();
    290
    291            if (!this.worldObj.isRemote && this.craftingInventory != null && !this.craftingInventory.canInteractWith(this))
    292            {
    293                this.closeScreen();
    294                this.craftingInventory = this.inventorySlots;
    295            }
    296
    297            if (this.isBurning() && this.capabilities.disableDamage)
    298            {
    299                this.extinguish();
    300            }
    301
    302            this.field_71091_bM = this.field_71094_bP;
    303            this.field_71096_bN = this.field_71095_bQ;
    304            this.field_71097_bO = this.field_71085_bR;
    305            double var9 = this.posX - this.field_71094_bP;
    306            double var3 = this.posY - this.field_71095_bQ;
    307            double var5 = this.posZ - this.field_71085_bR;
    308            double var7 = 10.0D;
    309
    310            if (var9 > var7)
    311            {
    312                this.field_71091_bM = this.field_71094_bP = this.posX;
    313            }
    314
    315            if (var5 > var7)
    316            {
    317                this.field_71097_bO = this.field_71085_bR = this.posZ;
    318            }
    319
    320            if (var3 > var7)
    321            {
    322                this.field_71096_bN = this.field_71095_bQ = this.posY;
    323            }
    324
    325            if (var9 < -var7)
    326            {
    327                this.field_71091_bM = this.field_71094_bP = this.posX;
    328            }
    329
    330            if (var5 < -var7)
    331            {
    332                this.field_71097_bO = this.field_71085_bR = this.posZ;
    333            }
    334
    335            if (var3 < -var7)
    336            {
    337                this.field_71096_bN = this.field_71095_bQ = this.posY;
    338            }
    339
    340            this.field_71094_bP += var9 * 0.25D;
    341            this.field_71085_bR += var5 * 0.25D;
    342            this.field_71095_bQ += var3 * 0.25D;
    343            this.addStat(StatList.minutesPlayedStat, 1);
    344
    345            if (this.ridingEntity == null)
    346            {
    347                this.startMinecartRidingCoordinate = null;
    348            }
    349
    350            if (!this.worldObj.isRemote)
    351            {
    352                this.foodStats.onUpdate(this);
    353            }
    354            FMLCommonHandler.instance().onPlayerPostTick(this);
    355        }
    356
    357        /**
    358         * Plays sounds and makes particles for item in use state
    359         */
    360        protected void updateItemUse(ItemStack par1ItemStack, int par2)
    361        {
    362            if (par1ItemStack.getItemUseAction() == EnumAction.drink)
    363            {
    364                this.worldObj.playSoundAtEntity(this, "random.drink", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
    365            }
    366
    367            if (par1ItemStack.getItemUseAction() == EnumAction.eat)
    368            {
    369                for (int var3 = 0; var3 < par2; ++var3)
    370                {
    371                    Vec3 var4 = Vec3.getVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
    372                    var4.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    373                    var4.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    374                    Vec3 var5 = Vec3.getVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.3D, (double)(-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D);
    375                    var5.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    376                    var5.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    377                    var5 = var5.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);
    378                    this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().shiftedIndex, var5.xCoord, var5.yCoord, var5.zCoord, var4.xCoord, var4.yCoord + 0.05D, var4.zCoord);
    379                }
    380
    381                this.worldObj.playSoundAtEntity(this, "random.eat", 0.5F + 0.5F * (float)this.rand.nextInt(2), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    382            }
    383        }
    384
    385        /**
    386         * Used for when item use count runs out, ie: eating completed
    387         */
    388        protected void onItemUseFinish()
    389        {
    390            if (this.itemInUse != null)
    391            {
    392                this.updateItemUse(this.itemInUse, 16);
    393                int var1 = this.itemInUse.stackSize;
    394                ItemStack var2 = this.itemInUse.onFoodEaten(this.worldObj, this);
    395
    396                if (var2 != this.itemInUse || var2 != null && var2.stackSize != var1)
    397                {
    398                    this.inventory.mainInventory[this.inventory.currentItem] = var2;
    399
    400                    if (var2.stackSize == 0)
    401                    {
    402                        this.inventory.mainInventory[this.inventory.currentItem] = null;
    403                    }
    404                }
    405
    406                this.clearItemInUse();
    407            }
    408        }
    409
    410        @SideOnly(Side.CLIENT)
    411        public void handleHealthUpdate(byte par1)
    412        {
    413            if (par1 == 9)
    414            {
    415                this.onItemUseFinish();
    416            }
    417            else
    418            {
    419                super.handleHealthUpdate(par1);
    420            }
    421        }
    422
    423        /**
    424         * Dead and sleeping entities cannot move
    425         */
    426        protected boolean isMovementBlocked()
    427        {
    428            return this.getHealth() <= 0 || this.isPlayerSleeping();
    429        }
    430
    431        /**
    432         * sets current screen to null (used on escape buttons of GUIs)
    433         */
    434        public void closeScreen()
    435        {
    436            this.craftingInventory = this.inventorySlots;
    437        }
    438
    439        /**
    440         * Handles updating while being ridden by an entity
    441         */
    442        public void updateRidden()
    443        {
    444            double var1 = this.posX;
    445            double var3 = this.posY;
    446            double var5 = this.posZ;
    447            super.updateRidden();
    448            this.prevCameraYaw = this.cameraYaw;
    449            this.cameraYaw = 0.0F;
    450            this.addMountedMovementStat(this.posX - var1, this.posY - var3, this.posZ - var5);
    451        }
    452
    453        @SideOnly(Side.CLIENT)
    454
    455        /**
    456         * Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned
    457         * (only actually used on players though its also on Entity)
    458         */
    459        public void preparePlayerToSpawn()
    460        {
    461            this.yOffset = 1.62F;
    462            this.setSize(0.6F, 1.8F);
    463            super.preparePlayerToSpawn();
    464            this.setEntityHealth(this.getMaxHealth());
    465            this.deathTime = 0;
    466        }
    467
    468        /**
    469         * Returns the swing speed modifier
    470         */
    471        private int getSwingSpeedModifier()
    472        {
    473            return this.isPotionActive(Potion.digSpeed) ? 6 - (1 + this.getActivePotionEffect(Potion.digSpeed).getAmplifier()) * 1 : (this.isPotionActive(Potion.digSlowdown) ? 6 + (1 + this.getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2 : 6);
    474        }
    475
    476        protected void updateEntityActionState()
    477        {
    478            int var1 = this.getSwingSpeedModifier();
    479
    480            if (this.isSwinging)
    481            {
    482                ++this.swingProgressInt;
    483
    484                if (this.swingProgressInt >= var1)
    485                {
    486                    this.swingProgressInt = 0;
    487                    this.isSwinging = false;
    488                }
    489            }
    490            else
    491            {
    492                this.swingProgressInt = 0;
    493            }
    494
    495            this.swingProgress = (float)this.swingProgressInt / (float)var1;
    496        }
    497
    498        /**
    499         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    500         * use this to react to sunlight and start to burn.
    501         */
    502        public void onLivingUpdate()
    503        {
    504            if (this.flyToggleTimer > 0)
    505            {
    506                --this.flyToggleTimer;
    507            }
    508
    509            if (this.worldObj.difficultySetting == 0 && this.getHealth() < this.getMaxHealth() && this.ticksExisted % 20 * 12 == 0)
    510            {
    511                this.heal(1);
    512            }
    513
    514            this.inventory.decrementAnimations();
    515            this.prevCameraYaw = this.cameraYaw;
    516            super.onLivingUpdate();
    517            this.landMovementFactor = this.capabilities.getWalkSpeed();
    518            this.jumpMovementFactor = this.speedInAir;
    519
    520            if (this.isSprinting())
    521            {
    522                this.landMovementFactor = (float)((double)this.landMovementFactor + (double)this.capabilities.getWalkSpeed() * 0.3D);
    523                this.jumpMovementFactor = (float)((double)this.jumpMovementFactor + (double)this.speedInAir * 0.3D);
    524            }
    525
    526            float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
    527            float var2 = (float)Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F;
    528
    529            if (var1 > 0.1F)
    530            {
    531                var1 = 0.1F;
    532            }
    533
    534            if (!this.onGround || this.getHealth() <= 0)
    535            {
    536                var1 = 0.0F;
    537            }
    538
    539            if (this.onGround || this.getHealth() <= 0)
    540            {
    541                var2 = 0.0F;
    542            }
    543
    544            this.cameraYaw += (var1 - this.cameraYaw) * 0.4F;
    545            this.cameraPitch += (var2 - this.cameraPitch) * 0.8F;
    546
    547            if (this.getHealth() > 0)
    548            {
    549                List var3 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(1.0D, 0.0D, 1.0D));
    550
    551                if (var3 != null)
    552                {
    553                    Iterator var4 = var3.iterator();
    554
    555                    while (var4.hasNext())
    556                    {
    557                        Entity var5 = (Entity)var4.next();
    558
    559                        if (!var5.isDead)
    560                        {
    561                            this.collideWithPlayer(var5);
    562                        }
    563                    }
    564                }
    565            }
    566        }
    567
    568        private void collideWithPlayer(Entity par1Entity)
    569        {
    570            par1Entity.onCollideWithPlayer(this);
    571        }
    572
    573        @SideOnly(Side.CLIENT)
    574        public int getScore()
    575        {
    576            return this.score;
    577        }
    578
    579        /**
    580         * Called when the mob's health reaches 0.
    581         */
    582        public void onDeath(DamageSource par1DamageSource)
    583        {
    584            super.onDeath(par1DamageSource);
    585            this.setSize(0.2F, 0.2F);
    586            this.setPosition(this.posX, this.posY, this.posZ);
    587            this.motionY = 0.10000000149011612D;
    588
    589            captureDrops = true;
    590            capturedDrops.clear();
    591
    592            if (this.username.equals("Notch"))
    593            {
    594                this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true);
    595            }
    596
    597            this.inventory.dropAllItems();
    598            captureDrops = false;
    599
    600            if (!worldObj.isRemote)
    601            {
    602                PlayerDropsEvent event = new PlayerDropsEvent(this, par1DamageSource, capturedDrops, recentlyHit > 0);
    603                if (!MinecraftForge.EVENT_BUS.post(event))
    604                {
    605                    for (EntityItem item : capturedDrops)
    606                    {
    607                        joinEntityItemWithWorld(item);
    608                    }
    609                }
    610            }
    611
    612            if (par1DamageSource != null)
    613            {
    614                this.motionX = (double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F);
    615                this.motionZ = (double)(-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F);
    616            }
    617            else
    618            {
    619                this.motionX = this.motionZ = 0.0D;
    620            }
    621
    622            this.yOffset = 0.1F;
    623            this.addStat(StatList.deathsStat, 1);
    624        }
    625
    626        /**
    627         * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args:
    628         * entity, scoreToAdd
    629         */
    630        public void addToPlayerScore(Entity par1Entity, int par2)
    631        {
    632            this.score += par2;
    633
    634            if (par1Entity instanceof EntityPlayer)
    635            {
    636                this.addStat(StatList.playerKillsStat, 1);
    637            }
    638            else
    639            {
    640                this.addStat(StatList.mobKillsStat, 1);
    641            }
    642        }
    643
    644        /**
    645         * Decrements the entity's air supply when underwater
    646         */
    647        protected int decreaseAirSupply(int par1)
    648        {
    649            int var2 = EnchantmentHelper.getRespiration(this.inventory);
    650            return var2 > 0 && this.rand.nextInt(var2 + 1) > 0 ? par1 : super.decreaseAirSupply(par1);
    651        }
    652
    653        /**
    654         * Called when player presses the drop item key
    655         */
    656        public EntityItem dropOneItem()
    657        {
    658            ItemStack stack = inventory.getCurrentItem();
    659            if (stack == null)
    660            {
    661                return null;
    662            }
    663            if (stack.getItem().onDroppedByPlayer(stack, this))
    664            {
    665                return ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, 1));
    666            }
    667            return null;
    668        }
    669
    670        /**
    671         * Args: itemstack - called when player drops an item stack that's not in his inventory (like items still placed in
    672         * a workbench while the workbench'es GUI gets closed)
    673         */
    674        public EntityItem dropPlayerItem(ItemStack par1ItemStack)
    675        {
    676            return ForgeHooks.onPlayerTossEvent(this, par1ItemStack);
    677        }
    678
    679        /**
    680         * Args: itemstack, flag
    681         */
    682        public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2)
    683        {
    684            if (par1ItemStack == null)
    685            {
    686                return null;
    687            }
    688            else
    689            {
    690                EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY - 0.30000001192092896D + (double)this.getEyeHeight(), this.posZ, par1ItemStack);
    691                var3.delayBeforeCanPickup = 40;
    692                float var4 = 0.1F;
    693                float var5;
    694
    695                if (par2)
    696                {
    697                    var5 = this.rand.nextFloat() * 0.5F;
    698                    float var6 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
    699                    var3.motionX = (double)(-MathHelper.sin(var6) * var5);
    700                    var3.motionZ = (double)(MathHelper.cos(var6) * var5);
    701                    var3.motionY = 0.20000000298023224D;
    702                }
    703                else
    704                {
    705                    var4 = 0.3F;
    706                    var3.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4);
    707                    var3.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4);
    708                    var3.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI) * var4 + 0.1F);
    709                    var4 = 0.02F;
    710                    var5 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
    711                    var4 *= this.rand.nextFloat();
    712                    var3.motionX += Math.cos((double)var5) * (double)var4;
    713                    var3.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F);
    714                    var3.motionZ += Math.sin((double)var5) * (double)var4;
    715                }
    716
    717                this.joinEntityItemWithWorld(var3);
    718                this.addStat(StatList.dropStat, 1);
    719                return var3;
    720            }
    721        }
    722
    723        /**
    724         * Joins the passed in entity item with the world. Args: entityItem
    725         */
    726        public void joinEntityItemWithWorld(EntityItem par1EntityItem)
    727        {
    728            if (captureDrops)
    729            {
    730                capturedDrops.add(par1EntityItem);
    731            }
    732            else
    733            {
    734                this.worldObj.spawnEntityInWorld(par1EntityItem);
    735            }
    736        }
    737
    738        /**
    739         * Returns how strong the player is against the specified block at this moment
    740         * Deprecated in favor of the more sensitive version
    741         */
    742        @Deprecated
    743        public float getCurrentPlayerStrVsBlock(Block par1Block)
    744        {
    745            return getCurrentPlayerStrVsBlock(par1Block, 0);
    746        }
    747
    748        public float getCurrentPlayerStrVsBlock(Block par1Block, int meta)
    749        {
    750            ItemStack stack = inventory.getCurrentItem();
    751            float var2 = (stack == null ? 1.0F : stack.getItem().getStrVsBlock(stack, par1Block, meta));
    752            int var3 = EnchantmentHelper.getEfficiencyModifier(this.inventory);
    753
    754            if (var3 > 0 && ForgeHooks.canHarvestBlock(par1Block, this, meta))
    755            {
    756                var2 += (float)(var3 * var3 + 1);
    757            }
    758
    759            if (this.isPotionActive(Potion.digSpeed))
    760            {
    761                var2 *= 1.0F + (float)(this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F;
    762            }
    763
    764            if (this.isPotionActive(Potion.digSlowdown))
    765            {
    766                var2 *= 1.0F - (float)(this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F;
    767            }
    768
    769            if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this.inventory))
    770            {
    771                var2 /= 5.0F;
    772            }
    773
    774            if (!this.onGround)
    775            {
    776                var2 /= 5.0F;
    777            }
    778
    779            var2 = ForgeEventFactory.getBreakSpeed(this, par1Block, meta, var2);
    780            return (var2 < 0 ? 0 : var2);
    781        }
    782
    783        /**
    784         * Checks if the player has the ability to harvest a block (checks current inventory item for a tool if necessary)
    785         */
    786        public boolean canHarvestBlock(Block par1Block)
    787        {
    788            return ForgeEventFactory.doPlayerHarvestCheck(this, par1Block, inventory.canHarvestBlock(par1Block));
    789        }
    790
    791        /**
    792         * (abstract) Protected helper method to read subclass entity data from NBT.
    793         */
    794        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    795        {
    796            super.readEntityFromNBT(par1NBTTagCompound);
    797            NBTTagList var2 = par1NBTTagCompound.getTagList("Inventory");
    798            this.inventory.readFromNBT(var2);
    799            this.dimension = par1NBTTagCompound.getInteger("Dimension");
    800            this.sleeping = par1NBTTagCompound.getBoolean("Sleeping");
    801            this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer");
    802            this.experience = par1NBTTagCompound.getFloat("XpP");
    803            this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel");
    804            this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal");
    805
    806            if (this.sleeping)
    807            {
    808                this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    809                this.wakeUpPlayer(true, true, false);
    810            }
    811
    812            if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") && par1NBTTagCompound.hasKey("SpawnZ"))
    813            {
    814                this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ"));
    815            }
    816
    817            this.foodStats.readNBT(par1NBTTagCompound);
    818            this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound);
    819
    820            if (par1NBTTagCompound.hasKey("EnderItems"))
    821            {
    822                NBTTagList var3 = par1NBTTagCompound.getTagList("EnderItems");
    823                this.theInventoryEnderChest.loadInventoryFromNBT(var3);
    824            }
    825        }
    826
    827        /**
    828         * (abstract) Protected helper method to write subclass entity data to NBT.
    829         */
    830        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    831        {
    832            super.writeEntityToNBT(par1NBTTagCompound);
    833            par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList()));
    834            par1NBTTagCompound.setInteger("Dimension", this.dimension);
    835            par1NBTTagCompound.setBoolean("Sleeping", this.sleeping);
    836            par1NBTTagCompound.setShort("SleepTimer", (short)this.sleepTimer);
    837            par1NBTTagCompound.setFloat("XpP", this.experience);
    838            par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel);
    839            par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal);
    840
    841            if (this.spawnChunk != null)
    842            {
    843                par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX);
    844                par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY);
    845                par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ);
    846            }
    847
    848            this.foodStats.writeNBT(par1NBTTagCompound);
    849            this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound);
    850            par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT());
    851        }
    852
    853        /**
    854         * Displays the GUI for interacting with a chest inventory. Args: chestInventory
    855         */
    856        public void displayGUIChest(IInventory par1IInventory) {}
    857
    858        public void displayGUIEnchantment(int par1, int par2, int par3) {}
    859
    860        /**
    861         * Displays the crafting GUI for a workbench.
    862         */
    863        public void displayGUIWorkbench(int par1, int par2, int par3) {}
    864
    865        /**
    866         * Called whenever an item is picked up from walking over it. Args: pickedUpEntity, stackSize
    867         */
    868        public void onItemPickup(Entity par1Entity, int par2) {}
    869
    870        public float getEyeHeight()
    871        {
    872            return 0.12F;
    873        }
    874
    875        /**
    876         * sets the players height back to normal after doing things like sleeping and dieing
    877         */
    878        protected void resetHeight()
    879        {
    880            this.yOffset = 1.62F;
    881        }
    882
    883        /**
    884         * Called when the entity is attacked.
    885         */
    886        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    887        {
    888            if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative())
    889            {
    890                return false;
    891            }
    892            else
    893            {
    894                this.entityAge = 0;
    895
    896                if (this.getHealth() <= 0)
    897                {
    898                    return false;
    899                }
    900                else
    901                {
    902                    if (this.isPlayerSleeping() && !this.worldObj.isRemote)
    903                    {
    904                        this.wakeUpPlayer(true, true, false);
    905                    }
    906
    907                    Entity var3 = par1DamageSource.getEntity();
    908
    909                    if (par1DamageSource.func_76350_n())
    910                    {
    911                        if (this.worldObj.difficultySetting == 0)
    912                        {
    913                            par2 = 0;
    914                        }
    915
    916                        if (this.worldObj.difficultySetting == 1)
    917                        {
    918                            par2 = par2 / 2 + 1;
    919                        }
    920
    921                        if (this.worldObj.difficultySetting == 3)
    922                        {
    923                            par2 = par2 * 3 / 2;
    924                        }
    925                    }
    926
    927                    if (par2 == 0)
    928                    {
    929                        return false;
    930                    }
    931                    else
    932                    {
    933                        Entity var4 = par1DamageSource.getEntity();
    934
    935                        if (var4 instanceof EntityArrow && ((EntityArrow)var4).shootingEntity != null)
    936                        {
    937                            var4 = ((EntityArrow)var4).shootingEntity;
    938                        }
    939
    940                        if (var4 instanceof EntityLiving)
    941                        {
    942                            this.alertWolves((EntityLiving)var4, false);
    943                        }
    944
    945                        this.addStat(StatList.damageTakenStat, par2);
    946                        return super.attackEntityFrom(par1DamageSource, par2);
    947                    }
    948                }
    949            }
    950        }
    951
    952        /**
    953         * Reduces damage, depending on potions
    954         */
    955        protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2)
    956        {
    957            int var3 = super.applyPotionDamageCalculations(par1DamageSource, par2);
    958
    959            if (var3 <= 0)
    960            {
    961                return 0;
    962            }
    963            else
    964            {
    965                int var4 = EnchantmentHelper.getEnchantmentModifierDamage(this.inventory, par1DamageSource);
    966
    967                if (var4 > 20)
    968                {
    969                    var4 = 20;
    970                }
    971
    972                if (var4 > 0 && var4 <= 20)
    973                {
    974                    int var5 = 25 - var4;
    975                    int var6 = var3 * var5 + this.carryoverDamage;
    976                    var3 = var6 / 25;
    977                    this.carryoverDamage = var6 % 25;
    978                }
    979
    980                return var3;
    981            }
    982        }
    983
    984        /**
    985         * returns if pvp is enabled or not
    986         */
    987        protected boolean isPVPEnabled()
    988        {
    989            return false;
    990        }
    991
    992        /**
    993         * Called when the player attack or gets attacked, it's alert all wolves in the area that are owned by the player to
    994         * join the attack or defend the player.
    995         */
    996        protected void alertWolves(EntityLiving par1EntityLiving, boolean par2)
    997        {
    998            if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast))
    999            {
    1000                if (par1EntityLiving instanceof EntityWolf)
    1001                {
    1002                    EntityWolf var3 = (EntityWolf)par1EntityLiving;
    1003
    1004                    if (var3.isTamed() && this.username.equals(var3.getOwnerName()))
    1005                    {
    1006                        return;
    1007                    }
    1008                }
    1009
    1010                if (!(par1EntityLiving instanceof EntityPlayer) || this.isPVPEnabled())
    1011                {
    1012                    List var6 = this.worldObj.getEntitiesWithinAABB(EntityWolf.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(this.posX, this.posY, this.posZ, this.posX + 1.0D, this.posY + 1.0D, this.posZ + 1.0D).expand(16.0D, 4.0D, 16.0D));
    1013                    Iterator var4 = var6.iterator();
    1014
    1015                    while (var4.hasNext())
    1016                    {
    1017                        EntityWolf var5 = (EntityWolf)var4.next();
    1018
    1019                        if (var5.isTamed() && var5.getEntityToAttack() == null && this.username.equals(var5.getOwnerName()) && (!par2 || !var5.isSitting()))
    1020                        {
    1021                            var5.setSitting(false);
    1022                            var5.setTarget(par1EntityLiving);
    1023                        }
    1024                    }
    1025                }
    1026            }
    1027        }
    1028
    1029        protected void damageArmor(int par1)
    1030        {
    1031            this.inventory.damageArmor(par1);
    1032        }
    1033
    1034        /**
    1035         * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
    1036         */
    1037        public int getTotalArmorValue()
    1038        {
    1039            return this.inventory.getTotalArmorValue();
    1040        }
    1041
    1042        /**
    1043         * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health
    1044         * second with the reduced value. Args: damageAmount
    1045         */
    1046        protected void damageEntity(DamageSource par1DamageSource, int par2)
    1047        {
    1048            LivingHurtEvent event = new LivingHurtEvent(this, par1DamageSource, par2);
    1049            if (MinecraftForge.EVENT_BUS.post(event) || event.ammount == 0)
    1050            {
    1051                return;
    1052            }
    1053            par2 = event.ammount;
    1054
    1055            if (!par1DamageSource.isUnblockable() && this.isBlocking())
    1056            {
    1057                par2 = 1 + par2 >> 1;
    1058            }
    1059
    1060            par2 = ArmorProperties.ApplyArmor(this, inventory.armorInventory, par1DamageSource, par2);
    1061            if (par2 <= 0)
    1062            {
    1063                return;
    1064            }
    1065            par2 = this.applyPotionDamageCalculations(par1DamageSource, par2);
    1066            this.addExhaustion(par1DamageSource.getHungerDamage());
    1067            this.health -= par2;
    1068        }
    1069
    1070        /**
    1071         * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace
    1072         */
    1073        public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) {}
    1074
    1075        /**
    1076         * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser
    1077         */
    1078        public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) {}
    1079
    1080        /**
    1081         * Displays the GUI for editing a sign. Args: tileEntitySign
    1082         */
    1083        public void displayGUIEditSign(TileEntitySign par1TileEntitySign) {}
    1084
    1085        /**
    1086         * Displays the GUI for interacting with a brewing stand.
    1087         */
    1088        public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) {}
    1089
    1090        public void displayGUIMerchant(IMerchant par1IMerchant) {}
    1091
    1092        /**
    1093         * Displays the GUI for interacting with a book.
    1094         */
    1095        public void displayGUIBook(ItemStack par1ItemStack) {}
    1096
    1097        public boolean interactWith(Entity par1Entity)
    1098        {
    1099            if (MinecraftForge.EVENT_BUS.post(new EntityInteractEvent(this, par1Entity)))
    1100            {
    1101                return false;
    1102            }
    1103            if (par1Entity.interact(this))
    1104            {
    1105                return true;
    1106            }
    1107            else
    1108            {
    1109                ItemStack var2 = this.getCurrentEquippedItem();
    1110
    1111                if (var2 != null && par1Entity instanceof EntityLiving)
    1112                {
    1113                    if (this.capabilities.isCreativeMode)
    1114                    {
    1115                        var2 = var2.copy();
    1116                    }
    1117
    1118                    if (var2.interactWith((EntityLiving)par1Entity))
    1119                    {
    1120                        if (var2.stackSize <= 0 && !this.capabilities.isCreativeMode)
    1121                        {
    1122                            this.destroyCurrentEquippedItem();
    1123                        }
    1124
    1125                        return true;
    1126                    }
    1127                }
    1128
    1129                return false;
    1130            }
    1131        }
    1132
    1133        /**
    1134         * Returns the currently being used item by the player.
    1135         */
    1136        public ItemStack getCurrentEquippedItem()
    1137        {
    1138            return this.inventory.getCurrentItem();
    1139        }
    1140
    1141        /**
    1142         * Destroys the currently equipped item from the player's inventory.
    1143         */
    1144        public void destroyCurrentEquippedItem()
    1145        {
    1146            ItemStack orig = getCurrentEquippedItem();
    1147            this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack)null);
    1148            MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, orig));
    1149        }
    1150
    1151        /**
    1152         * Returns the Y Offset of this entity.
    1153         */
    1154        public double getYOffset()
    1155        {
    1156            return (double)(this.yOffset - 0.5F);
    1157        }
    1158
    1159        /**
    1160         * Swings the item the player is holding.
    1161         */
    1162        public void swingItem()
    1163        {
    1164            if (!this.isSwinging || this.swingProgressInt >= this.getSwingSpeedModifier() / 2 || this.swingProgressInt < 0)
    1165            {
    1166                this.swingProgressInt = -1;
    1167                this.isSwinging = true;
    1168            }
    1169        }
    1170
    1171        /**
    1172         * Attacks for the player the targeted entity with the currently equipped item.  The equipped item has hitEntity
    1173         * called on it. Args: targetEntity
    1174         */
    1175        public void attackTargetEntityWithCurrentItem(Entity par1Entity)
    1176        {
    1177            if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(this, par1Entity)))
    1178            {
    1179                return;
    1180            }
    1181            ItemStack stack = getCurrentEquippedItem();
    1182            if (stack != null && stack.getItem().onLeftClickEntity(stack, this, par1Entity))
    1183            {
    1184                return;
    1185            }
    1186            if (par1Entity.canAttackWithItem())
    1187            {
    1188                int var2 = this.inventory.getDamageVsEntity(par1Entity);
    1189
    1190                if (this.isPotionActive(Potion.damageBoost))
    1191                {
    1192                    var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier();
    1193                }
    1194
    1195                if (this.isPotionActive(Potion.weakness))
    1196                {
    1197                    var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier();
    1198                }
    1199
    1200                int var3 = 0;
    1201                int var4 = 0;
    1202
    1203                if (par1Entity instanceof EntityLiving)
    1204                {
    1205                    var4 = EnchantmentHelper.getEnchantmentModifierLiving(this.inventory, (EntityLiving)par1Entity);
    1206                    var3 += EnchantmentHelper.getKnockbackModifier(this.inventory, (EntityLiving)par1Entity);
    1207                }
    1208
    1209                if (this.isSprinting())
    1210                {
    1211                    ++var3;
    1212                }
    1213
    1214                if (var2 > 0 || var4 > 0)
    1215                {
    1216                    boolean var5 = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && par1Entity instanceof EntityLiving;
    1217
    1218                    if (var5)
    1219                    {
    1220                        var2 += this.rand.nextInt(var2 / 2 + 2);
    1221                    }
    1222
    1223                    var2 += var4;
    1224                    boolean var6 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), var2);
    1225
    1226                    if (var6)
    1227                    {
    1228                        if (var3 > 0)
    1229                        {
    1230                            par1Entity.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)var3 * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)var3 * 0.5F));
    1231                            this.motionX *= 0.6D;
    1232                            this.motionZ *= 0.6D;
    1233                            this.setSprinting(false);
    1234                        }
    1235
    1236                        if (var5)
    1237                        {
    1238                            this.onCriticalHit(par1Entity);
    1239                        }
    1240
    1241                        if (var4 > 0)
    1242                        {
    1243                            this.onEnchantmentCritical(par1Entity);
    1244                        }
    1245
    1246                        if (var2 >= 18)
    1247                        {
    1248                            this.triggerAchievement(AchievementList.overkill);
    1249                        }
    1250
    1251                        this.setLastAttackingEntity(par1Entity);
    1252                    }
    1253
    1254                    ItemStack var7 = this.getCurrentEquippedItem();
    1255
    1256                    if (var7 != null && par1Entity instanceof EntityLiving)
    1257                    {
    1258                        var7.hitEntity((EntityLiving)par1Entity, this);
    1259
    1260                        if (var7.stackSize <= 0)
    1261                        {
    1262                            this.destroyCurrentEquippedItem();
    1263                        }
    1264                    }
    1265
    1266                    if (par1Entity instanceof EntityLiving)
    1267                    {
    1268                        if (par1Entity.isEntityAlive())
    1269                        {
    1270                            this.alertWolves((EntityLiving)par1Entity, true);
    1271                        }
    1272
    1273                        this.addStat(StatList.damageDealtStat, var2);
    1274                        int var8 = EnchantmentHelper.getFireAspectModifier(this.inventory, (EntityLiving)par1Entity);
    1275
    1276                        if (var8 > 0)
    1277                        {
    1278                            par1Entity.setFire(var8 * 4);
    1279                        }
    1280                    }
    1281
    1282                    this.addExhaustion(0.3F);
    1283                }
    1284            }
    1285        }
    1286
    1287        /**
    1288         * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically
    1289         */
    1290        public void onCriticalHit(Entity par1Entity) {}
    1291
    1292        public void onEnchantmentCritical(Entity par1Entity) {}
    1293
    1294        @SideOnly(Side.CLIENT)
    1295        public void respawnPlayer() {}
    1296
    1297        /**
    1298         * Will get destroyed next tick.
    1299         */
    1300        public void setDead()
    1301        {
    1302            super.setDead();
    1303            this.inventorySlots.onCraftGuiClosed(this);
    1304
    1305            if (this.craftingInventory != null)
    1306            {
    1307                this.craftingInventory.onCraftGuiClosed(this);
    1308            }
    1309        }
    1310
    1311        /**
    1312         * Checks if this entity is inside of an opaque block
    1313         */
    1314        public boolean isEntityInsideOpaqueBlock()
    1315        {
    1316            return !this.sleeping && super.isEntityInsideOpaqueBlock();
    1317        }
    1318
    1319        public boolean func_71066_bF()
    1320        {
    1321            return false;
    1322        }
    1323
    1324        /**
    1325         * Attempts to have the player sleep in a bed at the specified location.
    1326         */
    1327        public EnumStatus sleepInBedAt(int par1, int par2, int par3)
    1328        {
    1329            PlayerSleepInBedEvent event = new PlayerSleepInBedEvent(this, par1, par2, par3);
    1330            MinecraftForge.EVENT_BUS.post(event);
    1331            if (event.result != null)
    1332            {
    1333                return event.result;
    1334            }
    1335            if (!this.worldObj.isRemote)
    1336            {
    1337                if (this.isPlayerSleeping() || !this.isEntityAlive())
    1338                {
    1339                    return EnumStatus.OTHER_PROBLEM;
    1340                }
    1341
    1342                if (!this.worldObj.provider.isSurfaceWorld())
    1343                {
    1344                    return EnumStatus.NOT_POSSIBLE_HERE;
    1345                }
    1346
    1347                if (this.worldObj.isDaytime())
    1348                {
    1349                    return EnumStatus.NOT_POSSIBLE_NOW;
    1350                }
    1351
    1352                if (Math.abs(this.posX - (double)par1) > 3.0D || Math.abs(this.posY - (double)par2) > 2.0D || Math.abs(this.posZ - (double)par3) > 3.0D)
    1353                {
    1354                    return EnumStatus.TOO_FAR_AWAY;
    1355                }
    1356
    1357                double var4 = 8.0D;
    1358                double var6 = 5.0D;
    1359                List var8 = this.worldObj.getEntitiesWithinAABB(EntityMob.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par1 - var4, (double)par2 - var6, (double)par3 - var4, (double)par1 + var4, (double)par2 + var6, (double)par3 + var4));
    1360
    1361                if (!var8.isEmpty())
    1362                {
    1363                    return EnumStatus.NOT_SAFE;
    1364                }
    1365            }
    1366
    1367            this.setSize(0.2F, 0.2F);
    1368            this.yOffset = 0.2F;
    1369
    1370            if (this.worldObj.blockExists(par1, par2, par3))
    1371            {
    1372                int var9 = this.worldObj.getBlockMetadata(par1, par2, par3);
    1373                int var5 = BlockBed.getDirection(var9);
    1374                Block block = Block.blocksList[worldObj.getBlockId(par1, par2, par3)];
    1375                if (block != null)
    1376                {
    1377                    var5 = block.getBedDirection(worldObj, par1, par2, par3);
    1378                }
    1379                float var10 = 0.5F;
    1380                float var7 = 0.5F;
    1381
    1382                switch (var5)
    1383                {
    1384                    case 0:
    1385                        var7 = 0.9F;
    1386                        break;
    1387                    case 1:
    1388                        var10 = 0.1F;
    1389                        break;
    1390                    case 2:
    1391                        var7 = 0.1F;
    1392                        break;
    1393                    case 3:
    1394                        var10 = 0.9F;
    1395                }
    1396
    1397                this.func_71013_b(var5);
    1398                this.setPosition((double)((float)par1 + var10), (double)((float)par2 + 0.9375F), (double)((float)par3 + var7));
    1399            }
    1400            else
    1401            {
    1402                this.setPosition((double)((float)par1 + 0.5F), (double)((float)par2 + 0.9375F), (double)((float)par3 + 0.5F));
    1403            }
    1404
    1405            this.sleeping = true;
    1406            this.sleepTimer = 0;
    1407            this.playerLocation = new ChunkCoordinates(par1, par2, par3);
    1408            this.motionX = this.motionZ = this.motionY = 0.0D;
    1409
    1410            if (!this.worldObj.isRemote)
    1411            {
    1412                this.worldObj.updateAllPlayersSleepingFlag();
    1413            }
    1414
    1415            return EnumStatus.OK;
    1416        }
    1417
    1418        private void func_71013_b(int par1)
    1419        {
    1420            this.field_71079_bU = 0.0F;
    1421            this.field_71089_bV = 0.0F;
    1422
    1423            switch (par1)
    1424            {
    1425                case 0:
    1426                    this.field_71089_bV = -1.8F;
    1427                    break;
    1428                case 1:
    1429                    this.field_71079_bU = 1.8F;
    1430                    break;
    1431                case 2:
    1432                    this.field_71089_bV = 1.8F;
    1433                    break;
    1434                case 3:
    1435                    this.field_71079_bU = -1.8F;
    1436            }
    1437        }
    1438
    1439        /**
    1440         * Wake up the player if they're sleeping.
    1441         */
    1442        public void wakeUpPlayer(boolean par1, boolean par2, boolean par3)
    1443        {
    1444            this.setSize(0.6F, 1.8F);
    1445            this.resetHeight();
    1446            ChunkCoordinates var4 = this.playerLocation;
    1447            ChunkCoordinates var5 = this.playerLocation;
    1448
    1449            Block block = (var4 == null ? null : Block.blocksList[worldObj.getBlockId(var4.posX, var4.posY, var4.posZ)]);
    1450
    1451            if (var4 != null && block != null && block.isBed(worldObj, var4.posX, var4.posY, var4.posZ, this))
    1452            {
    1453                block.setBedOccupied(this.worldObj, var4.posX, var4.posY, var4.posZ, this, false);
    1454                var5 = block.getBedSpawnPosition(worldObj, var4.posX, var4.posY, var4.posZ, this);
    1455
    1456                if (var5 == null)
    1457                {
    1458                    var5 = new ChunkCoordinates(var4.posX, var4.posY + 1, var4.posZ);
    1459                }
    1460
    1461                this.setPosition((double)((float)var5.posX + 0.5F), (double)((float)var5.posY + this.yOffset + 0.1F), (double)((float)var5.posZ + 0.5F));
    1462            }
    1463
    1464            this.sleeping = false;
    1465
    1466            if (!this.worldObj.isRemote && par2)
    1467            {
    1468                this.worldObj.updateAllPlayersSleepingFlag();
    1469            }
    1470
    1471            if (par1)
    1472            {
    1473                this.sleepTimer = 0;
    1474            }
    1475            else
    1476            {
    1477                this.sleepTimer = 100;
    1478            }
    1479
    1480            if (par3)
    1481            {
    1482                this.setSpawnChunk(this.playerLocation);
    1483            }
    1484        }
    1485
    1486        /**
    1487         * Checks if the player is currently in a bed
    1488         */
    1489        private boolean isInBed()
    1490        {
    1491            ChunkCoordinates c = playerLocation;
    1492            int blockID = worldObj.getBlockId(c.posX, c.posY, c.posZ);
    1493            return Block.blocksList[blockID] != null && Block.blocksList[blockID].isBed(worldObj, c.posX, c.posY, c.posZ, this);
    1494        }
    1495
    1496        /**
    1497         * Ensure that a block enabling respawning exists at the specified coordinates and find an empty space nearby to
    1498         * spawn.
    1499         */
    1500        public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates)
    1501        {
    1502            IChunkProvider var2 = par0World.getChunkProvider();
    1503            var2.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4);
    1504            var2.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4);
    1505            var2.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4);
    1506            var2.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4);
    1507
    1508            ChunkCoordinates c = par1ChunkCoordinates;
    1509            Block block = Block.blocksList[par0World.getBlockId(c.posX, c.posY, c.posZ)];
    1510            if (block == null || !block.isBed(par0World, c.posX, c.posY, c.posZ, null))
    1511            {
    1512                return null;
    1513            }
    1514            else
    1515            {
    1516                ChunkCoordinates var3 = block.getBedSpawnPosition(par0World, c.posX, c.posY, c.posZ, null);
    1517                return var3;
    1518            }
    1519        }
    1520
    1521        @SideOnly(Side.CLIENT)
    1522
    1523        /**
    1524         * Returns the orientation of the bed in degrees.
    1525         */
    1526        public float getBedOrientationInDegrees()
    1527        {
    1528            if (this.playerLocation != null)
    1529            {
    1530                int x = playerLocation.posX;
    1531                int y = playerLocation.posY;
    1532                int z = playerLocation.posZ;
    1533                Block block = Block.blocksList[worldObj.getBlockId(x, y, z)];
    1534                int var2 = (block == null ? 0 : block.getBedDirection(worldObj, x, y, z));
    1535
    1536                switch (var2)
    1537                {
    1538                    case 0:
    1539                        return 90.0F;
    1540                    case 1:
    1541                        return 0.0F;
    1542                    case 2:
    1543                        return 270.0F;
    1544                    case 3:
    1545                        return 180.0F;
    1546                }
    1547            }
    1548
    1549            return 0.0F;
    1550        }
    1551
    1552        /**
    1553         * Returns whether player is sleeping or not
    1554         */
    1555        public boolean isPlayerSleeping()
    1556        {
    1557            return this.sleeping;
    1558        }
    1559
    1560        /**
    1561         * Returns whether or not the player is asleep and the screen has fully faded.
    1562         */
    1563        public boolean isPlayerFullyAsleep()
    1564        {
    1565            return this.sleeping && this.sleepTimer >= 100;
    1566        }
    1567
    1568        @SideOnly(Side.CLIENT)
    1569        public int getSleepTimer()
    1570        {
    1571            return this.sleepTimer;
    1572        }
    1573
    1574        /**
    1575         * Add a chat message to the player
    1576         */
    1577        public void addChatMessage(String par1Str) {}
    1578
    1579        /**
    1580         * Returns the coordinates to respawn the player based on last bed that the player sleep.
    1581         */
    1582        public ChunkCoordinates getSpawnChunk()
    1583        {
    1584            return this.spawnChunk;
    1585        }
    1586
    1587        /**
    1588         * Defines a spawn coordinate to player spawn. Used by bed after the player sleep on it.
    1589         */
    1590        public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates)
    1591        {
    1592            if (par1ChunkCoordinates != null)
    1593            {
    1594                this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates);
    1595            }
    1596            else
    1597            {
    1598                this.spawnChunk = null;
    1599            }
    1600        }
    1601
    1602        /**
    1603         * Will trigger the specified trigger.
    1604         */
    1605        public void triggerAchievement(StatBase par1StatBase)
    1606        {
    1607            this.addStat(par1StatBase, 1);
    1608        }
    1609
    1610        /**
    1611         * Adds a value to a statistic field.
    1612         */
    1613        public void addStat(StatBase par1StatBase, int par2) {}
    1614
    1615        /**
    1616         * Causes this entity to do an upwards motion (jumping).
    1617         */
    1618        protected void jump()
    1619        {
    1620            super.jump();
    1621            this.addStat(StatList.jumpStat, 1);
    1622
    1623            if (this.isSprinting())
    1624            {
    1625                this.addExhaustion(0.8F);
    1626            }
    1627            else
    1628            {
    1629                this.addExhaustion(0.2F);
    1630            }
    1631        }
    1632
    1633        /**
    1634         * Moves the entity based on the specified heading.  Args: strafe, forward
    1635         */
    1636        public void moveEntityWithHeading(float par1, float par2)
    1637        {
    1638            double var3 = this.posX;
    1639            double var5 = this.posY;
    1640            double var7 = this.posZ;
    1641
    1642            if (this.capabilities.isFlying && this.ridingEntity == null)
    1643            {
    1644                double var9 = this.motionY;
    1645                float var11 = this.jumpMovementFactor;
    1646                this.jumpMovementFactor = this.capabilities.getFlySpeed();
    1647                super.moveEntityWithHeading(par1, par2);
    1648                this.motionY = var9 * 0.6D;
    1649                this.jumpMovementFactor = var11;
    1650            }
    1651            else
    1652            {
    1653                super.moveEntityWithHeading(par1, par2);
    1654            }
    1655
    1656            this.addMovementStat(this.posX - var3, this.posY - var5, this.posZ - var7);
    1657        }
    1658
    1659        /**
    1660         * Adds a value to a movement statistic field - like run, walk, swin or climb.
    1661         */
    1662        public void addMovementStat(double par1, double par3, double par5)
    1663        {
    1664            if (this.ridingEntity == null)
    1665            {
    1666                int var7;
    1667
    1668                if (this.isInsideOfMaterial(Material.water))
    1669                {
    1670                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F);
    1671
    1672                    if (var7 > 0)
    1673                    {
    1674                        this.addStat(StatList.distanceDoveStat, var7);
    1675                        this.addExhaustion(0.015F * (float)var7 * 0.01F);
    1676                    }
    1677                }
    1678                else if (this.isInWater())
    1679                {
    1680                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
    1681
    1682                    if (var7 > 0)
    1683                    {
    1684                        this.addStat(StatList.distanceSwumStat, var7);
    1685                        this.addExhaustion(0.015F * (float)var7 * 0.01F);
    1686                    }
    1687                }
    1688                else if (this.isOnLadder())
    1689                {
    1690                    if (par3 > 0.0D)
    1691                    {
    1692                        this.addStat(StatList.distanceClimbedStat, (int)Math.round(par3 * 100.0D));
    1693                    }
    1694                }
    1695                else if (this.onGround)
    1696                {
    1697                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
    1698
    1699                    if (var7 > 0)
    1700                    {
    1701                        this.addStat(StatList.distanceWalkedStat, var7);
    1702
    1703                        if (this.isSprinting())
    1704                        {
    1705                            this.addExhaustion(0.099999994F * (float)var7 * 0.01F);
    1706                        }
    1707                        else
    1708                        {
    1709                            this.addExhaustion(0.01F * (float)var7 * 0.01F);
    1710                        }
    1711                    }
    1712                }
    1713                else
    1714                {
    1715                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
    1716
    1717                    if (var7 > 25)
    1718                    {
    1719                        this.addStat(StatList.distanceFlownStat, var7);
    1720                    }
    1721                }
    1722            }
    1723        }
    1724
    1725        /**
    1726         * Adds a value to a mounted movement statistic field - by minecart, boat, or pig.
    1727         */
    1728        private void addMountedMovementStat(double par1, double par3, double par5)
    1729        {
    1730            if (this.ridingEntity != null)
    1731            {
    1732                int var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F);
    1733
    1734                if (var7 > 0)
    1735                {
    1736                    if (this.ridingEntity instanceof EntityMinecart)
    1737                    {
    1738                        this.addStat(StatList.distanceByMinecartStat, var7);
    1739
    1740                        if (this.startMinecartRidingCoordinate == null)
    1741                        {
    1742                            this.startMinecartRidingCoordinate = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    1743                        }
    1744                        else if ((double)this.startMinecartRidingCoordinate.getDistanceSquared(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) >= 1000000.0D)
    1745                        {
    1746                            this.addStat(AchievementList.onARail, 1);
    1747                        }
    1748                    }
    1749                    else if (this.ridingEntity instanceof EntityBoat)
    1750                    {
    1751                        this.addStat(StatList.distanceByBoatStat, var7);
    1752                    }
    1753                    else if (this.ridingEntity instanceof EntityPig)
    1754                    {
    1755                        this.addStat(StatList.distanceByPigStat, var7);
    1756                    }
    1757                }
    1758            }
    1759        }
    1760
    1761        /**
    1762         * Called when the mob is falling. Calculates and applies fall damage.
    1763         */
    1764        protected void fall(float par1)
    1765        {
    1766            if (!this.capabilities.allowFlying)
    1767            {
    1768                if (par1 >= 2.0F)
    1769                {
    1770                    this.addStat(StatList.distanceFallenStat, (int)Math.round((double)par1 * 100.0D));
    1771                }
    1772
    1773                super.fall(par1);
    1774            }
    1775        }
    1776
    1777        /**
    1778         * This method gets called when the entity kills another one.
    1779         */
    1780        public void onKillEntity(EntityLiving par1EntityLiving)
    1781        {
    1782            if (par1EntityLiving instanceof EntityMob)
    1783            {
    1784                this.triggerAchievement(AchievementList.killEnemy);
    1785            }
    1786        }
    1787
    1788        @SideOnly(Side.CLIENT)
    1789
    1790        /**
    1791         * Gets the Icon Index of the item currently held
    1792         */
    1793        public int getItemIcon(ItemStack par1ItemStack, int par2)
    1794        {
    1795            int var3 = super.getItemIcon(par1ItemStack, par2);
    1796
    1797            if (par1ItemStack.itemID == Item.fishingRod.shiftedIndex && this.fishEntity != null)
    1798            {
    1799                var3 = par1ItemStack.getIconIndex() + 16;
    1800            }
    1801            else
    1802            {
    1803                if (par1ItemStack.getItem().requiresMultipleRenderPasses())
    1804                {
    1805                    return par1ItemStack.getItem().getIconFromDamageForRenderPass(par1ItemStack.getItemDamage(), par2);
    1806                }
    1807
    1808                if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.shiftedIndex)
    1809                {
    1810                    int var4 = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount;
    1811
    1812                    if (var4 >= 18)
    1813                    {
    1814                        return 133;
    1815                    }
    1816
    1817                    if (var4 > 13)
    1818                    {
    1819                        return 117;
    1820                    }
    1821
    1822                    if (var4 > 0)
    1823                    {
    1824                        return 101;
    1825                    }
    1826                }
    1827                var3 = par1ItemStack.getItem().getIconIndex(par1ItemStack, par2, this, itemInUse, itemInUseCount);
    1828            }
    1829
    1830            return var3;
    1831        }
    1832
    1833        /**
    1834         * Called by portal blocks when an entity is within it.
    1835         */
    1836        public void setInPortal()
    1837        {
    1838            if (this.timeUntilPortal > 0)
    1839            {
    1840                this.timeUntilPortal = 10;
    1841            }
    1842            else
    1843            {
    1844                this.inPortal = true;
    1845            }
    1846        }
    1847
    1848        /**
    1849         * This method increases the player's current amount of experience.
    1850         */
    1851        public void addExperience(int par1)
    1852        {
    1853            this.score += par1;
    1854            int var2 = Integer.MAX_VALUE - this.experienceTotal;
    1855
    1856            if (par1 > var2)
    1857            {
    1858                par1 = var2;
    1859            }
    1860
    1861            this.experience += (float)par1 / (float)this.xpBarCap();
    1862
    1863            for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float)this.xpBarCap())
    1864            {
    1865                this.experience = (this.experience - 1.0F) * (float)this.xpBarCap();
    1866                this.increaseLevel();
    1867            }
    1868        }
    1869
    1870        /**
    1871         * Decrease the player level, used to pay levels for enchantments on items at enchanted table.
    1872         */
    1873        public void removeExperience(int par1)
    1874        {
    1875            this.experienceLevel -= par1;
    1876
    1877            if (this.experienceLevel < 0)
    1878            {
    1879                this.experienceLevel = 0;
    1880            }
    1881        }
    1882
    1883        /**
    1884         * This method returns the cap amount of experience that the experience bar can hold. With each level, the
    1885         * experience cap on the player's experience bar is raised by 10.
    1886         */
    1887        public int xpBarCap()
    1888        {
    1889            return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17);
    1890        }
    1891
    1892        /**
    1893         * This method increases the player's experience level by one.
    1894         */
    1895        private void increaseLevel()
    1896        {
    1897            ++this.experienceLevel;
    1898        }
    1899
    1900        /**
    1901         * increases exhaustion level by supplied amount
    1902         */
    1903        public void addExhaustion(float par1)
    1904        {
    1905            if (!this.capabilities.disableDamage)
    1906            {
    1907                if (!this.worldObj.isRemote)
    1908                {
    1909                    this.foodStats.addExhaustion(par1);
    1910                }
    1911            }
    1912        }
    1913
    1914        /**
    1915         * Returns the player's FoodStats object.
    1916         */
    1917        public FoodStats getFoodStats()
    1918        {
    1919            return this.foodStats;
    1920        }
    1921
    1922        public boolean canEat(boolean par1)
    1923        {
    1924            return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage;
    1925        }
    1926
    1927        /**
    1928         * Checks if the player's health is not full and not zero.
    1929         */
    1930        public boolean shouldHeal()
    1931        {
    1932            return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth();
    1933        }
    1934
    1935        /**
    1936         * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration
    1937         */
    1938        public void setItemInUse(ItemStack par1ItemStack, int par2)
    1939        {
    1940            if (par1ItemStack != this.itemInUse)
    1941            {
    1942                this.itemInUse = par1ItemStack;
    1943                this.itemInUseCount = par2;
    1944
    1945                if (!this.worldObj.isRemote)
    1946                {
    1947                    this.setEating(true);
    1948                }
    1949            }
    1950        }
    1951
    1952        public boolean canPlayerEdit(int par1, int par2, int par3)
    1953        {
    1954            return this.capabilities.allowEdit;
    1955        }
    1956
    1957        /**
    1958         * Get the experience points the entity currently has.
    1959         */
    1960        protected int getExperiencePoints(EntityPlayer par1EntityPlayer)
    1961        {
    1962            int var2 = this.experienceLevel * 7;
    1963            return var2 > 100 ? 100 : var2;
    1964        }
    1965
    1966        /**
    1967         * Only use is to identify if class is an instance of player for experience dropping
    1968         */
    1969        protected boolean isPlayer()
    1970        {
    1971            return true;
    1972        }
    1973
    1974        /**
    1975         * Gets the username of the entity.
    1976         */
    1977        public String getEntityName()
    1978        {
    1979            return this.username;
    1980        }
    1981
    1982        public void travelToTheEnd(int par1) {}
    1983
    1984        /**
    1985         * Copies the values from the given player into this player if boolean par2 is true. Always clones Ender Chest
    1986         * Inventory.
    1987         */
    1988        public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2)
    1989        {
    1990            if (par2)
    1991            {
    1992                this.inventory.copyInventory(par1EntityPlayer.inventory);
    1993                this.health = par1EntityPlayer.health;
    1994                this.foodStats = par1EntityPlayer.foodStats;
    1995                this.experienceLevel = par1EntityPlayer.experienceLevel;
    1996                this.experienceTotal = par1EntityPlayer.experienceTotal;
    1997                this.experience = par1EntityPlayer.experience;
    1998                this.score = par1EntityPlayer.score;
    1999            }
    2000
    2001            this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest;
    2002        }
    2003
    2004        /**
    2005         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
    2006         * prevent them from trampling crops
    2007         */
    2008        protected boolean canTriggerWalking()
    2009        {
    2010            return !this.capabilities.isFlying;
    2011        }
    2012
    2013        /**
    2014         * Sends the player's abilities to the server (if there is one).
    2015         */
    2016        public void sendPlayerAbilities() {}
    2017
    2018        public void sendGameTypeToPlayer(EnumGameType par1EnumGameType) {}
    2019
    2020        /**
    2021         * Gets the name of this command sender (usually username, but possibly "Rcon")
    2022         */
    2023        public String getCommandSenderName()
    2024        {
    2025            return this.username;
    2026        }
    2027
    2028        public StringTranslate getTranslator()
    2029        {
    2030            return StringTranslate.getInstance();
    2031        }
    2032
    2033        /**
    2034         * Translates and formats the given string key with the given arguments.
    2035         */
    2036        public String translateString(String par1Str, Object ... par2ArrayOfObj)
    2037        {
    2038            return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj);
    2039        }
    2040
    2041        /**
    2042         * Returns the InventoryEnderChest of this player.
    2043         */
    2044        public InventoryEnderChest getInventoryEnderChest()
    2045        {
    2046            return this.theInventoryEnderChest;
    2047        }
    2048
    2049        public void openGui(Object mod, int modGuiId, World world, int x, int y, int z)
    2050        {
    2051            FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z);
    2052        }
    2053    }