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