mojira.dev
MC-9176

Glass panes not correctly rendering with the back of stairs

When glass panes are placed they do not bind with the full block back of stairs like they should.

Related issues

Attachments

Comments

migrated
[media][media]
Tails

Glass panes, fences and iron bars do not connect to stairs.

rydian

... because stairs are transparent.

bugi74

The above is the explanation (=excuse) why they are not connected with the current code, but does not mean they are not intended to connect. See, for example, MC-8345. The issue can be fixed to work as players would expect.

(Seems I had already bookmarked this issue so I'd try fixing it, but haven't had yet time to get into it.)

Edit: I took a look at it, and using the changes from MC-8345, this can be fixed somewhat easily. Unfortunately, easy doesn't equal to little work; certain change must be propagated through a bunch of classes, which means too much work for this night. Alternately, certain methods can be changed a tiny bit, but that would in turn require a lot of testing (to not break something else), or, a bunch of code could be copied and adapted to this specific case, but that is just bad coding style.

Hmm.. looks like lots of the code to be copied in that last choice has already duplication in it, so it might actually give a decent result after some combining and cleanup. Have to have a better look at this... perhaps tomorrow.

Simons Mith

I'm very much with MArkku here. And would those who use the excuse that stairs are transparent kindly explain why glass panes /do/ join to leaves, glass blocks and glowstone, all of which are classed as transparent blocks?

fuj1n

The reason why glass panes connect to the above blocks is that they are hard-coded to do so, the glass panes has been intentionally programmed to not connect to transparent blocks, and have a few exceptions (eg. if(par1IBlockAccess.isBlockSolid(par2 - 1, par3, par4) || par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == Block.glass.blockId){ } this is just a simple example).

bugi74

Exactly like fuj1n explains. And that is the part I'm going to "attack". I'll add similar smartness as in the torch placement bug. Just it wasn't as trivial to apply to this issue as to the other one, due to some design decisions/architecture hiccups. I'm still at work, but I'll get to this later today.

bugi74

Sample screenshot 'fixed-panes-stairs.png' showing both torches attached and glass panes connected to backside of stair blocks. Code fixes incoming.

bugi74

(NOTE: would be best to fix all of this, MC-8345 and MC-2938 at the same time; see the MC-2938 for more text.)

Fix
The basic reason for the issue is the same as for the MC-8345; the code does not have own method to check only surfaces of blocks, so it checks just the full block type, and also typically has some special case handling here and there (like fuj1n explained for this issue).

