[MC-9176] Glass panes not correctly rendering with the back of stairs Created: 04/Feb/13  Updated: 10/Apr/17  Resolved: 10/Apr/17

Status: Resolved
Project: Minecraft: Java Edition
Component/s: None
Affects Version/s: Minecraft 1.4.6, Minecraft 1.4.7, Snapshot 13w05b, Snapshot 13w09a, Snapshot 13w09b, Snapshot 13w09c, Minecraft 1.5, Snapshot 13w11a, Minecraft 1.5.2, Minecraft 1.6.1, Minecraft 1.6.2, Minecraft 1.7.4, Minecraft 14w05b, Minecraft 14w34b, Minecraft 1.8.1-pre3, Minecraft 1.8.6, Minecraft 1.8.7, Minecraft 1.8.8, Minecraft 15w42a, Minecraft 15w44b, Minecraft 15w45a, Minecraft 15w47a, Minecraft 15w47c, Minecraft 1.9 Pre-Release 2, Minecraft 1.10, Minecraft 1.10.2, Minecraft 16w43a, Minecraft 16w44a, Minecraft 1.11 Pre-Release 1, Minecraft 1.11.2, Minecraft 17w06a
Fix Version/s: Minecraft 17w15a

Type: Bug
Reporter: Adam Towers Assignee: Maria Lemón
Resolution: Fixed Votes: 21
Labels: None

Attachments: PNG File 2013-02-04_20.00.05.png     PNG File fixed-panes-stairs.png    
Issue Links:
Duplicate
is duplicated by MC-28022 Glass panel wont connect to stairs Resolved
is duplicated by MC-56099 Glass pain textures and hit-box do no... Resolved
is duplicated by MC-65836 Fences, iron bars, glass panes, etc. ... Resolved
is duplicated by MC-68101 Glass Panes not connecting to stairs Resolved
Relates
relates to MC-8345 Placing torch on backside of stairs i... Resolved
relates to MC-10613 Fence doesn't connect with stairs Resolved
relates to MC-2938 Different types of fences and walls d... Resolved
CHK:
Confirmation Status: Confirmed

 Description   

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



 Comments   
Comment by Socks [ 09/Nov/16 ]

still in 1.11 Pre-Release 1

Comment by Socks [ 04/Nov/16 ]

still in 16w44a

Comment by Kris Wilkins [ 18/Jun/16 ]

Confirmed in 1.10.

Comment by George Gates [ 20/Feb/16 ]

Still happening in 1.9-pre2.

Comment by George Gates [ 19/Nov/15 ]

Still happening in 15w47a.

Comment by George Gates [ 05/Nov/15 ]

Still happening in 15w45a.

Comment by George Gates [ 01/Nov/15 ]

Still happening in 15w44b.

Comment by George Gates [ 14/Oct/15 ]

Still happening in 15w42a.

Comment by George Gates [ 20/Nov/14 ]

Confirmed in 1.8.1-pre5.

Comment by George Gates [ 15/Oct/14 ]

Confirmed in 1.8.1-pre1.

Comment by Itouch2 [ 15/Mar/14 ]

Confirmed for 14w11b

Comment by Itouch2 [ 12/Mar/14 ]

Confirmed for 1.7.5, 14w08a and 14w10c

Comment by Robert Lawson [ 03/Nov/13 ]

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

Comment by Marios [ 10/Jun/13 ]

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

Comment by Richard Pundurs [ 28/Mar/13 ]

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

Comment by Markku [ 01/Mar/13 ]

Affects 13w09c.

Comment by Markku [ 28/Feb/13 ]

Affects 13w09b.

Comment by Markku [ 22/Feb/13 ]

(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.)

Comment by Markku [ 22/Feb/13 ]

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

Comment by Markku [ 22/Feb/13 ]

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.

Comment by fuj1n (Arthur Uzulin) [ 22/Feb/13 ]

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).

Comment by Simons Mith [ 22/Feb/13 ]

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?

Comment by Markku [ 21/Feb/13 ]

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.

Comment by George Gates [ 21/Feb/13 ]

... because stairs are transparent.

Comment by Tails [ 04/Feb/13 ]

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

Generated at Sun Jan 12 12:20:12 UTC 2025 using Jira 9.12.2#9120002-sha1:301bf498dd45d800842af0b84230f1bb58606c13.