    001package net.minecraft.entity.monster;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import net.minecraft.entity.Entity;
    006import net.minecraft.entity.player.EntityPlayer;
    007import net.minecraft.entity.projectile.EntitySmallFireball;
    008import net.minecraft.item.Item;
    009import net.minecraft.util.DamageSource;
    010import net.minecraft.util.MathHelper;
    011import net.minecraft.world.World;
    012
    013public class EntityBlaze extends EntityMob
    014{
    015    /** Random offset used in floating behaviour */
    016    private float heightOffset = 0.5F;
    017
    018    /** ticks until heightOffset is randomized */
    019    private int heightOffsetUpdateTime;
    020    private int field_70846_g;
    021
    022    public EntityBlaze(World par1World)
    023    {
    024        super(par1World);
    025        this.texture = "/mob/fire.png";
    026        this.isImmuneToFire = true;
    027        this.experienceValue = 10;
    028    }
    029
    030    public int getMaxHealth()
    031    {
    032        return 20;
    033    }
    034
    035    protected void entityInit()
    036    {
    037        super.entityInit();
    038        this.dataWatcher.addObject(16, new Byte((byte)0));
    039    }
    040
    041    /**
    042     * Returns the sound this mob makes while it's alive.
    043     */
    044    protected String getLivingSound()
    045    {
    046        return "mob.blaze.breathe";
    047    }
    048
    049    /**
    050     * Returns the sound this mob makes when it is hurt.
    051     */
    052    protected String getHurtSound()
    053    {
    054        return "mob.blaze.hit";
    055    }
    056
    057    /**
    058     * Returns the sound this mob makes on death.
    059     */
    060    protected String getDeathSound()
    061    {
    062        return "mob.blaze.death";
    063    }
    064
    065    @SideOnly(Side.CLIENT)
    066    public int getBrightnessForRender(float par1)
    067    {
    068        return 15728880;
    069    }
    070
    071    /**
    072     * Gets how bright this entity is.
    073     */
    074    public float getBrightness(float par1)
    075    {
    076        return 1.0F;
    077    }
    078
    079    /**
    080     * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    081     * use this to react to sunlight and start to burn.
    082     */
    083    public void onLivingUpdate()
    084    {
    085        if (!this.worldObj.isRemote)
    086        {
    087            if (this.isWet())
    088            {
    089                this.attackEntityFrom(DamageSource.drown, 1);
    090            }
    091
    092            --this.heightOffsetUpdateTime;
    093
    094            if (this.heightOffsetUpdateTime <= 0)
    095            {
    096                this.heightOffsetUpdateTime = 100;
    097                this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F;
    098            }
    099
    100            if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset)
    101            {
    102                this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D;
    103            }
    104        }
    105
    106        if (this.rand.nextInt(24) == 0)
    107        {
    108            this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F);
    109        }
    110
    111        if (!this.onGround && this.motionY < 0.0D)
    112        {
    113            this.motionY *= 0.6D;
    114        }
    115
    116        for (int i = 0; i < 2; ++i)
    117        {
    118            this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D);
    119        }
    120
    121        super.onLivingUpdate();
    122    }
    123
    124    /**
    125     * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack.
    126     */
    127    protected void attackEntity(Entity par1Entity, float par2)
    128    {
    129        if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY)
    130        {
    131            this.attackTime = 20;
    132            this.attackEntityAsMob(par1Entity);
    133        }
    134        else if (par2 < 30.0F)
    135        {
    136            double d0 = par1Entity.posX - this.posX;
    137            double d1 = par1Entity.boundingBox.minY + (double)(par1Entity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F));
    138            double d2 = par1Entity.posZ - this.posZ;
    139
    140            if (this.attackTime == 0)
    141            {
    142                ++this.field_70846_g;
    143
    144                if (this.field_70846_g == 1)
    145                {
    146                    this.attackTime = 60;
    147                    this.func_70844_e(true);
    148                }
    149                else if (this.field_70846_g <= 4)
    150                {
    151                    this.attackTime = 6;
    152                }
    153                else
    154                {
    155                    this.attackTime = 100;
    156                    this.field_70846_g = 0;
    157                    this.func_70844_e(false);
    158                }
    159
    160                if (this.field_70846_g > 1)
    161                {
    162                    float f1 = MathHelper.sqrt_float(par2) * 0.5F;
    163                    this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1009, (int)this.posX, (int)this.posY, (int)this.posZ, 0);
    164
    165                    for (int i = 0; i < 1; ++i)
    166                    {
    167                        EntitySmallFireball entitysmallfireball = new EntitySmallFireball(this.worldObj, this, d0 + this.rand.nextGaussian() * (double)f1, d1, d2 + this.rand.nextGaussian() * (double)f1);
    168                        entitysmallfireball.posY = this.posY + (double)(this.height / 2.0F) + 0.5D;
    169                        this.worldObj.spawnEntityInWorld(entitysmallfireball);
    170                    }
    171                }
    172            }
    173
    174            this.rotationYaw = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
    175            this.hasAttacked = true;
    176        }
    177    }
    178
    179    /**
    180     * Called when the mob is falling. Calculates and applies fall damage.
    181     */
    182    protected void fall(float par1) {}
    183
    184    /**
    185     * Returns the item ID for the item the mob drops on death.
    186     */
    187    protected int getDropItemId()
    188    {
    189        return Item.blazeRod.itemID;
    190    }
    191
    192    /**
    193     * Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
    194     */
    195    public boolean isBurning()
    196    {
    197        return this.func_70845_n();
    198    }
    199
    200    /**
    201     * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
    202     * par2 - Level of Looting used to kill this mob.
    203     */
    204    protected void dropFewItems(boolean par1, int par2)
    205    {
    206        if (par1)
    207        {
    208            int j = this.rand.nextInt(2 + par2);
    209
    210            for (int k = 0; k < j; ++k)
    211            {
    212                this.dropItem(Item.blazeRod.itemID, 1);
    213            }
    214        }
    215    }
    216
    217    public boolean func_70845_n()
    218    {
    219        return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
    220    }
    221
    222    public void func_70844_e(boolean par1)
    223    {
    224        byte b0 = this.dataWatcher.getWatchableObjectByte(16);
    225
    226        if (par1)
    227        {
    228            b0 = (byte)(b0 | 1);
    229        }
    230        else
    231        {
    232            b0 &= -2;
    233        }
    234
    235        this.dataWatcher.updateObject(16, Byte.valueOf(b0));
    236    }
    237
    238    /**
    239     * Checks to make sure the light is not too bright where the mob is spawning
    240     */
    241    protected boolean isValidLightLevel()
    242    {
    243        return true;
    244    }
    245
    246    /**
    247     * Returns the amount of damage a mob should deal.
    248     */
    249    public int getAttackStrength(Entity par1Entity)
    250    {
    251        return 6;
    252    }
    253}