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 }