001 package net.minecraft.src;
002
003 public class EntitySquid extends EntityWaterMob
004 {
005 public float field_70861_d = 0.0F;
006 public float field_70862_e = 0.0F;
007 public float field_70859_f = 0.0F;
008 public float field_70860_g = 0.0F;
009 public float field_70867_h = 0.0F;
010 public float field_70868_i = 0.0F;
011
012 /** angle of the tentacles in radians */
013 public float tentacleAngle = 0.0F;
014
015 /** the last calculated angle of the tentacles in radians */
016 public float lastTentacleAngle = 0.0F;
017 private float randomMotionSpeed = 0.0F;
018 private float field_70864_bA = 0.0F;
019 private float field_70871_bB = 0.0F;
020 private float randomMotionVecX = 0.0F;
021 private float randomMotionVecY = 0.0F;
022 private float randomMotionVecZ = 0.0F;
023
024 public EntitySquid(World par1World)
025 {
026 super(par1World);
027 this.texture = "/mob/squid.png";
028 this.setSize(0.95F, 0.95F);
029 this.field_70864_bA = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F;
030 }
031
032 public int getMaxHealth()
033 {
034 return 10;
035 }
036
037 /**
038 * Returns the sound this mob makes while it's alive.
039 */
040 protected String getLivingSound()
041 {
042 return null;
043 }
044
045 /**
046 * Returns the sound this mob makes when it is hurt.
047 */
048 protected String getHurtSound()
049 {
050 return null;
051 }
052
053 /**
054 * Returns the sound this mob makes on death.
055 */
056 protected String getDeathSound()
057 {
058 return null;
059 }
060
061 /**
062 * Returns the volume for the sounds this mob makes.
063 */
064 protected float getSoundVolume()
065 {
066 return 0.4F;
067 }
068
069 /**
070 * Returns the item ID for the item the mob drops on death.
071 */
072 protected int getDropItemId()
073 {
074 return 0;
075 }
076
077 /**
078 * Drop 0-2 items of this living's type
079 */
080 protected void dropFewItems(boolean par1, int par2)
081 {
082 int var3 = this.rand.nextInt(3 + par2) + 1;
083
084 for (int var4 = 0; var4 < var3; ++var4)
085 {
086 this.entityDropItem(new ItemStack(Item.dyePowder, 1, 0), 0.0F);
087 }
088 }
089
090 /**
091 * Checks if this entity is inside water (if inWater field is true as a result of handleWaterMovement() returning
092 * true)
093 */
094 public boolean isInWater()
095 {
096 return this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.6000000238418579D, 0.0D), Material.water, this);
097 }
098
099 /**
100 * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
101 * use this to react to sunlight and start to burn.
102 */
103 public void onLivingUpdate()
104 {
105 super.onLivingUpdate();
106 this.field_70862_e = this.field_70861_d;
107 this.field_70860_g = this.field_70859_f;
108 this.field_70868_i = this.field_70867_h;
109 this.lastTentacleAngle = this.tentacleAngle;
110 this.field_70867_h += this.field_70864_bA;
111
112 if (this.field_70867_h > ((float)Math.PI * 2F))
113 {
114 this.field_70867_h -= ((float)Math.PI * 2F);
115
116 if (this.rand.nextInt(10) == 0)
117 {
118 this.field_70864_bA = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F;
119 }
120 }
121
122 if (this.isInWater())
123 {
124 float var1;
125
126 if (this.field_70867_h < (float)Math.PI)
127 {
128 var1 = this.field_70867_h / (float)Math.PI;
129 this.tentacleAngle = MathHelper.sin(var1 * var1 * (float)Math.PI) * (float)Math.PI * 0.25F;
130
131 if ((double)var1 > 0.75D)
132 {
133 this.randomMotionSpeed = 1.0F;
134 this.field_70871_bB = 1.0F;
135 }
136 else
137 {
138 this.field_70871_bB *= 0.8F;
139 }
140 }
141 else
142 {
143 this.tentacleAngle = 0.0F;
144 this.randomMotionSpeed *= 0.9F;
145 this.field_70871_bB *= 0.99F;
146 }
147
148 if (!this.worldObj.isRemote)
149 {
150 this.motionX = (double)(this.randomMotionVecX * this.randomMotionSpeed);
151 this.motionY = (double)(this.randomMotionVecY * this.randomMotionSpeed);
152 this.motionZ = (double)(this.randomMotionVecZ * this.randomMotionSpeed);
153 }
154
155 var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
156 this.renderYawOffset += (-((float)Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float)Math.PI - this.renderYawOffset) * 0.1F;
157 this.rotationYaw = this.renderYawOffset;
158 this.field_70859_f += (float)Math.PI * this.field_70871_bB * 1.5F;
159 this.field_70861_d += (-((float)Math.atan2((double)var1, this.motionY)) * 180.0F / (float)Math.PI - this.field_70861_d) * 0.1F;
160 }
161 else
162 {
163 this.tentacleAngle = MathHelper.abs(MathHelper.sin(this.field_70867_h)) * (float)Math.PI * 0.25F;
164
165 if (!this.worldObj.isRemote)
166 {
167 this.motionX = 0.0D;
168 this.motionY -= 0.08D;
169 this.motionY *= 0.9800000190734863D;
170 this.motionZ = 0.0D;
171 }
172
173 this.field_70861_d = (float)((double)this.field_70861_d + (double)(-90.0F - this.field_70861_d) * 0.02D);
174 }
175 }
176
177 /**
178 * Moves the entity based on the specified heading. Args: strafe, forward
179 */
180 public void moveEntityWithHeading(float par1, float par2)
181 {
182 this.moveEntity(this.motionX, this.motionY, this.motionZ);
183 }
184
185 protected void updateEntityActionState()
186 {
187 ++this.entityAge;
188
189 if (this.entityAge > 100)
190 {
191 this.randomMotionVecX = this.randomMotionVecY = this.randomMotionVecZ = 0.0F;
192 }
193 else if (this.rand.nextInt(50) == 0 || !this.inWater || this.randomMotionVecX == 0.0F && this.randomMotionVecY == 0.0F && this.randomMotionVecZ == 0.0F)
194 {
195 float var1 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
196 this.randomMotionVecX = MathHelper.cos(var1) * 0.2F;
197 this.randomMotionVecY = -0.1F + this.rand.nextFloat() * 0.2F;
198 this.randomMotionVecZ = MathHelper.sin(var1) * 0.2F;
199 }
200
201 this.despawnEntity();
202 }
203
204 /**
205 * Checks if the entity's current position is a valid location to spawn this entity.
206 */
207 public boolean getCanSpawnHere()
208 {
209 return this.posY > 45.0D && this.posY < 63.0D && super.getCanSpawnHere();
210 }
211 }