    001    package net.minecraft.src;
    002
    003    public class EntityAIControlledByPlayer extends EntityAIBase
    004    {
    005        private final EntityLiving thisEntity;
    006        private final float maxSpeed;
    007        private float currentSpeed = 0.0F;
    008
    009        /** Whether the entity's speed is boosted. */
    010        private boolean speedBoosted = false;
    011
    012        /**
    013         * Counter for speed boosting, upon reaching maxSpeedBoostTime the speed boost will be disabled
    014         */
    015        private int speedBoostTime = 0;
    016
    017        /** Maximum time the entity's speed should be boosted for. */
    018        private int maxSpeedBoostTime = 0;
    019
    020        public EntityAIControlledByPlayer(EntityLiving par1EntityLiving, float par2)
    021        {
    022            this.thisEntity = par1EntityLiving;
    023            this.maxSpeed = par2;
    024            this.setMutexBits(7);
    025        }
    026
    027        /**
    028         * Execute a one shot task or start executing a continuous task
    029         */
    030        public void startExecuting()
    031        {
    032            this.currentSpeed = 0.0F;
    033        }
    034
    035        /**
    036         * Resets the task
    037         */
    038        public void resetTask()
    039        {
    040            this.speedBoosted = false;
    041            this.currentSpeed = 0.0F;
    042        }
    043
    044        /**
    045         * Returns whether the EntityAIBase should begin execution.
    046         */
    047        public boolean shouldExecute()
    048        {
    049            return this.thisEntity.isEntityAlive() && this.thisEntity.riddenByEntity != null && this.thisEntity.riddenByEntity instanceof EntityPlayer && (this.speedBoosted || this.thisEntity.canBeSteered());
    050        }
    051
    052        /**
    053         * Updates the task
    054         */
    055        public void updateTask()
    056        {
    057            EntityPlayer var1 = (EntityPlayer)this.thisEntity.riddenByEntity;
    058            EntityCreature var2 = (EntityCreature)this.thisEntity;
    059            float var3 = MathHelper.wrapAngleTo180_float(var1.rotationYaw - this.thisEntity.rotationYaw) * 0.5F;
    060
    061            if (var3 > 5.0F)
    062            {
    063                var3 = 5.0F;
    064            }
    065
    066            if (var3 < -5.0F)
    067            {
    068                var3 = -5.0F;
    069            }
    070
    071            this.thisEntity.rotationYaw = MathHelper.wrapAngleTo180_float(this.thisEntity.rotationYaw + var3);
    072
    073            if (this.currentSpeed < this.maxSpeed)
    074            {
    075                this.currentSpeed += (this.maxSpeed - this.currentSpeed) * 0.01F;
    076            }
    077
    078            if (this.currentSpeed > this.maxSpeed)
    079            {
    080                this.currentSpeed = this.maxSpeed;
    081            }
    082
    083            int var4 = MathHelper.floor_double(this.thisEntity.posX);
    084            int var5 = MathHelper.floor_double(this.thisEntity.posY);
    085            int var6 = MathHelper.floor_double(this.thisEntity.posZ);
    086            float var7 = this.currentSpeed;
    087
    088            if (this.speedBoosted)
    089            {
    090                if (this.speedBoostTime++ > this.maxSpeedBoostTime)
    091                {
    092                    this.speedBoosted = false;
    093                }
    094
    095                var7 += var7 * 1.15F * MathHelper.sin((float)this.speedBoostTime / (float)this.maxSpeedBoostTime * (float)Math.PI);
    096            }
    097
    098            float var8 = 0.91F;
    099
    100            if (this.thisEntity.onGround)
    101            {
    102                var8 = 0.54600006F;
    103                int var9 = this.thisEntity.worldObj.getBlockId(MathHelper.floor_float((float)var4), MathHelper.floor_float((float)var5) - 1, MathHelper.floor_float((float)var6));
    104
    105                if (var9 > 0)
    106                {
    107                    var8 = Block.blocksList[var9].slipperiness * 0.91F;
    108                }
    109            }
    110
    111            float var21 = 0.16277136F / (var8 * var8 * var8);
    112            float var10 = MathHelper.sin(var2.rotationYaw * (float)Math.PI / 180.0F);
    113            float var11 = MathHelper.cos(var2.rotationYaw * (float)Math.PI / 180.0F);
    114            float var12 = var2.getAIMoveSpeed() * var21;
    115            float var13 = Math.max(var7, 1.0F);
    116            var13 = var12 / var13;
    117            float var14 = var7 * var13;
    118            float var15 = -(var14 * var10);
    119            float var16 = var14 * var11;
    120
    121            if (MathHelper.abs(var15) > MathHelper.abs(var16))
    122            {
    123                if (var15 < 0.0F)
    124                {
    125                    var15 -= this.thisEntity.width / 2.0F;
    126                }
    127
    128                if (var15 > 0.0F)
    129                {
    130                    var15 += this.thisEntity.width / 2.0F;
    131                }
    132
    133                var16 = 0.0F;
    134            }
    135            else
    136            {
    137                var15 = 0.0F;
    138
    139                if (var16 < 0.0F)
    140                {
    141                    var16 -= this.thisEntity.width / 2.0F;
    142                }
    143
    144                if (var16 > 0.0F)
    145                {
    146                    var16 += this.thisEntity.width / 2.0F;
    147                }
    148            }
    149
    150            int var17 = MathHelper.floor_double(this.thisEntity.posX + (double)var15);
    151            int var18 = MathHelper.floor_double(this.thisEntity.posZ + (double)var16);
    152            PathPoint var19 = new PathPoint(MathHelper.floor_float(this.thisEntity.width + 1.0F), MathHelper.floor_float(this.thisEntity.height + var1.height + 1.0F), MathHelper.floor_float(this.thisEntity.width + 1.0F));
    153
    154            if ((var4 != var17 || var6 != var18) && PathFinder.func_82565_a(this.thisEntity, var17, var5, var18, var19, false, false, true) == 0 && PathFinder.func_82565_a(this.thisEntity, var4, var5 + 1, var6, var19, false, false, true) == 1 && PathFinder.func_82565_a(this.thisEntity, var17, var5 + 1, var18, var19, false, false, true) == 1)
    155            {
    156                var2.getJumpHelper().setJumping();
    157            }
    158
    159            if (!var1.capabilities.isCreativeMode && this.currentSpeed >= this.maxSpeed * 0.5F && this.thisEntity.getRNG().nextFloat() < 0.006F && !this.speedBoosted)
    160            {
    161                ItemStack var20 = var1.getHeldItem();
    162
    163                if (var20 != null && var20.itemID == Item.carrotOnAStick.shiftedIndex)
    164                {
    165                    var20.damageItem(1, var1);
    166
    167                    if (var20.stackSize == 0)
    168                    {
    169                        var1.inventory.mainInventory[var1.inventory.currentItem] = new ItemStack(Item.fishingRod);
    170                    }
    171                }
    172            }
    173
    174            this.thisEntity.moveEntityWithHeading(0.0F, var7);
    175        }
    176
    177        /**
    178         * Return whether the entity's speed is boosted.
    179         */
    180        public boolean isSpeedBoosted()
    181        {
    182            return this.speedBoosted;
    183        }
    184
    185        /**
    186         * Boost the entity's movement speed.
    187         */
    188        public void boostSpeed()
    189        {
    190            this.speedBoosted = true;
    191            this.speedBoostTime = 0;
    192            this.maxSpeedBoostTime = this.thisEntity.getRNG().nextInt(841) + 140;
    193        }
    194
    195        /**
    196         * Return whether the entity is being controlled by a player.
    197         */
    198        public boolean isControlledByPlayer()
    199        {
    200            return !this.isSpeedBoosted() && this.currentSpeed > this.maxSpeed * 0.3F;
    201        }
    202    }