001 package net.minecraft.src; 002 003 public class EntityBat extends EntityAmbientCreature 004 { 005 private ChunkCoordinates field_82237_a; 006 007 public EntityBat(World par1World) 008 { 009 super(par1World); 010 this.texture = "/mob/bat.png"; 011 this.setSize(0.5F, 0.9F); 012 this.func_82236_f(true); 013 } 014 015 protected void entityInit() 016 { 017 super.entityInit(); 018 this.dataWatcher.addObject(16, new Byte((byte)0)); 019 } 020 021 /** 022 * Returns the volume for the sounds this mob makes. 023 */ 024 protected float getSoundVolume() 025 { 026 return 0.1F; 027 } 028 029 /** 030 * Returns the sound this mob makes while it's alive. 031 */ 032 protected String getLivingSound() 033 { 034 return "mob.bat.idle"; 035 } 036 037 /** 038 * Returns the sound this mob makes when it is hurt. 039 */ 040 protected String getHurtSound() 041 { 042 return "mob.bat.hurt"; 043 } 044 045 /** 046 * Returns the sound this mob makes on death. 047 */ 048 protected String getDeathSound() 049 { 050 return "mob.bat.death"; 051 } 052 053 public int getMaxHealth() 054 { 055 return 6; 056 } 057 058 public boolean func_82235_h() 059 { 060 return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; 061 } 062 063 public void func_82236_f(boolean par1) 064 { 065 byte var2 = this.dataWatcher.getWatchableObjectByte(16); 066 067 if (par1) 068 { 069 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 1))); 070 } 071 else 072 { 073 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -2))); 074 } 075 } 076 077 /** 078 * Returns true if the newer Entity AI code should be run 079 */ 080 protected boolean isAIEnabled() 081 { 082 return true; 083 } 084 085 /** 086 * Called to update the entity's position/logic. 087 */ 088 public void onUpdate() 089 { 090 super.onUpdate(); 091 092 if (this.func_82235_h()) 093 { 094 this.motionX = this.motionY = this.motionZ = 0.0D; 095 this.posY = (double)MathHelper.floor_double(this.posY) + 1.0D - (double)this.height; 096 } 097 else 098 { 099 this.motionY *= 0.6000000238418579D; 100 } 101 } 102 103 protected void updateAITasks() 104 { 105 super.updateAITasks(); 106 107 if (this.func_82235_h()) 108 { 109 if (!this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int)this.posY + 1, MathHelper.floor_double(this.posZ))) 110 { 111 this.func_82236_f(false); 112 this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1015, (int)this.posX, (int)this.posY, (int)this.posZ, 0); 113 } 114 else 115 { 116 if (this.rand.nextInt(200) == 0) 117 { 118 this.rotationYawHead = (float)this.rand.nextInt(360); 119 } 120 121 if (this.worldObj.getClosestPlayerToEntity(this, 4.0D) != null) 122 { 123 this.func_82236_f(false); 124 this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1015, (int)this.posX, (int)this.posY, (int)this.posZ, 0); 125 } 126 } 127 } 128 else 129 { 130 if (this.field_82237_a != null && (!this.worldObj.isAirBlock(this.field_82237_a.posX, this.field_82237_a.posY, this.field_82237_a.posZ) || this.field_82237_a.posY < 1)) 131 { 132 this.field_82237_a = null; 133 } 134 135 if (this.field_82237_a == null || this.rand.nextInt(30) == 0 || this.field_82237_a.getDistanceSquared((int)this.posX, (int)this.posY, (int)this.posZ) < 4.0F) 136 { 137 this.field_82237_a = new ChunkCoordinates((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(6) - 2, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); 138 } 139 140 double var1 = (double)this.field_82237_a.posX + 0.5D - this.posX; 141 double var3 = (double)this.field_82237_a.posY + 0.1D - this.posY; 142 double var5 = (double)this.field_82237_a.posZ + 0.5D - this.posZ; 143 this.motionX += (Math.signum(var1) * 0.5D - this.motionX) * 0.10000000149011612D; 144 this.motionY += (Math.signum(var3) * 0.699999988079071D - this.motionY) * 0.10000000149011612D; 145 this.motionZ += (Math.signum(var5) * 0.5D - this.motionZ) * 0.10000000149011612D; 146 float var7 = (float)(Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F; 147 float var8 = MathHelper.wrapAngleTo180_float(var7 - this.rotationYaw); 148 this.moveForward = 0.5F; 149 this.rotationYaw += var8; 150 151 if (this.rand.nextInt(100) == 0 && this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int)this.posY + 1, MathHelper.floor_double(this.posZ))) 152 { 153 this.func_82236_f(true); 154 } 155 } 156 } 157 158 /** 159 * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to 160 * prevent them from trampling crops 161 */ 162 protected boolean canTriggerWalking() 163 { 164 return false; 165 } 166 167 /** 168 * Called when the mob is falling. Calculates and applies fall damage. 169 */ 170 protected void fall(float par1) {} 171 172 /** 173 * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance 174 * and deal fall damage if landing on the ground. Args: distanceFallenThisTick, onGround 175 */ 176 protected void updateFallState(double par1, boolean par3) {} 177 178 public boolean func_82144_au() 179 { 180 return true; 181 } 182 183 /** 184 * Called when the entity is attacked. 185 */ 186 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 187 { 188 if (!this.worldObj.isRemote && this.func_82235_h()) 189 { 190 this.func_82236_f(false); 191 } 192 193 return super.attackEntityFrom(par1DamageSource, par2); 194 } 195 196 /** 197 * (abstract) Protected helper method to read subclass entity data from NBT. 198 */ 199 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 200 { 201 super.readEntityFromNBT(par1NBTTagCompound); 202 this.dataWatcher.updateObject(16, Byte.valueOf(par1NBTTagCompound.getByte("BatFlags"))); 203 } 204 205 /** 206 * (abstract) Protected helper method to write subclass entity data to NBT. 207 */ 208 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 209 { 210 super.writeEntityToNBT(par1NBTTagCompound); 211 par1NBTTagCompound.setByte("BatFlags", this.dataWatcher.getWatchableObjectByte(16)); 212 } 213 214 /** 215 * Checks if the entity's current position is a valid location to spawn this entity. 216 */ 217 public boolean getCanSpawnHere() 218 { 219 int var1 = MathHelper.floor_double(this.boundingBox.minY); 220 221 if (var1 >= 63) 222 { 223 return false; 224 } 225 else 226 { 227 int var2 = MathHelper.floor_double(this.posX); 228 int var3 = MathHelper.floor_double(this.posZ); 229 int var4 = this.worldObj.getBlockLightValue(var2, var1, var3); 230 return var4 > this.rand.nextInt(7) ? false : super.getCanSpawnHere(); 231 } 232 } 233 234 public void func_82163_bD() {} 235 }