    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import net.minecraft.client.Minecraft;
    006
    007    @SideOnly(Side.CLIENT)
    008    public class EntityPlayerSP extends EntityPlayer
    009    {
    010        public MovementInput movementInput;
    011        protected Minecraft mc;
    012
    013        /**
    014         * Used to tell if the player pressed forward twice. If this is at 0 and it's pressed (And they are allowed to
    015         * sprint, aka enough food on the ground etc) it sets this to 7. If it's pressed and it's greater than 0 enable
    016         * sprinting.
    017         */
    018        protected int sprintToggleTimer = 0;
    019
    020        /** Ticks left before sprinting is disabled. */
    021        public int sprintingTicksLeft = 0;
    022        public float renderArmYaw;
    023        public float renderArmPitch;
    024        public float prevRenderArmYaw;
    025        public float prevRenderArmPitch;
    026        private MouseFilter field_71162_ch = new MouseFilter();
    027        private MouseFilter field_71160_ci = new MouseFilter();
    028        private MouseFilter field_71161_cj = new MouseFilter();
    029
    030        public EntityPlayerSP(Minecraft par1Minecraft, World par2World, Session par3Session, int par4)
    031        {
    032            super(par2World);
    033            this.mc = par1Minecraft;
    034            this.dimension = par4;
    035
    036            if (par3Session != null && par3Session.username != null && par3Session.username.length() > 0)
    037            {
    038                this.skinUrl = "http://skins.minecraft.net/MinecraftSkins/" + StringUtils.stripControlCodes(par3Session.username) + ".png";
    039            }
    040
    041            this.username = par3Session.username;
    042        }
    043
    044        /**
    045         * Tries to moves the entity by the passed in displacement. Args: x, y, z
    046         */
    047        public void moveEntity(double par1, double par3, double par5)
    048        {
    049            super.moveEntity(par1, par3, par5);
    050        }
    051
    052        public void updateEntityActionState()
    053        {
    054            super.updateEntityActionState();
    055            this.moveStrafing = this.movementInput.moveStrafe;
    056            this.moveForward = this.movementInput.moveForward;
    057            this.isJumping = this.movementInput.jump;
    058            this.prevRenderArmYaw = this.renderArmYaw;
    059            this.prevRenderArmPitch = this.renderArmPitch;
    060            this.renderArmPitch = (float)((double)this.renderArmPitch + (double)(this.rotationPitch - this.renderArmPitch) * 0.5D);
    061            this.renderArmYaw = (float)((double)this.renderArmYaw + (double)(this.rotationYaw - this.renderArmYaw) * 0.5D);
    062        }
    063
    064        /**
    065         * Returns whether the entity is in a local (client) world
    066         */
    067        protected boolean isClientWorld()
    068        {
    069            return true;
    070        }
    071
    072        /**
    073         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    074         * use this to react to sunlight and start to burn.
    075         */
    076        public void onLivingUpdate()
    077        {
    078            if (this.sprintingTicksLeft > 0)
    079            {
    080                --this.sprintingTicksLeft;
    081
    082                if (this.sprintingTicksLeft == 0)
    083                {
    084                    this.setSprinting(false);
    085                }
    086            }
    087
    088            if (this.sprintToggleTimer > 0)
    089            {
    090                --this.sprintToggleTimer;
    091            }
    092
    093            if (this.mc.playerController.func_78747_a())
    094            {
    095                this.posX = this.posZ = 0.5D;
    096                this.posX = 0.0D;
    097                this.posZ = 0.0D;
    098                this.rotationYaw = (float)this.ticksExisted / 12.0F;
    099                this.rotationPitch = 10.0F;
    100                this.posY = 68.5D;
    101            }
    102            else
    103            {
    104                if (!this.mc.statFileWriter.hasAchievementUnlocked(AchievementList.openInventory))
    105                {
    106                    this.mc.guiAchievement.queueAchievementInformation(AchievementList.openInventory);
    107                }
    108
    109                this.prevTimeInPortal = this.timeInPortal;
    110
    111                if (this.inPortal)
    112                {
    113                    if (this.mc.currentScreen != null)
    114                    {
    115                        this.mc.displayGuiScreen((GuiScreen)null);
    116                    }
    117
    118                    if (this.timeInPortal == 0.0F)
    119                    {
    120                        this.mc.sndManager.playSoundFX("portal.trigger", 1.0F, this.rand.nextFloat() * 0.4F + 0.8F);
    121                    }
    122
    123                    this.timeInPortal += 0.0125F;
    124
    125                    if (this.timeInPortal >= 1.0F)
    126                    {
    127                        this.timeInPortal = 1.0F;
    128                    }
    129
    130                    this.inPortal = false;
    131                }
    132                else if (this.isPotionActive(Potion.confusion) && this.getActivePotionEffect(Potion.confusion).getDuration() > 60)
    133                {
    134                    this.timeInPortal += 0.006666667F;
    135
    136                    if (this.timeInPortal > 1.0F)
    137                    {
    138                        this.timeInPortal = 1.0F;
    139                    }
    140                }
    141                else
    142                {
    143                    if (this.timeInPortal > 0.0F)
    144                    {
    145                        this.timeInPortal -= 0.05F;
    146                    }
    147
    148                    if (this.timeInPortal < 0.0F)
    149                    {
    150                        this.timeInPortal = 0.0F;
    151                    }
    152                }
    153
    154                if (this.timeUntilPortal > 0)
    155                {
    156                    --this.timeUntilPortal;
    157                }
    158
    159                boolean var1 = this.movementInput.jump;
    160                float var2 = 0.8F;
    161                boolean var3 = this.movementInput.moveForward >= var2;
    162                this.movementInput.updatePlayerMoveState();
    163
    164                if (this.isUsingItem())
    165                {
    166                    this.movementInput.moveStrafe *= 0.2F;
    167                    this.movementInput.moveForward *= 0.2F;
    168                    this.sprintToggleTimer = 0;
    169                }
    170
    171                if (this.movementInput.sneak && this.ySize < 0.2F)
    172                {
    173                    this.ySize = 0.2F;
    174                }
    175
    176                this.pushOutOfBlocks(this.posX - (double)this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ + (double)this.width * 0.35D);
    177                this.pushOutOfBlocks(this.posX - (double)this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ - (double)this.width * 0.35D);
    178                this.pushOutOfBlocks(this.posX + (double)this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ - (double)this.width * 0.35D);
    179                this.pushOutOfBlocks(this.posX + (double)this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ + (double)this.width * 0.35D);
    180                boolean var4 = (float)this.getFoodStats().getFoodLevel() > 6.0F || this.capabilities.allowFlying;
    181
    182                if (this.onGround && !var3 && this.movementInput.moveForward >= var2 && !this.isSprinting() && var4 && !this.isUsingItem() && !this.isPotionActive(Potion.blindness))
    183                {
    184                    if (this.sprintToggleTimer == 0)
    185                    {
    186                        this.sprintToggleTimer = 7;
    187                    }
    188                    else
    189                    {
    190                        this.setSprinting(true);
    191                        this.sprintToggleTimer = 0;
    192                    }
    193                }
    194
    195                if (this.isSneaking())
    196                {
    197                    this.sprintToggleTimer = 0;
    198                }
    199
    200                if (this.isSprinting() && (this.movementInput.moveForward < var2 || this.isCollidedHorizontally || !var4))
    201                {
    202                    this.setSprinting(false);
    203                }
    204
    205                if (this.capabilities.allowFlying && !var1 && this.movementInput.jump)
    206                {
    207                    if (this.flyToggleTimer == 0)
    208                    {
    209                        this.flyToggleTimer = 7;
    210                    }
    211                    else
    212                    {
    213                        this.capabilities.isFlying = !this.capabilities.isFlying;
    214                        this.sendPlayerAbilities();
    215                        this.flyToggleTimer = 0;
    216                    }
    217                }
    218
    219                if (this.capabilities.isFlying)
    220                {
    221                    if (this.movementInput.sneak)
    222                    {
    223                        this.motionY -= 0.15D;
    224                    }
    225
    226                    if (this.movementInput.jump)
    227                    {
    228                        this.motionY += 0.15D;
    229                    }
    230                }
    231
    232                super.onLivingUpdate();
    233
    234                if (this.onGround && this.capabilities.isFlying)
    235                {
    236                    this.capabilities.isFlying = false;
    237                    this.sendPlayerAbilities();
    238                }
    239            }
    240        }
    241
    242        /**
    243         * Gets the player's field of view multiplier. (ex. when flying)
    244         */
    245        public float getFOVMultiplier()
    246        {
    247            float var1 = 1.0F;
    248
    249            if (this.capabilities.isFlying)
    250            {
    251                var1 *= 1.1F;
    252            }
    253
    254            var1 *= (this.landMovementFactor * this.getSpeedModifier() / this.speedOnGround + 1.0F) / 2.0F;
    255
    256            if (this.isUsingItem() && this.getItemInUse().itemID == Item.bow.shiftedIndex)
    257            {
    258                int var2 = this.getItemInUseDuration();
    259                float var3 = (float)var2 / 20.0F;
    260
    261                if (var3 > 1.0F)
    262                {
    263                    var3 = 1.0F;
    264                }
    265                else
    266                {
    267                    var3 *= var3;
    268                }
    269
    270                var1 *= 1.0F - var3 * 0.15F;
    271            }
    272
    273            return var1;
    274        }
    275
    276        /**
    277         * (abstract) Protected helper method to write subclass entity data to NBT.
    278         */
    279        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    280        {
    281            super.writeEntityToNBT(par1NBTTagCompound);
    282            par1NBTTagCompound.setInteger("Score", this.score);
    283        }
    284
    285        public void updateCloak()
    286        {
    287            this.playerCloakUrl = "http://skins.minecraft.net/MinecraftCloaks/" + StringUtils.stripControlCodes(this.username) + ".png";
    288            this.cloakUrl = this.playerCloakUrl;
    289        }
    290
    291        /**
    292         * (abstract) Protected helper method to read subclass entity data from NBT.
    293         */
    294        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    295        {
    296            super.readEntityFromNBT(par1NBTTagCompound);
    297            this.score = par1NBTTagCompound.getInteger("Score");
    298        }
    299
    300        /**
    301         * sets current screen to null (used on escape buttons of GUIs)
    302         */
    303        public void closeScreen()
    304        {
    305            super.closeScreen();
    306            this.mc.displayGuiScreen((GuiScreen)null);
    307        }
    308
    309        /**
    310         * Displays the GUI for editing a sign. Args: tileEntitySign
    311         */
    312        public void displayGUIEditSign(TileEntitySign par1TileEntitySign)
    313        {
    314            this.mc.displayGuiScreen(new GuiEditSign(par1TileEntitySign));
    315        }
    316
    317        /**
    318         * Displays the GUI for interacting with a book.
    319         */
    320        public void displayGUIBook(ItemStack par1ItemStack)
    321        {
    322            Item var2 = par1ItemStack.getItem();
    323
    324            if (var2 == Item.writtenBook)
    325            {
    326                this.mc.displayGuiScreen(new GuiScreenBook(this, par1ItemStack, false));
    327            }
    328            else if (var2 == Item.writableBook)
    329            {
    330                this.mc.displayGuiScreen(new GuiScreenBook(this, par1ItemStack, true));
    331            }
    332        }
    333
    334        /**
    335         * Displays the GUI for interacting with a chest inventory. Args: chestInventory
    336         */
    337        public void displayGUIChest(IInventory par1IInventory)
    338        {
    339            this.mc.displayGuiScreen(new GuiChest(this.inventory, par1IInventory));
    340        }
    341
    342        /**
    343         * Displays the crafting GUI for a workbench.
    344         */
    345        public void displayGUIWorkbench(int par1, int par2, int par3)
    346        {
    347            this.mc.displayGuiScreen(new GuiCrafting(this.inventory, this.worldObj, par1, par2, par3));
    348        }
    349
    350        public void displayGUIEnchantment(int par1, int par2, int par3)
    351        {
    352            this.mc.displayGuiScreen(new GuiEnchantment(this.inventory, this.worldObj, par1, par2, par3));
    353        }
    354
    355        /**
    356         * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace
    357         */
    358        public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace)
    359        {
    360            this.mc.displayGuiScreen(new GuiFurnace(this.inventory, par1TileEntityFurnace));
    361        }
    362
    363        /**
    364         * Displays the GUI for interacting with a brewing stand.
    365         */
    366        public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand)
    367        {
    368            this.mc.displayGuiScreen(new GuiBrewingStand(this.inventory, par1TileEntityBrewingStand));
    369        }
    370
    371        /**
    372         * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser
    373         */
    374        public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser)
    375        {
    376            this.mc.displayGuiScreen(new GuiDispenser(this.inventory, par1TileEntityDispenser));
    377        }
    378
    379        public void displayGUIMerchant(IMerchant par1IMerchant)
    380        {
    381            this.mc.displayGuiScreen(new GuiMerchant(this.inventory, par1IMerchant, this.worldObj));
    382        }
    383
    384        /**
    385         * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically
    386         */
    387        public void onCriticalHit(Entity par1Entity)
    388        {
    389            this.mc.effectRenderer.addEffect(new EntityCrit2FX(this.mc.theWorld, par1Entity));
    390        }
    391
    392        public void onEnchantmentCritical(Entity par1Entity)
    393        {
    394            EntityCrit2FX var2 = new EntityCrit2FX(this.mc.theWorld, par1Entity, "magicCrit");
    395            this.mc.effectRenderer.addEffect(var2);
    396        }
    397
    398        /**
    399         * Called whenever an item is picked up from walking over it. Args: pickedUpEntity, stackSize
    400         */
    401        public void onItemPickup(Entity par1Entity, int par2)
    402        {
    403            this.mc.effectRenderer.addEffect(new EntityPickupFX(this.mc.theWorld, par1Entity, this, -0.5F));
    404        }
    405
    406        /**
    407         * Returns if this entity is sneaking.
    408         */
    409        public boolean isSneaking()
    410        {
    411            return this.movementInput.sneak && !this.sleeping;
    412        }
    413
    414        /**
    415         * Updates health locally.
    416         */
    417        public void setHealth(int par1)
    418        {
    419            int var2 = this.getHealth() - par1;
    420
    421            if (var2 <= 0)
    422            {
    423                this.setEntityHealth(par1);
    424
    425                if (var2 < 0)
    426                {
    427                    this.hurtResistantTime = this.maxHurtResistantTime / 2;
    428                }
    429            }
    430            else
    431            {
    432                this.lastDamage = var2;
    433                this.setEntityHealth(this.getHealth());
    434                this.hurtResistantTime = this.maxHurtResistantTime;
    435                this.damageEntity(DamageSource.generic, var2);
    436                this.hurtTime = this.maxHurtTime = 10;
    437            }
    438        }
    439
    440        /**
    441         * Add a chat message to the player
    442         */
    443        public void addChatMessage(String par1Str)
    444        {
    445            this.mc.ingameGUI.getChatGUI().addTranslatedMessage(par1Str, new Object[0]);
    446        }
    447
    448        /**
    449         * Adds a value to a statistic field.
    450         */
    451        public void addStat(StatBase par1StatBase, int par2)
    452        {
    453            if (par1StatBase != null)
    454            {
    455                if (par1StatBase.isAchievement())
    456                {
    457                    Achievement var3 = (Achievement)par1StatBase;
    458
    459                    if (var3.parentAchievement == null || this.mc.statFileWriter.hasAchievementUnlocked(var3.parentAchievement))
    460                    {
    461                        if (!this.mc.statFileWriter.hasAchievementUnlocked(var3))
    462                        {
    463                            this.mc.guiAchievement.queueTakenAchievement(var3);
    464                        }
    465
    466                        this.mc.statFileWriter.readStat(par1StatBase, par2);
    467                    }
    468                }
    469                else
    470                {
    471                    this.mc.statFileWriter.readStat(par1StatBase, par2);
    472                }
    473            }
    474        }
    475
    476        private boolean isBlockTranslucent(int par1, int par2, int par3)
    477        {
    478            return this.worldObj.isBlockNormalCube(par1, par2, par3);
    479        }
    480
    481        /**
    482         * Adds velocity to push the entity out of blocks at the specified x, y, z position Args: x, y, z
    483         */
    484        protected boolean pushOutOfBlocks(double par1, double par3, double par5)
    485        {
    486            int var7 = MathHelper.floor_double(par1);
    487            int var8 = MathHelper.floor_double(par3);
    488            int var9 = MathHelper.floor_double(par5);
    489            double var10 = par1 - (double)var7;
    490            double var12 = par5 - (double)var9;
    491
    492            if (this.isBlockTranslucent(var7, var8, var9) || this.isBlockTranslucent(var7, var8 + 1, var9))
    493            {
    494                boolean var14 = !this.isBlockTranslucent(var7 - 1, var8, var9) && !this.isBlockTranslucent(var7 - 1, var8 + 1, var9);
    495                boolean var15 = !this.isBlockTranslucent(var7 + 1, var8, var9) && !this.isBlockTranslucent(var7 + 1, var8 + 1, var9);
    496                boolean var16 = !this.isBlockTranslucent(var7, var8, var9 - 1) && !this.isBlockTranslucent(var7, var8 + 1, var9 - 1);
    497                boolean var17 = !this.isBlockTranslucent(var7, var8, var9 + 1) && !this.isBlockTranslucent(var7, var8 + 1, var9 + 1);
    498                byte var18 = -1;
    499                double var19 = 9999.0D;
    500
    501                if (var14 && var10 < var19)
    502                {
    503                    var19 = var10;
    504                    var18 = 0;
    505                }
    506
    507                if (var15 && 1.0D - var10 < var19)
    508                {
    509                    var19 = 1.0D - var10;
    510                    var18 = 1;
    511                }
    512
    513                if (var16 && var12 < var19)
    514                {
    515                    var19 = var12;
    516                    var18 = 4;
    517                }
    518
    519                if (var17 && 1.0D - var12 < var19)
    520                {
    521                    var19 = 1.0D - var12;
    522                    var18 = 5;
    523                }
    524
    525                float var21 = 0.1F;
    526
    527                if (var18 == 0)
    528                {
    529                    this.motionX = (double)(-var21);
    530                }
    531
    532                if (var18 == 1)
    533                {
    534                    this.motionX = (double)var21;
    535                }
    536
    537                if (var18 == 4)
    538                {
    539                    this.motionZ = (double)(-var21);
    540                }
    541
    542                if (var18 == 5)
    543                {
    544                    this.motionZ = (double)var21;
    545                }
    546            }
    547
    548            return false;
    549        }
    550
    551        /**
    552         * Set sprinting switch for Entity.
    553         */
    554        public void setSprinting(boolean par1)
    555        {
    556            super.setSprinting(par1);
    557            this.sprintingTicksLeft = par1 ? 600 : 0;
    558        }
    559
    560        /**
    561         * Sets the current XP, total XP, and level number.
    562         */
    563        public void setXPStats(float par1, int par2, int par3)
    564        {
    565            this.experience = par1;
    566            this.experienceTotal = par2;
    567            this.experienceLevel = par3;
    568        }
    569
    570        public void sendChatToPlayer(String par1Str)
    571        {
    572            this.mc.ingameGUI.getChatGUI().printChatMessage(par1Str);
    573        }
    574
    575        /**
    576         * Returns true if the command sender is allowed to use the given command.
    577         */
    578        public boolean canCommandSenderUseCommand(String par1Str)
    579        {
    580            return this.worldObj.getWorldInfo().areCommandsAllowed();
    581        }
    582    }