public float getFluidHeightForRender(
      IBlockAccess world, int x, int y, int z, BlockFluidBase block) {
    if (world.getBlock(x, y, z) == block) {
      Block verticalOrigin = world.getBlock(x, y - block.densityDir, z);
      if (verticalOrigin.getMaterial().isLiquid() || verticalOrigin instanceof IFluidBlock) {
        return 1;
      }

      if (world.getBlockMetadata(x, y, z) == block.getMaxRenderHeightMeta()) {
        return 0.875F;
      }
    }
    return !world.getBlock(x, y, z).getMaterial().isSolid()
            && world.getBlock(x, y - block.densityDir, z) == block
        ? 1
        : block.getQuantaPercentage(world, x, y, z) * 0.875F;
  }
  @Override
  public boolean renderWorldBlock(
      IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
    if (!(block instanceof BlockFluidBase)) {
      return false;
    }

    Tessellator tessellator = Tessellator.instance;
    int color = block.colorMultiplier(world, x, y, z);
    float red = (color >> 16 & 255) / 255.0F;
    float green = (color >> 8 & 255) / 255.0F;
    float blue = (color & 255) / 255.0F;

    BlockFluidBase theFluid = (BlockFluidBase) block;
    int bMeta = world.getBlockMetadata(x, y, z);

    boolean renderTop = world.getBlock(x, y - theFluid.densityDir, z) != theFluid;

    boolean renderBottom =
        block.shouldSideBeRendered(world, x, y + theFluid.densityDir, z, 0)
            && world.getBlock(x, y + theFluid.densityDir, z) != theFluid;

    boolean[] renderSides =
        new boolean[] {
          block.shouldSideBeRendered(world, x, y, z - 1, 2),
          block.shouldSideBeRendered(world, x, y, z + 1, 3),
          block.shouldSideBeRendered(world, x - 1, y, z, 4),
          block.shouldSideBeRendered(world, x + 1, y, z, 5)
        };

    if (!renderTop
        && !renderBottom
        && !renderSides[0]
        && !renderSides[1]
        && !renderSides[2]
        && !renderSides[3]) {
      return false;
    } else {
      boolean rendered = false;
      double heightNW, heightSW, heightSE, heightNE;
      float flow11 = getFluidHeightForRender(world, x, y, z, theFluid);

      if (flow11 != 1) {
        float flow00 = getFluidHeightForRender(world, x - 1, y, z - 1, theFluid);
        float flow01 = getFluidHeightForRender(world, x - 1, y, z, theFluid);
        float flow02 = getFluidHeightForRender(world, x - 1, y, z + 1, theFluid);
        float flow10 = getFluidHeightForRender(world, x, y, z - 1, theFluid);
        float flow12 = getFluidHeightForRender(world, x, y, z + 1, theFluid);
        float flow20 = getFluidHeightForRender(world, x + 1, y, z - 1, theFluid);
        float flow21 = getFluidHeightForRender(world, x + 1, y, z, theFluid);
        float flow22 = getFluidHeightForRender(world, x + 1, y, z + 1, theFluid);

        heightNW = getFluidHeightAverage(new float[] {flow00, flow01, flow10, flow11});
        heightSW = getFluidHeightAverage(new float[] {flow01, flow02, flow12, flow11});
        heightSE = getFluidHeightAverage(new float[] {flow12, flow21, flow22, flow11});
        heightNE = getFluidHeightAverage(new float[] {flow10, flow20, flow21, flow11});
      } else {
        heightNW = flow11;
        heightSW = flow11;
        heightSE = flow11;
        heightNE = flow11;
      }

      boolean rises = theFluid.densityDir == 1;
      if (renderer.renderAllFaces || renderTop) {
        rendered = true;
        IIcon iconStill = getIcon(block.getIcon(1, bMeta));
        float flowDir = (float) BlockFluidBase.getFlowDirection(world, x, y, z);

        if (flowDir > -999.0F) {
          iconStill = getIcon(block.getIcon(2, bMeta));
        }

        heightNW -= RENDER_OFFSET;
        heightSW -= RENDER_OFFSET;
        heightSE -= RENDER_OFFSET;
        heightNE -= RENDER_OFFSET;

        double u1, u2, u3, u4, v1, v2, v3, v4;

        if (flowDir < -999.0F) {
          u2 = iconStill.getInterpolatedU(0.0D);
          v2 = iconStill.getInterpolatedV(0.0D);
          u1 = u2;
          v1 = iconStill.getInterpolatedV(16.0D);
          u4 = iconStill.getInterpolatedU(16.0D);
          v4 = v1;
          u3 = u4;
          v3 = v2;
        } else {
          float xFlow = MathHelper.sin(flowDir) * 0.25F;
          float zFlow = MathHelper.cos(flowDir) * 0.25F;
          u2 = iconStill.getInterpolatedU(8.0F + (-zFlow - xFlow) * 16.0F);
          v2 = iconStill.getInterpolatedV(8.0F + (-zFlow + xFlow) * 16.0F);
          u1 = iconStill.getInterpolatedU(8.0F + (-zFlow + xFlow) * 16.0F);
          v1 = iconStill.getInterpolatedV(8.0F + (zFlow + xFlow) * 16.0F);
          u4 = iconStill.getInterpolatedU(8.0F + (zFlow + xFlow) * 16.0F);
          v4 = iconStill.getInterpolatedV(8.0F + (zFlow - xFlow) * 16.0F);
          u3 = iconStill.getInterpolatedU(8.0F + (zFlow - xFlow) * 16.0F);
          v3 = iconStill.getInterpolatedV(8.0F + (-zFlow - xFlow) * 16.0F);
        }

        tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
        tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);

        if (!rises) {
          tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
          tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
          tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
          tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
        } else {
          tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
          tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
          tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
          tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
        }
      }

      if (renderer.renderAllFaces || renderBottom) {
        rendered = true;
        tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
        if (!rises) {
          tessellator.setColorOpaque_F(LIGHT_Y_NEG * red, LIGHT_Y_NEG * green, LIGHT_Y_NEG * blue);
          renderer.renderFaceYNeg(block, x, y + RENDER_OFFSET, z, getIcon(block.getIcon(0, bMeta)));
        } else {
          tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
          renderer.renderFaceYPos(block, x, y + RENDER_OFFSET, z, getIcon(block.getIcon(1, bMeta)));
        }
      }

      for (int side = 0; side < 4; ++side) {
        int x2 = x;
        int z2 = z;

        switch (side) {
          case 0:
            --z2;
            break;
          case 1:
            ++z2;
            break;
          case 2:
            --x2;
            break;
          case 3:
            ++x2;
            break;
        }

        IIcon iconFlow = getIcon(block.getIcon(side + 2, bMeta));
        if (renderer.renderAllFaces || renderSides[side]) {
          rendered = true;

          double ty1;
          double tx1;
          double ty2;
          double tx2;
          double tz1;
          double tz2;

          if (side == 0) {
            ty1 = heightNW;
            ty2 = heightNE;
            tx1 = x;
            tx2 = x + 1;
            tz1 = z + RENDER_OFFSET;
            tz2 = z + RENDER_OFFSET;
          } else if (side == 1) {
            ty1 = heightSE;
            ty2 = heightSW;
            tx1 = x + 1;
            tx2 = x;
            tz1 = z + 1 - RENDER_OFFSET;
            tz2 = z + 1 - RENDER_OFFSET;
          } else if (side == 2) {
            ty1 = heightSW;
            ty2 = heightNW;
            tx1 = x + RENDER_OFFSET;
            tx2 = x + RENDER_OFFSET;
            tz1 = z + 1;
            tz2 = z;
          } else {
            ty1 = heightNE;
            ty2 = heightSE;
            tx1 = x + 1 - RENDER_OFFSET;
            tx2 = x + 1 - RENDER_OFFSET;
            tz1 = z;
            tz2 = z + 1;
          }

          float u1Flow = iconFlow.getInterpolatedU(0.0D);
          float u2Flow = iconFlow.getInterpolatedU(8.0D);
          float v1Flow = iconFlow.getInterpolatedV((1.0D - ty1) * 16.0D * 0.5D);
          float v2Flow = iconFlow.getInterpolatedV((1.0D - ty2) * 16.0D * 0.5D);
          float v3Flow = iconFlow.getInterpolatedV(8.0D);
          tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x2, y, z2));
          float sideLighting = 1.0F;

          if (side < 2) {
            sideLighting = LIGHT_XZ_NEG;
          } else {
            sideLighting = LIGHT_XZ_POS;
          }

          tessellator.setColorOpaque_F(
              LIGHT_Y_POS * sideLighting * red,
              LIGHT_Y_POS * sideLighting * green,
              LIGHT_Y_POS * sideLighting * blue);

          if (!rises) {
            tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
            tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
            tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
            tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
          } else {
            tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
            tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
            tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
            tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
          }
        }
      }
      renderer.renderMinY = 0;
      renderer.renderMaxY = 1;
      return rendered;
    }
  }