mojira.dev
MC-132706

Sticky pistons pull blocks that pop off

If a block that would pop off when pushed is pulled, it also pops off.

Expected behaviour (happens in 1.12):
The block is ignored, not pulled

Actual behaviour:
Block is pulled, usually resulting in it popping off

Also affects glazed terracotta (MC-133214)

Video:
https://www.youtube.com/watch?v=2t1cpX6Dm5M

Linked issues

Comments 6

I think I have an idea what might have happened. In the sticky piston retraction code there is a big nasty if statement for determining if the piston can pull the block or structure in front of it. I think it originally looked like this:

 

if (!movingState.isAir() && isPushable(movingState, level, twoPos, direction.getOpposite(), false, direction) && (movingState.getPistonPushReaction() == PushReaction.NORMAL || movingBlock == Blocks.PISTON || movingBlock == Blocks.STICKY_PISTON))

 

While Grum was working on MC-54026, I recall him expressing frustration at how unwieldy that if statement is in EigenCraft. I suspect he tried to refactor it. 🙂 Something probably got missed. The fix is probably a simple one.

 

 

I found the comment I was remembering:

 

[media]

Removing the following check would produce the behavior seen (based on 1.12.2 code):

isPushable(movingState, level, twoPos, direction.getOpposite(), false, direction)

Later on in the moveBlocks function a similar, but not quite the same check, is done. I have to use MCP naming for the rest of this. In MCP the moveBlocks function is named canPush.

BlockPistonStructureHelper blockpistonstructurehelper = new BlockPistonStructureHelper(worldIn, pos, direction, extending);

        if (!blockpistonstructurehelper.canMove())
        {
            return false;
        }

The call to blockpistonstructurehelper.canMove() contains:

if (!BlockPistonBase.canPush(iblockstate, this.world, this.blockToMove, this.moveDirection, false, this.moveDirection))
        {
            if (iblockstate.getMobilityFlag() == EnumPushReaction.DESTROY)
            {
                this.toDestroy.add(this.blockToMove);
                return true;
            }
            else
            {
                return false;
            }
        }

You can see that this check is slightly different. The first direction parameter is not reversed, which is what causes the glazed terracotta block to be pulled, and if a block is marked as a destructable block the function allows the move and add the block to the list of blocks to break.

This helper function is specifically designed for pushing and not retracting. Adding the original check back to the if statement should be all that is needed to fix this bug.

Unfortunately this is only partially resolved. "Destructable" blocks are fixed, but sticky pistons are still pulling glazed terracotta blocks. Can this be re-opened?

I had the following bug report: https://bugs.mojang.com/browse/MC-132898 "Multiple layers of falling gravity blocks break"

Is this bug MC-132706 the root cause of my bug MC-132898? I'll edit this message if it appears my bug is "fixed", and I'll note there as well as reference this bug as I think they may be related.

EDIT:
My issue is still unresolved in Pre7. In a double-layer of gravel blocks, one layer gets broken by a double-retraction. Is it appropriate then to assume that bug is not related to this bug? And would someone be able to confirm if they have the same item breaking when a gravity block in two or more layers breaks when pulled in a double-piston retraction?

Probably related but not the exact same bug; they did some internal changes to pistons and that may have created that bug in addition to this. I'll link it.

Earthcomputer

michael

Confirmed

sticky_piston

Minecraft 1.13-pre6

Minecraft 1.13-pre7

Retrieved