To resolve the torches vs. backs of stairs, I added a method to check just for the block's surface (if it is a full and solid surface). It didn't directly work for this issue, as it was made just for the torch-stuff at the time. I made the necessary changes to accommodate both issues, and as a side-effect, made the new method work more correctly. (I'll update the code in the other issue, too.)

However, I also had to adjust certain method calls in a way that may have some undesired side-effects. Testing recommended.

Here are the code changes, using mix of MCP and my own namings:

Block

/**
     * Override as necessary.
     * @param side 1 = bottom, 2 = z+1, 3 = z-1, 4 = x+1, 5 = x-1,  top = 0 or anything else
     * @return true if that side is solid and full surface
     */
    public boolean hasSolidFullSurfaceAt(IBlockAccess access, int x, int y, int z, int side) {
        switch (side) {
            case 1: return access.isBlockNormalCube(x, y, z);
            case 2:
            case 3:
            case 4:
            case 5: return access.isBlockNormalCube(x, y, z);
            default: return access.doesBlockHaveSolidTopSurface(x, y, z);
        }
    }

BlockStairs

public boolean hasSolidFullSurfaceAt(IBlockAccess access, int x, int y, int z, int side) {
        int metaData = access.getBlockMetadata(x, y, z);
        switch (side) {
            case 1: return (metaData & 4) == 0;
            case 2: return (metaData & 3) == 3;
            case 3: return (metaData & 3) == 2;
            case 4: return (metaData & 3) == 1;
            case 5: return (metaData & 3) == 0;
            default: return (metaData & 4) == 1; // true if it is upside down
        }
    }

BlockPane

public void addCollidingBlockToList(World world, int x, int y, int z, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) {
//        boolean north = this.canThisPaneConnectToThisBlockID(world.getBlockId(x, y, z - 1));
//        boolean south = this.canThisPaneConnectToThisBlockID(world.getBlockId(x, y, z + 1));
//        boolean west = this.canThisPaneConnectToThisBlockID(world.getBlockId(x - 1, y, z));
//        boolean east = this.canThisPaneConnectToThisBlockID(world.getBlockId(x + 1, y, z));
        boolean north = this.canPaneAtConnectToDir(world, x, y, z, 3);
        boolean south = this.canPaneAtConnectToDir(world, x, y, z, 2);
        boolean west = this.canPaneAtConnectToDir(world, x, y, z, 5);
        boolean east = this.canPaneAtConnectToDir(world, x, y, z, 4);
        ...

    public void setBlockBoundsBasedOnState(IBlockAccess blockAccess, int x, int y, int z) {
        ...
//        boolean north = this.canThisPaneConnectToThisBlockID(blockAccess.getBlockId(x, y, z - 1));
//        boolean south = this.canThisPaneConnectToThisBlockID(blockAccess.getBlockId(x, y, z + 1));
//        boolean west = this.canThisPaneConnectToThisBlockID(blockAccess.getBlockId(x - 1, y, z));
//        boolean east = this.canThisPaneConnectToThisBlockID(blockAccess.getBlockId(x + 1, y, z));
        boolean north = this.canPaneAtConnectToDir(blockAccess, x, y, z, 3);
        boolean south = this.canPaneAtConnectToDir(blockAccess, x, y, z, 2);
        boolean west = this.canPaneAtConnectToDir(blockAccess, x, y, z, 5);
        boolean east = this.canPaneAtConnectToDir(blockAccess, x, y, z, 4);
        ...

    /**
     * ADDED METHOD.
     * @param dir 1 = bottom, 2 = z+1, 3 = z-1, 4 = x+1, 5 = x-1,  top = 0 or anything else
     */
    public final boolean canPaneAtConnectToDir(IBlockAccess access, int x, int y, int z, int dir) {
        switch (dir) {
            case 2: { z++; break; }
            case 3: { z--; break; }
            case 4: { x++; break; }
            case 5: { x--; break; }
            default: return false;
        }
        
        int blockId = access.getBlockId(x, y, z);
        if (this.canThisPaneConnectToThisBlockID(blockId)) return true; // Old check
        // ADDED CHECK (compared to old operation), THE CORE OF THIS FIX:
        Block block = Block.blocksList[blockId];
        if (block == null)
            return false;
        return block.hasSolidFullSurfaceAt(access, x, y, z, dir);
    }

RenderBlocks.renderBlockPane()

...
//        boolean north = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(x, y, z - 1));
//        boolean south = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(x, y, z + 1));
//        boolean west = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(x - 1, y, z));
//        boolean east = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(x + 1, y, z));
        boolean north = blockPane.canPaneAtConnectToDir(blockAccess, x, y, z, 3);
        boolean south = blockPane.canPaneAtConnectToDir(blockAccess, x, y, z, 2);
        boolean west = blockPane.canPaneAtConnectToDir(blockAccess, x, y, z, 5);
        boolean east = blockPane.canPaneAtConnectToDir(blockAccess, x, y, z, 4);
        ...

I tested changes on 1.4.7, results as in the screenshot. (Though the torches need also the MC-8345 fixes applied, too.)

bugi74

Affects 13w09b.

bugi74

Affects 13w09c.

Mordikins

Markku wrote a fix... why is this still unresolved?

Marios

I seriously hope this is not considered to be intended behavior. Voted.

Robert Lawson

I am seeing the same issue in the new 1.7.2 release.

Itouch2

Confirmed for 1.7.5, 14w08a and 14w10c

Itouch2

Confirmed for 14w11b

rydian

Confirmed in 1.8.1-pre1.

rydian

Confirmed in 1.8.1-pre5.

rydian

Still happening in 15w42a.

rydian

Still happening in 15w44b.

rydian

Still happening in 15w45a.

rydian

Still happening in 15w47a.

rydian

Still happening in 1.9-pre2.

Kris Wilkins

Confirmed in 1.10.

Socks

still in 16w44a

Socks

still in 1.11 Pre-Release 1

Adam Towers

migrated

Confirmed

Minecraft 1.4.6, Minecraft 1.4.7, Snapshot 13w05b, Snapshot 13w09a, Snapshot 13w09b, ..., Minecraft 16w43a, Minecraft 16w44a, Minecraft 1.11 Pre-Release 1, Minecraft 1.11.2, Minecraft 17w06a

Minecraft 17w15a

Retrieved