/** Called when the entity is attacked. */
  public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) {
    if (worldObj.isRemote || isDead) {
      return true;
    }

    func_41016_d(-func_41021_q());
    func_41014_b(10);
    setBeenAttacked();
    func_41018_e_(func_41020_o() + par2 * 10);

    if (func_41020_o() > 40) {
      if (riddenByEntity != null) {
        riddenByEntity.mountEntity(this);
      }

      setEntityDead();
      dropItemWithOffset(Item.minecartEmpty.shiftedIndex, 1, 0.0F);

      if (minecartType == 1) {
        EntityMinecart entityminecart = this;
        label0:
        for (int i = 0; i < entityminecart.getSizeInventory(); i++) {
          ItemStack itemstack = entityminecart.getStackInSlot(i);

          if (itemstack == null) {
            continue;
          }

          float f = rand.nextFloat() * 0.8F + 0.1F;
          float f1 = rand.nextFloat() * 0.8F + 0.1F;
          float f2 = rand.nextFloat() * 0.8F + 0.1F;

          do {
            if (itemstack.stackSize <= 0) {
              continue label0;
            }

            int j = rand.nextInt(21) + 10;

            if (j > itemstack.stackSize) {
              j = itemstack.stackSize;
            }

            itemstack.stackSize -= j;
            EntityItem entityitem =
                new EntityItem(
                    worldObj,
                    posX + (double) f,
                    posY + (double) f1,
                    posZ + (double) f2,
                    new ItemStack(itemstack.itemID, j, itemstack.getItemDamage()));
            float f3 = 0.05F;
            entityitem.motionX = (float) rand.nextGaussian() * f3;
            entityitem.motionY = (float) rand.nextGaussian() * f3 + 0.2F;
            entityitem.motionZ = (float) rand.nextGaussian() * f3;
            worldObj.spawnEntityInWorld(entityitem);
          } while (true);
        }

        dropItemWithOffset(Block.chest.blockID, 1, 0.0F);
      } else if (minecartType == 2) {
        dropItemWithOffset(Block.stoneOvenIdle.blockID, 1, 0.0F);
      }
    }

    return true;
  }
  /** Called to update the entity's position/logic. */
  public void onUpdate() {
    if (func_41019_p() > 0) {
      func_41014_b(func_41019_p() - 1);
    }

    if (func_41020_o() > 0) {
      func_41018_e_(func_41020_o() - 1);
    }

    if (isMinecartPowered() && rand.nextInt(4) == 0) {
      worldObj.spawnParticle("largesmoke", posX, posY + 0.8D, posZ, 0.0D, 0.0D, 0.0D);
    }

    if (worldObj.isRemote) {
      if (turnProgress > 0) {
        double d = posX + (minecartX - posX) / (double) turnProgress;
        double d1 = posY + (minecartY - posY) / (double) turnProgress;
        double d3 = posZ + (minecartZ - posZ) / (double) turnProgress;
        double d5;

        for (d5 = minecartYaw - (double) rotationYaw; d5 < -180D; d5 += 360D) {}

        for (; d5 >= 180D; d5 -= 360D) {}

        rotationYaw += d5 / (double) turnProgress;
        rotationPitch += (minecartPitch - (double) rotationPitch) / (double) turnProgress;
        turnProgress--;
        setPosition(d, d1, d3);
        setRotation(rotationYaw, rotationPitch);
      } else {
        setPosition(posX, posY, posZ);
        setRotation(rotationYaw, rotationPitch);
      }

      return;
    }

    prevPosX = posX;
    prevPosY = posY;
    prevPosZ = posZ;
    motionY -= 0.04D;
    int i = MathHelper.floor_double(posX);
    int j = MathHelper.floor_double(posY);
    int k = MathHelper.floor_double(posZ);

    if (BlockRail.isRailBlockAt(worldObj, i, j - 1, k)) {
      j--;
    }

    double d2 = 0.4D;
    double d4 = 0.0078125D;
    int l = worldObj.getBlockId(i, j, k);

    if (BlockRail.isRailBlock(l)) {
      Vec3D vec3d = func_182_g(posX, posY, posZ);
      int i1 = worldObj.getBlockMetadata(i, j, k);
      posY = j;
      boolean flag = false;
      boolean flag1 = false;

      if (l == Block.railPowered.blockID) {
        flag = (i1 & 8) != 0;
        flag1 = !flag;
      }

      if (((BlockRail) Block.blocksList[l]).isPowered()) {
        i1 &= 7;
      }

      if (i1 >= 2 && i1 <= 5) {
        posY = j + 1;
      }

      if (i1 == 2) {
        motionX -= d4;
      }

      if (i1 == 3) {
        motionX += d4;
      }

      if (i1 == 4) {
        motionZ += d4;
      }

      if (i1 == 5) {
        motionZ -= d4;
      }

      int ai[][] = field_468_ak[i1];
      double d9 = ai[1][0] - ai[0][0];
      double d10 = ai[1][2] - ai[0][2];
      double d11 = Math.sqrt(d9 * d9 + d10 * d10);
      double d12 = motionX * d9 + motionZ * d10;

      if (d12 < 0.0D) {
        d9 = -d9;
        d10 = -d10;
      }

      double d13 = Math.sqrt(motionX * motionX + motionZ * motionZ);
      motionX = (d13 * d9) / d11;
      motionZ = (d13 * d10) / d11;

      if (flag1) {
        double d16 = Math.sqrt(motionX * motionX + motionZ * motionZ);

        if (d16 < 0.03D) {
          motionX *= 0.0D;
          motionY *= 0.0D;
          motionZ *= 0.0D;
        } else {
          motionX *= 0.5D;
          motionY *= 0.0D;
          motionZ *= 0.5D;
        }
      }

      double d17 = 0.0D;
      double d18 = (double) i + 0.5D + (double) ai[0][0] * 0.5D;
      double d19 = (double) k + 0.5D + (double) ai[0][2] * 0.5D;
      double d20 = (double) i + 0.5D + (double) ai[1][0] * 0.5D;
      double d21 = (double) k + 0.5D + (double) ai[1][2] * 0.5D;
      d9 = d20 - d18;
      d10 = d21 - d19;

      if (d9 == 0.0D) {
        posX = (double) i + 0.5D;
        d17 = posZ - (double) k;
      } else if (d10 == 0.0D) {
        posZ = (double) k + 0.5D;
        d17 = posX - (double) i;
      } else {
        double d22 = posX - d18;
        double d24 = posZ - d19;
        double d26 = (d22 * d9 + d24 * d10) * 2D;
        d17 = d26;
      }

      posX = d18 + d9 * d17;
      posZ = d19 + d10 * d17;
      setPosition(posX, posY + (double) yOffset, posZ);
      double d23 = motionX;
      double d25 = motionZ;

      if (riddenByEntity != null) {
        d23 *= 0.75D;
        d25 *= 0.75D;
      }

      if (d23 < -d2) {
        d23 = -d2;
      }

      if (d23 > d2) {
        d23 = d2;
      }

      if (d25 < -d2) {
        d25 = -d2;
      }

      if (d25 > d2) {
        d25 = d2;
      }

      moveEntity(d23, 0.0D, d25);

      if (ai[0][1] != 0
          && MathHelper.floor_double(posX) - i == ai[0][0]
          && MathHelper.floor_double(posZ) - k == ai[0][2]) {
        setPosition(posX, posY + (double) ai[0][1], posZ);
      } else if (ai[1][1] != 0
          && MathHelper.floor_double(posX) - i == ai[1][0]
          && MathHelper.floor_double(posZ) - k == ai[1][2]) {
        setPosition(posX, posY + (double) ai[1][1], posZ);
      }

      if (riddenByEntity != null) {
        motionX *= 0.997D;
        motionY *= 0.0D;
        motionZ *= 0.997D;
      } else {
        if (minecartType == 2) {
          double d27 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);

          if (d27 > 0.01D) {
            pushX /= d27;
            pushZ /= d27;
            double d29 = 0.04D;
            motionX *= 0.8D;
            motionY *= 0.0D;
            motionZ *= 0.8D;
            motionX += pushX * d29;
            motionZ += pushZ * d29;
          } else {
            motionX *= 0.9D;
            motionY *= 0.0D;
            motionZ *= 0.9D;
          }
        }

        motionX *= 0.96D;
        motionY *= 0.0D;
        motionZ *= 0.96D;
      }

      Vec3D vec3d1 = func_182_g(posX, posY, posZ);

      if (vec3d1 != null && vec3d != null) {
        double d28 = (vec3d.yCoord - vec3d1.yCoord) * 0.05D;
        double d14 = Math.sqrt(motionX * motionX + motionZ * motionZ);

        if (d14 > 0.0D) {
          motionX = (motionX / d14) * (d14 + d28);
          motionZ = (motionZ / d14) * (d14 + d28);
        }

        setPosition(posX, vec3d1.yCoord, posZ);
      }

      int k1 = MathHelper.floor_double(posX);
      int l1 = MathHelper.floor_double(posZ);

      if (k1 != i || l1 != k) {
        double d15 = Math.sqrt(motionX * motionX + motionZ * motionZ);
        motionX = d15 * (double) (k1 - i);
        motionZ = d15 * (double) (l1 - k);
      }

      if (minecartType == 2) {
        double d30 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);

        if (d30 > 0.01D && motionX * motionX + motionZ * motionZ > 0.001D) {
          pushX /= d30;
          pushZ /= d30;

          if (pushX * motionX + pushZ * motionZ < 0.0D) {
            pushX = 0.0D;
            pushZ = 0.0D;
          } else {
            pushX = motionX;
            pushZ = motionZ;
          }
        }
      }

      if (flag) {
        double d31 = Math.sqrt(motionX * motionX + motionZ * motionZ);

        if (d31 > 0.01D) {
          double d32 = 0.04D;
          motionX += (motionX / d31) * d32;
          motionZ += (motionZ / d31) * d32;
        } else if (i1 == 1) {
          if (worldObj.isBlockNormalCube(i - 1, j, k)) {
            motionX = 0.02D;
          } else if (worldObj.isBlockNormalCube(i + 1, j, k)) {
            motionX = -0.02D;
          }
        } else if (i1 == 0) {
          if (worldObj.isBlockNormalCube(i, j, k - 1)) {
            motionZ = 0.02D;
          } else if (worldObj.isBlockNormalCube(i, j, k + 1)) {
            motionZ = -0.02D;
          }
        }
      }
    } else {
      if (motionX < -d2) {
        motionX = -d2;
      }

      if (motionX > d2) {
        motionX = d2;
      }

      if (motionZ < -d2) {
        motionZ = -d2;
      }

      if (motionZ > d2) {
        motionZ = d2;
      }

      if (onGround) {
        motionX *= 0.5D;
        motionY *= 0.5D;
        motionZ *= 0.5D;
      }

      moveEntity(motionX, motionY, motionZ);

      if (!onGround) {
        motionX *= 0.95D;
        motionY *= 0.95D;
        motionZ *= 0.95D;
      }
    }

    rotationPitch = 0.0F;
    double d6 = prevPosX - posX;
    double d7 = prevPosZ - posZ;

    if (d6 * d6 + d7 * d7 > 0.001D) {
      rotationYaw = (float) ((Math.atan2(d7, d6) * 180D) / Math.PI);

      if (field_469_aj) {
        rotationYaw += 180F;
      }
    }

    double d8;

    for (d8 = rotationYaw - prevRotationYaw; d8 >= 180D; d8 -= 360D) {}

    for (; d8 < -180D; d8 += 360D) {}

    if (d8 < -170D || d8 >= 170D) {
      rotationYaw += 180F;
      field_469_aj = !field_469_aj;
    }

    setRotation(rotationYaw, rotationPitch);
    List list =
        worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.2D, 0.0D, 0.2D));

    if (list != null && list.size() > 0) {
      for (int j1 = 0; j1 < list.size(); j1++) {
        Entity entity = (Entity) list.get(j1);

        if (entity != riddenByEntity
            && entity.canBePushed()
            && (entity instanceof EntityMinecart)) {
          entity.applyEntityCollision(this);
        }
      }
    }

    if (riddenByEntity != null && riddenByEntity.isDead) {
      if (riddenByEntity.ridingEntity == this) {
        riddenByEntity.ridingEntity = null;
      }

      riddenByEntity = null;
    }

    if (fuel > 0) {
      fuel--;
    }

    if (fuel <= 0) {
      pushX = pushZ = 0.0D;
    }

    setMinecartPowered(fuel > 0);
  }