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    }