Program: 34646
Project: 34646
Buggy source:
@Override protected void updateEntityActionState(){
  EntityPlayer closest=worldObj.getClosestPlayerToEntity(this,164D);
  if (closest == null)   return;
  rotationYaw=MathUtil.toDeg((float)Math.atan2(posZ - closest.posZ,posX - closest.posX)) + 90F;
  rotationPitch=MathUtil.toDeg((float)Math.atan2(posY - (closest.posY + closest.getEyeHeight()),MathUtil.distance(posX - closest.posX,posZ - closest.posZ)));
  double targetYDiff=posY - (closest.posY + 9D);
  BlockPosM tmpPos=BlockPosM.tmp(this);
  for (int a=1; a <= 7; a+=2) {
    if (!tmpPos.moveDown().moveDown().isAir(worldObj)) {
      targetYDiff=-1.5D;
      break;
    }
  }
  if (Math.abs(targetYDiff) > 1D)   motionY-=Math.abs(targetYDiff) * 0.0045D * Math.signum(targetYDiff);
  if (ticksExisted == 1)   targetAngleChangeDir=rand.nextBoolean();
 else   if (rand.nextInt(195) == 0 || (targetAngleTimer > 122 || (targetAngleTimer+=rand.nextInt(2)) > 122)) {
    targetAngleChangeDir=!targetAngleChangeDir;
    targetAngleTimer=0;
  }
  targetAngle+=(targetAngleChangeDir ? 1 : -1) * 0.02F;
  double[] vec=DragonUtil.getNormalizedVector((closest.posX + MathHelper.cos(targetAngle) * 40D) - posX + (rand.nextDouble() - 0.5D) * 4D,(closest.posZ + MathHelper.sin(targetAngle) * 40D) - posZ + (rand.nextDouble() - 0.5D) * 4D);
  motionVec.xCoord=vec[0] * 0.5D;
  motionVec.zCoord=vec[1] * 0.5D;
  motionX=motionVec.xCoord * 0.1D + motionX * 0.9D;
  motionZ=motionVec.zCoord * 0.1D + motionZ * 0.9D;
  if (currentAttack == ATTACK_NONE) {
    if (++timer > 125 - worldObj.difficultySetting.getDifficultyId() * 7 - (isAngry ? 18 : 0) - (ModCommonProxy.opMobs ? 12 : 0)) {
      boolean hasCalledGolems=false;
      if (isAngry && worldObj.difficultySetting != EnumDifficulty.PEACEFUL && rand.nextInt(5) == 0) {
        for (        EntityPlayer player : getNearbyPlayers()) {
          int targeted=0;
          List<EntityMobFireGolem> golems=worldObj.getEntitiesWithinAABB(EntityMobFireGolem.class,player.boundingBox.expand(32D,32D,32D));
          for (          EntityMobFireGolem golem : golems) {
            if (golem.getEntityToAttack() == player && ++targeted >= 2)             break;
          }
          if (targeted >= 2)           continue;
          golems=worldObj.getEntitiesWithinAABB(EntityMobFireGolem.class,player.boundingBox.expand(16D,16D,16D));
          if (golems.isEmpty())           continue;
          for (int attempt=0, called=ModCommonProxy.opMobs ? 3 : 2; attempt < 3 && !golems.isEmpty() && called > 0; attempt++) {
            EntityMobFireGolem golem=golems.remove(rand.nextInt(golems.size()));
            if (player.getDistanceToEntity(golem) <= 16D) {
              golem.setTarget(player);
              PacketPipeline.sendToAllAround(this,128D,new C22EffectLine(FXType.Line.FIRE_FIEND_GOLEM_CALL,this,golem));
              called-=rand.nextInt(2) + 1;
            }
          }
        }
        timer>>=1;
      }
      if (!hasCalledGolems) {
        currentAttack=rand.nextInt(3) != 0 ? ATTACK_FIREBALLS : ATTACK_FLAMES;
        if (currentAttack == ATTACK_FLAMES && prevAttack == ATTACK_FLAMES)         currentAttack=ATTACK_FIREBALLS;
        dataWatcher.updateObject(16,currentAttack);
        prevAttack=currentAttack;
        timer=0;
      }
    }
  }
 else   if (currentAttack == ATTACK_FIREBALLS) {
    int amt=ModCommonProxy.opMobs ? 8 : 6, speed=isAngry ? 8 : 12;
    if (++timer == 1) {
      double ang=360D / amt;
      for (int a=0; a < amt; a++) {
        controlledFireballs.add(new EntityProjectileFiendFireball(worldObj,this,posX,posY + height * 0.5F,posZ,-a * ang,speed * (a + 2)));
        worldObj.spawnEntityInWorld(controlledFireballs.get(a));
      }
    }
 else     if (timer >= (amt + 2) * speed) {
      dataWatcher.updateObject(16,currentAttack=ATTACK_NONE);
      timer=0;
      controlledFireballs.clear();
    }
 else     if (timer >= 2) {
      for (      EntityProjectileFiendFireball fireball : controlledFireballs) {
        if (fireball.timer > 1)         fireball.updateCenter(this);
 else         if (fireball.timer == 1) {
          List<EntityPlayer> players=getNearbyPlayers();
          fireball.shootAt(players.isEmpty() ? null : players.get(rand.nextInt(players.size())));
        }
      }
    }
  }
 else   if (currentAttack == ATTACK_FLAMES) {
    if (++timer > (isAngry ? 18 : 26)) {
      int fireLength=3 + (worldObj.difficultySetting.getDifficultyId() >> 1);
      for (      EntityPlayer player : getNearbyPlayers()) {
        player.setFire(fireLength);
        player.attackEntityFrom(new DamageSourceMobUnscaled(this),DamageSourceMobUnscaled.getDamage(ModCommonProxy.opMobs ? 12F : 8F,worldObj.difficultySetting));
        PacketPipeline.sendToAllAround(player,64D,new C20Effect(FXType.Basic.FIRE_FIEND_FLAME_ATTACK,player));
      }
      timer=0;
      dataWatcher.updateObject(16,currentAttack=ATTACK_NONE);
    }
  }
  for (  EntityLivingBase e : (List<EntityLivingBase>)worldObj.getEntitiesWithinAABB(EntityLivingBase.class,boundingBox.expand(0.8D,1.65D,0.8D))) {
    if (e == this || e.isImmuneToFire())     continue;
    e.setFire(2 + rand.nextInt(4));
    e.hurtResistantTime=0;
    e.attackEntityFrom(new DamageSourceMobUnscaled(this),ModCommonProxy.opMobs ? 9F : 5F);
    e.hurtResistantTime=7;
  }
  moveForward*=0.6F;
  wingAnimationStep=1F;
  if (Math.abs(moveForward) > 0.01D)   wingAnimationStep+=1F;
  if (motionY > 0.001D)   wingAnimationStep+=1.5F;
 else   if (motionY < 0.001D)   wingAnimationStep-=0.75F;
  wingAnimation+=wingAnimationStep * 0.01F;
}

