    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 EntityIronGolem extends EntityGolem
    007    {
    008        /** deincrements, and a distance-to-home check is done at 0 */
    009        private int homeCheckTimer = 0;
    010        Village villageObj = null;
    011        private int attackTimer;
    012        private int holdRoseTick;
    013
    014        public EntityIronGolem(World par1World)
    015        {
    016            super(par1World);
    017            this.texture = "/mob/villager_golem.png";
    018            this.setSize(1.4F, 2.9F);
    019            this.getNavigator().setAvoidsWater(true);
    020            this.tasks.addTask(1, new EntityAIAttackOnCollide(this, 0.25F, true));
    021            this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.22F, 32.0F));
    022            this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.16F, true));
    023            this.tasks.addTask(4, new EntityAIMoveTwardsRestriction(this, 0.16F));
    024            this.tasks.addTask(5, new EntityAILookAtVillager(this));
    025            this.tasks.addTask(6, new EntityAIWander(this, 0.16F));
    026            this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
    027            this.tasks.addTask(8, new EntityAILookIdle(this));
    028            this.targetTasks.addTask(1, new EntityAIDefendVillage(this));
    029            this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false));
    030            this.targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityMob.class, 16.0F, 0, false, true));
    031        }
    032
    033        protected void entityInit()
    034        {
    035            super.entityInit();
    036            this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
    037        }
    038
    039        /**
    040         * Returns true if the newer Entity AI code should be run
    041         */
    042        public boolean isAIEnabled()
    043        {
    044            return true;
    045        }
    046
    047        /**
    048         * main AI tick function, replaces updateEntityActionState
    049         */
    050        protected void updateAITick()
    051        {
    052            if (--this.homeCheckTimer <= 0)
    053            {
    054                this.homeCheckTimer = 70 + this.rand.nextInt(50);
    055                this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 32);
    056
    057                if (this.villageObj == null)
    058                {
    059                    this.detachHome();
    060                }
    061                else
    062                {
    063                    ChunkCoordinates var1 = this.villageObj.getCenter();
    064                    this.setHomeArea(var1.posX, var1.posY, var1.posZ, this.villageObj.getVillageRadius());
    065                }
    066            }
    067
    068            super.updateAITick();
    069        }
    070
    071        public int getMaxHealth()
    072        {
    073            return 100;
    074        }
    075
    076        /**
    077         * Decrements the entity's air supply when underwater
    078         */
    079        protected int decreaseAirSupply(int par1)
    080        {
    081            return par1;
    082        }
    083
    084        /**
    085         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    086         * use this to react to sunlight and start to burn.
    087         */
    088        public void onLivingUpdate()
    089        {
    090            super.onLivingUpdate();
    091
    092            if (this.attackTimer > 0)
    093            {
    094                --this.attackTimer;
    095            }
    096
    097            if (this.holdRoseTick > 0)
    098            {
    099                --this.holdRoseTick;
    100            }
    101
    102            if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D && this.rand.nextInt(5) == 0)
    103            {
    104                int var1 = MathHelper.floor_double(this.posX);
    105                int var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
    106                int var3 = MathHelper.floor_double(this.posZ);
    107                int var4 = this.worldObj.getBlockId(var1, var2, var3);
    108
    109                if (var4 > 0)
    110                {
    111                    this.worldObj.spawnParticle("tilecrack_" + var4, this.posX + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, this.boundingBox.minY + 0.1D, this.posZ + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, 4.0D * ((double)this.rand.nextFloat() - 0.5D), 0.5D, ((double)this.rand.nextFloat() - 0.5D) * 4.0D);
    112                }
    113            }
    114        }
    115
    116        public boolean isExplosiveMob(Class par1Class)
    117        {
    118            return this.getBit1Flag() && EntityPlayer.class.isAssignableFrom(par1Class) ? false : super.isExplosiveMob(par1Class);
    119        }
    120
    121        public boolean attackEntityAsMob(Entity par1Entity)
    122        {
    123            this.attackTimer = 10;
    124            this.worldObj.setEntityState(this, (byte)4);
    125            boolean var2 = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), 7 + this.rand.nextInt(15));
    126
    127            if (var2)
    128            {
    129                par1Entity.motionY += 0.4000000059604645D;
    130            }
    131
    132            this.worldObj.playSoundAtEntity(this, "mob.irongolem.throw", 1.0F, 1.0F);
    133            return var2;
    134        }
    135
    136        @SideOnly(Side.CLIENT)
    137        public void handleHealthUpdate(byte par1)
    138        {
    139            if (par1 == 4)
    140            {
    141                this.attackTimer = 10;
    142                this.worldObj.playSoundAtEntity(this, "mob.irongolem.throw", 1.0F, 1.0F);
    143            }
    144            else if (par1 == 11)
    145            {
    146                this.holdRoseTick = 400;
    147            }
    148            else
    149            {
    150                super.handleHealthUpdate(par1);
    151            }
    152        }
    153
    154        public Village getVillage()
    155        {
    156            return this.villageObj;
    157        }
    158
    159        @SideOnly(Side.CLIENT)
    160        public int getAttackTimer()
    161        {
    162            return this.attackTimer;
    163        }
    164
    165        public void setHoldingRose(boolean par1)
    166        {
    167            this.holdRoseTick = par1 ? 400 : 0;
    168            this.worldObj.setEntityState(this, (byte)11);
    169        }
    170
    171        /**
    172         * Returns the sound this mob makes while it's alive.
    173         */
    174        protected String getLivingSound()
    175        {
    176            return "none";
    177        }
    178
    179        /**
    180         * Returns the sound this mob makes when it is hurt.
    181         */
    182        protected String getHurtSound()
    183        {
    184            return "mob.irongolem.hit";
    185        }
    186
    187        /**
    188         * Returns the sound this mob makes on death.
    189         */
    190        protected String getDeathSound()
    191        {
    192            return "mob.irongolem.death";
    193        }
    194
    195        /**
    196         * Plays step sound at given x, y, z for the entity
    197         */
    198        protected void playStepSound(int par1, int par2, int par3, int par4)
    199        {
    200            this.worldObj.playSoundAtEntity(this, "mob.irongolem.walk", 1.0F, 1.0F);
    201        }
    202
    203        /**
    204         * Drop 0-2 items of this living's type
    205         */
    206        protected void dropFewItems(boolean par1, int par2)
    207        {
    208            int var3 = this.rand.nextInt(3);
    209            int var4;
    210
    211            for (var4 = 0; var4 < var3; ++var4)
    212            {
    213                this.dropItem(Block.plantRed.blockID, 1);
    214            }
    215
    216            var4 = 3 + this.rand.nextInt(3);
    217
    218            for (int var5 = 0; var5 < var4; ++var5)
    219            {
    220                this.dropItem(Item.ingotIron.shiftedIndex, 1);
    221            }
    222        }
    223
    224        public int getHoldRoseTick()
    225        {
    226            return this.holdRoseTick;
    227        }
    228
    229        public boolean getBit1Flag()
    230        {
    231            return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
    232        }
    233
    234        public void setBit1FlagTo(boolean par1)
    235        {
    236            byte var2 = this.dataWatcher.getWatchableObjectByte(16);
    237
    238            if (par1)
    239            {
    240                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 1)));
    241            }
    242            else
    243            {
    244                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -2)));
    245            }
    246        }
    247    }