When water is placed diagonally from other water blocks like it does in the screenshots below, it causes a graphical glitch.
You must connect the second source at the farthest point of the first. Let the first stretch all the way out.
It doesn't matter what block is near the water.
Code analysis
Code analysis by @unknown can be found in this comment.
Linked issues
Attachments
Comments 35
Not really intended, but one more case of "it works well enough and doesn't completely break things, so leave it as is for now".
It has been around a long time, and iirc, has even been (ab)used for benefits, but that does not make it less of a bug.
The code calculates the corner water levels based on the existence and levels of water in 8 blocks around each corner/edge. However, it is quite naive and does not make any checks whether the neighbor blocks provide a path for the water to actually affect the block being rendered.
There are a number of cases (block patterns) to check, but it seems doable. This has been "bugging" me, too, so... Working on a fix, lets see what I can come up with.
Current code
I will only include the method signature for the method getFluidHeight() here as the method body gets changed quite a bit, no point in showing the original.
RenderBlocks
public boolean renderBlockFluids(Block block, int x, int y, int z) {
...
double var24 = (double) this.getFluidHeight(x, y, z, var22);
double var26 = (double) this.getFluidHeight(x, y, z + 1, var22);
double var28 = (double) this.getFluidHeight(x + 1, y, z + 1, var22);
double var30 = (double) this.getFluidHeight(x + 1, y, z, var22);
...
}
private float getFluidHeight(int x, int y, int z, Material fluidType)
Better code
RenderBlocks
public boolean renderBlockFluids(Block block, int x, int y, int z) {
...
double var24 = (double) this.getFluidHeight(x, z, x, y, z, var22);
double var26 = (double) this.getFluidHeight(x, z, x, y, z + 1, var22);
double var28 = (double) this.getFluidHeight(x, z, x + 1, y, z + 1, var22);
double var30 = (double) this.getFluidHeight(x, z, x + 1, y, z, var22);
...
}
private float getFluidHeight(int blockx, int bloxkz, int x, int y, int z, Material fluidType) {
int var5 = 0;
float var6 = 0.0F;
for (int direction = 0; direction < 4; ++direction) {
int checkX = x - (direction & 1);
int checkZ = z - (direction >> 1 & 1);
if (this.blockAccess.getBlockMaterial(checkX, y + 1, checkZ) == fluidType) {
// These are checks that there is actually a suitable path for the fluid from that block to this block so that its level can affect.
if (checkX == blockx && checkZ == blockz) // Directly above
return 1.0F;
if (checkX != blockx && checkZ != blockz) { // Diagonal in every way
// Does not affect directly at all.
} else { // Diagonal in one main direction
// If there is same fluid above this block, then 1.0
if (this.blockAccess.getBlockMaterial(blockx, y + 1, blockz) == fluidType)
return 1.0F;
// If there is same fluid under that block, then 1.0
if (this.blockAccess.getBlockMaterial(checkX, y, checkZ) == fluidType)
return 1.0F;
}
}
Material checkedMaterial = this.blockAccess.getBlockMaterial(checkX, y, checkZ);
if (checkedMaterial == fluidType) {
// The diagonal neighbor block must have a path of same fluid to this block, or skip its effect:
if (checkX != blockx && checkZ != blockz
&& (this.blockAccess.getBlockMaterial(checkX, y, blockz) != fluidType
&& this.blockAccess.getBlockMaterial(blockx, y, checkZ) != fluidType)) {
continue;
} else {
int checkedMeta = this.blockAccess.getBlockMetadata(checkX, y, checkZ);
if (checkedMeta >= 8 || checkedMeta == 0) {
var6 += BlockFluid.getFluidHeightPercent(checkedMeta) * 10.0F;
var5 += 10;
}
var6 += BlockFluid.getFluidHeightPercent(checkedMeta);
++var5;
}
} else if (!checkedMaterial.isSolid()) {
// Non-solid makes the level lower
// If it is in diagonal neighbor, then there must be non-solid path, or skip its effect:
if (checkX != blockx && checkZ != blockz
&& (this.blockAccess.getBlockMaterial(checkX, y, blockz).isSolid()
&& this.blockAccess.getBlockMaterial(blockx, y, checkZ).isSolid()))
continue;
++var6;
++var5;
}
}
return 1.0F - var6 / (float) var5;
}
I will attach a screenshot showing the results (for the changed rendering; there are other cases of rendering, which I managed to mess up temporarily while working on the fix, but since they haven't changed with the version above, I won't include screenshots of those.)
can confirm in 1.17.1 and added another example:
[media](the orange blocks are normal solid blocks and the fences on top are all waterlogged and blocked with sings.)
Oh and it doesn't look at all like never fixing these old issues didn't create any new problems later on.... (<- be aware of the sarcasm! And I'm not sure if the amount of negations is right in there)
I got a similar issue to this bug MC-236748
with a quarter-waterlogged big dripleaf.
Version: 1.18.1-pre1
The glitch persists after server restart and client restart.
[media]
I think that this may ne intended, but I am not entirely sure.