001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    
006    public class EntityCreeper extends EntityMob
007    {
008        /**
009         * The amount of time since the creeper was close enough to the player to ignite
010         */
011        int timeSinceIgnited;
012    
013        /**
014         * Time when this creeper was last in an active state (Messed up code here, probably causes creeper animation to go
015         * weird)
016         */
017        int lastActiveTime;
018    
019        public EntityCreeper(World par1World)
020        {
021            super(par1World);
022            this.texture = "/mob/creeper.png";
023            this.tasks.addTask(1, new EntityAISwimming(this));
024            this.tasks.addTask(2, new EntityAICreeperSwell(this));
025            this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityOcelot.class, 6.0F, 0.25F, 0.3F));
026            this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 0.25F, false));
027            this.tasks.addTask(5, new EntityAIWander(this, 0.2F));
028            this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
029            this.tasks.addTask(6, new EntityAILookIdle(this));
030            this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true));
031            this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false));
032        }
033    
034        /**
035         * Returns true if the newer Entity AI code should be run
036         */
037        public boolean isAIEnabled()
038        {
039            return true;
040        }
041    
042        public int getMaxHealth()
043        {
044            return 20;
045        }
046    
047        protected void entityInit()
048        {
049            super.entityInit();
050            this.dataWatcher.addObject(16, Byte.valueOf((byte) - 1));
051            this.dataWatcher.addObject(17, Byte.valueOf((byte)0));
052        }
053    
054        /**
055         * (abstract) Protected helper method to write subclass entity data to NBT.
056         */
057        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
058        {
059            super.writeEntityToNBT(par1NBTTagCompound);
060    
061            if (this.dataWatcher.getWatchableObjectByte(17) == 1)
062            {
063                par1NBTTagCompound.setBoolean("powered", true);
064            }
065        }
066    
067        /**
068         * (abstract) Protected helper method to read subclass entity data from NBT.
069         */
070        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
071        {
072            super.readEntityFromNBT(par1NBTTagCompound);
073            this.dataWatcher.updateObject(17, Byte.valueOf((byte)(par1NBTTagCompound.getBoolean("powered") ? 1 : 0)));
074        }
075    
076        /**
077         * Called to update the entity's position/logic.
078         */
079        public void onUpdate()
080        {
081            if (this.isEntityAlive())
082            {
083                this.lastActiveTime = this.timeSinceIgnited;
084                int var1 = this.getCreeperState();
085    
086                if (var1 > 0 && this.timeSinceIgnited == 0)
087                {
088                    this.worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 0.5F);
089                }
090    
091                this.timeSinceIgnited += var1;
092    
093                if (this.timeSinceIgnited < 0)
094                {
095                    this.timeSinceIgnited = 0;
096                }
097    
098                if (this.timeSinceIgnited >= 30)
099                {
100                    this.timeSinceIgnited = 30;
101    
102                    if (!this.worldObj.isRemote)
103                    {
104                        if (this.getPowered())
105                        {
106                            this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 6.0F);
107                        }
108                        else
109                        {
110                            this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 3.0F);
111                        }
112    
113                        this.setDead();
114                    }
115                }
116            }
117    
118            super.onUpdate();
119        }
120    
121        /**
122         * Returns the sound this mob makes when it is hurt.
123         */
124        protected String getHurtSound()
125        {
126            return "mob.creeper";
127        }
128    
129        /**
130         * Returns the sound this mob makes on death.
131         */
132        protected String getDeathSound()
133        {
134            return "mob.creeperdeath";
135        }
136    
137        /**
138         * Called when the mob's health reaches 0.
139         */
140        public void onDeath(DamageSource par1DamageSource)
141        {
142            super.onDeath(par1DamageSource);
143    
144            if (par1DamageSource.getEntity() instanceof EntitySkeleton)
145            {
146                this.dropItem(Item.record13.shiftedIndex + this.rand.nextInt(10), 1);
147            }
148        }
149    
150        public boolean attackEntityAsMob(Entity par1Entity)
151        {
152            return true;
153        }
154    
155        /**
156         * Returns true if the creeper is powered by a lightning bolt.
157         */
158        public boolean getPowered()
159        {
160            return this.dataWatcher.getWatchableObjectByte(17) == 1;
161        }
162    
163        @SideOnly(Side.CLIENT)
164    
165        /**
166         * Connects the the creeper flashes to the creeper's color multiplier
167         */
168        public float setCreeperFlashTime(float par1)
169        {
170            return ((float)this.lastActiveTime + (float)(this.timeSinceIgnited - this.lastActiveTime) * par1) / 28.0F;
171        }
172    
173        /**
174         * Returns the item ID for the item the mob drops on death.
175         */
176        protected int getDropItemId()
177        {
178            return Item.gunpowder.shiftedIndex;
179        }
180    
181        /**
182         * Returns the current state of creeper, -1 is idle, 1 is 'in fuse'
183         */
184        public int getCreeperState()
185        {
186            return this.dataWatcher.getWatchableObjectByte(16);
187        }
188    
189        /**
190         * Sets the state of creeper, -1 to idle and 1 to be 'in fuse'
191         */
192        public void setCreeperState(int par1)
193        {
194            this.dataWatcher.updateObject(16, Byte.valueOf((byte)par1));
195        }
196    
197        /**
198         * Called when a lightning bolt hits the entity.
199         */
200        public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt)
201        {
202            super.onStruckByLightning(par1EntityLightningBolt);
203            this.dataWatcher.updateObject(17, Byte.valueOf((byte)1));
204        }
205    }