Fixed version (ground truth):
@Override protected void updateEntityActionState(){
  EntityPlayer closest=worldObj.getClosestPlayerToEntity(this,164D);
  if (closest == null)   return;
  rotationYaw=MathUtil.toDeg((float)Math.atan2(posZ - closest.posZ,posX - closest.posX)) + 90F;
  rotationPitch=MathUtil.toDeg((float)Math.atan2(posY - (closest.posY + closest.getEyeHeight()),MathUtil.distance(posX - closest.posX,posZ - closest.posZ)));
  double targetYDiff=posY - (closest.posY + 9D);
  BlockPosM tmpPos=BlockPosM.tmp(this);
  for (int a=1; a <= 7; a+=2) {
    if (!tmpPos.moveDown().moveDown().isAir(worldObj)) {
      targetYDiff=-1.5D;
      break;
    }
  }
  if (Math.abs(targetYDiff) > 1D)   motionY-=Math.abs(targetYDiff) * 0.0045D * Math.signum(targetYDiff);
  if (ticksExisted == 1)   targetAngleChangeDir=rand.nextBoolean();
 else   if (rand.nextInt(195) == 0 || (targetAngleTimer > 122 || (targetAngleTimer+=rand.nextInt(2)) > 122)) {
    targetAngleChangeDir=!targetAngleChangeDir;
    targetAngleTimer=0;
  }
  targetAngle+=(targetAngleChangeDir ? 1 : -1) * 0.02F;
  double[] vec=DragonUtil.getNormalizedVector((closest.posX + MathHelper.cos(targetAngle) * 40D) - posX + (rand.nextDouble() - 0.5D) * 4D,(closest.posZ + MathHelper.sin(targetAngle) * 40D) - posZ + (rand.nextDouble() - 0.5D) * 4D);
  motionVec.xCoord=vec[0] * 0.5D;
  motionVec.zCoord=vec[1] * 0.5D;
  motionX=motionVec.xCoord * 0.1D + motionX * 0.9D;
  motionZ=motionVec.zCoord * 0.1D + motionZ * 0.9D;
  if (currentAttack == ATTACK_NONE) {
    if (++timer > 125 - worldObj.difficultySetting.getDifficultyId() * 7 - (isAngry ? 18 : 0) - (ModCommonProxy.opMobs ? 12 : 0)) {
      boolean hasCalledGolems=false;
      if (isAngry && worldObj.difficultySetting != EnumDifficulty.PEACEFUL && rand.nextInt(5) == 0) {
        for (        EntityPlayer player : getNearbyPlayers()) {
          int targeted=0;
          List<EntityMobFireGolem> golems=worldObj.getEntitiesWithinAABB(EntityMobFireGolem.class,player.boundingBox.expand(32D,32D,32D));
          for (          EntityMobFireGolem golem : golems) {
            if (golem.getEntityToAttack() == player && ++targeted >= 2)             break;
          }
          if (targeted >= 2)           continue;
          golems=worldObj.getEntitiesWithinAABB(EntityMobFireGolem.class,player.boundingBox.expand(16D,16D,16D));
          if (golems.isEmpty())           continue;
          for (int attempt=0, called=ModCommonProxy.opMobs ? 3 : 2; attempt < 3 && !golems.isEmpty() && called > 0; attempt++) {
            EntityMobFireGolem golem=golems.remove(rand.nextInt(golems.size()));
            if (player.getDistanceToEntity(golem) <= 16D) {
              golem.setTarget(player);
              PacketPipeline.sendToAllAround(this,128D,new C22EffectLine(FXType.Line.FIRE_FIEND_GOLEM_CALL,this,golem));
              called-=rand.nextInt(2) + 1;
            }
          }
        }
        timer>>=1;
      }
      if (!hasCalledGolems) {
        currentAttack=rand.nextInt(3) != 0 ? ATTACK_FIREBALLS : ATTACK_FLAMES;
        if (currentAttack == ATTACK_FLAMES && prevAttack == ATTACK_FLAMES)         currentAttack=ATTACK_FIREBALLS;
        dataWatcher.updateObject(16,currentAttack);
        prevAttack=currentAttack;
        timer=0;
      }
    }
  }
 else   if (currentAttack == ATTACK_FIREBALLS) {
    int amt=ModCommonProxy.opMobs ? 8 : 6, speed=isAngry ? 8 : 12;
    if (++timer == 1) {
      double ang=360D / amt;
      for (int a=0; a < amt; a++) {
        controlledFireballs.add(new EntityProjectileFiendFireball(worldObj,this,posX,posY + height * 0.5F,posZ,-a * ang,speed * (a + 2)));
        worldObj.spawnEntityInWorld(controlledFireballs.get(a));
      }
    }
 else     if (timer >= (amt + 2) * speed) {
      dataWatcher.updateObject(16,currentAttack=ATTACK_NONE);
      timer=0;
      controlledFireballs.clear();
    }
 else     if (timer >= 2) {
      for (      EntityProjectileFiendFireball fireball : controlledFireballs) {
        if (fireball.timer > 1)         fireball.updateCenter(this);
 else         if (fireball.timer == 1)         fireball.shootAt(CollectionUtil.randomOrNull(getNearbyPlayers(),rand));
      }
    }
  }
 else   if (currentAttack == ATTACK_FLAMES) {
    if (++timer > (isAngry ? 18 : 26)) {
      int fireLength=3 + (worldObj.difficultySetting.getDifficultyId() >> 1);
      for (      EntityPlayer player : getNearbyPlayers()) {
        player.setFire(fireLength);
        player.attackEntityFrom(new DamageSourceMobUnscaled(this),DamageSourceMobUnscaled.getDamage(ModCommonProxy.opMobs ? 12F : 8F,worldObj.difficultySetting));
        PacketPipeline.sendToAllAround(player,64D,new C20Effect(FXType.Basic.FIRE_FIEND_FLAME_ATTACK,player));
      }
      timer=0;
      dataWatcher.updateObject(16,currentAttack=ATTACK_NONE);
    }
  }
  for (  EntityLivingBase e : (List<EntityLivingBase>)worldObj.getEntitiesWithinAABB(EntityLivingBase.class,boundingBox.expand(0.8D,1.65D,0.8D))) {
    if (e == this || e.isImmuneToFire())     continue;
    e.setFire(2 + rand.nextInt(4));
    e.hurtResistantTime=0;
    e.attackEntityFrom(new DamageSourceMobUnscaled(this),ModCommonProxy.opMobs ? 9F : 5F);
    e.hurtResistantTime=7;
  }
  moveForward*=0.6F;
  wingAnimationStep=1F;
  if (Math.abs(moveForward) > 0.01D)   wingAnimationStep+=1F;
  if (motionY > 0.001D)   wingAnimationStep+=1.5F;
 else   if (motionY < 0.001D)   wingAnimationStep-=0.75F;
  wingAnimation+=wingAnimationStep * 0.01F;
}