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