The bug
The BlockPattern
class is incorrectly matching blocks that aren't including the block being placed by the player.
Proof
In the screenshots provided, if you replace the red wool block with a wither skull the wither will be detected and spawned, even though the pattern matched was not comprised of the block the player placed.
Possible fix
Instead of using a block iterator iterating over all blocks in a cube (of size 3 for the wither as it is the max(width,height,depth)
the BlockPattern
class should be iterating over the inverted offsets of the BlockPattern. (e.g. translateOffset(position, face1, face2, -i, -j, -k))
(an optimization is to skip Predicates.alwaysTrue()
and or unplaceable blocks).
There is a second bug that I am having troubles replicating, but involves modded minecraft where as the above is reproducible in vanilla. The second issue is involved with asymmetrical block patterns.
Linked issues
relates to 1
Attachments
Comments 29
I've managed to fix it in a modded version. http://puu.sh/cMfDn/cc88804ea3.jpg is a screenshot of what I've been doing to debug the issue.
I've uploaded the world with an example of what the code is doing.
at 0,64,0 is where the wither head was placed to generate the pattern.
0,0 - Dinnerbones code with a custom BlockPattern.
256,0 - My Fix with a custom BlockPattern.
512,0 - Dinnerbones code with a WitherBoss Pattern.
768,0 - My Fix with a WitherBoss Pattern.
Bedrock represents the block being placed.
Glowstone represents the "origin" of the BlockStructure / predicate array.
On the edge of each row / column / pillar is a "summary" of that column & pillar where the patterns are overlaid from each other.
When the wither skull was placed, the current block pattern in the first orientation overwrote its position, and 10 blocks above all possible rotations were overlaid over each other.
You can see the bug in dinnerbones code clearly, on the translations where the bedrock block is not a part of blockstructure test.
this.witherPattern = FactoryBlockPattern.start()
.aisle(new String[] {"ORRR","G "," " })
.aisle(new String[] {"B "," "," " })
.aisle(new String[] {"B "," "," " })
.where('O',IS_WITHER_SKELETON)
.where('R',Blocks.redstone_block) .where('R',BlockWorldState.hasState(BlockStateHelper.forBlock(Blocks.redstone_block)))
.where('G',Blocks.slime_block) .where('G',BlockWorldState.hasState(BlockStateHelper.forBlock(Blocks.slime_block)))
.where('B',Blocks.lapis_block) .where('B',BlockWorldState.hasState(BlockStateHelper.forBlock(Blocks.lapis_block)))
.where('~', BlockWorldState.hasState(BlockStateHelper.forBlock(Blocks.air))).build();
Confirmed for 1.8.6. It spawns...then moves while still invincible 😞
Confirmed, but only seemed to happen when facing south/east.