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 }