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