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 }