mojira.dev
MC-94566

Breaking non-container comparator-enabled blocks doesn't send a comparator update through blocks

The bug

As you may know, comparators are able to get a redstone signal from cakes, cauldrons, command blocks, end portal frames, item frames, and jukeboxes, depending on the status of the block/entity in question. As with containers, they are able to read this signal through solid blocks. However, non-containers do not send a comparator update when they break, are fully eaten, are /killed, or are otherwise removed from the game, meaning that a comparator reading it through a solid block will not change power levels until it receives an update from another source.

Placing or updating these blocks will send comparator updates as expected; it is only when they are removed that this happens.

Note that containers used to have an identical problem (MC-11109), which was fixed in 2013.

How to reproduce

  1. Place cake next to a solid block, with a comparator leading out.

  2. Go to survival mode, and use the command /effect @p hunger 1 100 as necessary to eat all the cake. Note, after the last slice, that the comparator remains powered.

  3. Replace the cake.

  4. Break it and note that the comparator is still powered.

  5. Place a cauldron next to the solid block and fill it with water.

  6. Break it and note that the comparator is still powered.

  7. Place a command block next to the solid block, enter the command /say hi (or any other command that will successfully execute), and power it.

  8. Break it and note that the comparator is still powered.

  9. Place an end portal frame next to the solid block, and insert an eye of ender.

  10. Break it and note that the comparator is still powered.

  11. Place an item frame on the solid block and insert an item.

  12. Stand next to it, run /kill @e[r=5,type=item_frame] (version permitting) and note that the comparator is still powered. This one is less of a bug, since it requires console commands, but I am including it for completeness.

  13. Place a jukebox next to the solid block and insert a record.

  14. Break it and note that the comparator is still powered.

  15. Note that placing and modifying these blocks in any way that does not remove them from the world updates the comparator as expected.

Code analysis

Code analysis by @unknown can be found in this comment.

Linked issues

Attachments

Comments 7

Confirmed for 15w51b.

Partwise duplicates MC-16716

As this contains more situations it could be made the main report, however please create a new report for situations other than breaking a block.

Please link to this comment in the description

The following is based on a decompiled version of Minecraft 1.9 using MCP 9.24 beta.

Breaking blocks does not update comparator

The reason for this is that block which override the method net.minecraft.block.Block.hasComparatorInputOverride(IBlockState) to return true do not override the method net.minecraft.block.Block.breakBlock(World, BlockPos, IBlockState) to call the method net.minecraft.world.World.updateComparatorOutputLevel(BlockPos, Block).

Eating cake

The reason for this is that the method net.minecraft.block.BlockCake.eatCake(World, BlockPos, IBlockState, EntityPlayer) is not calling the method net.minecraft.world.World.updateComparatorOutputLevel(BlockPos, Block).

Rain filling cauldron

The reason for this is very likely that the method net.minecraft.block.BlockCauldron.fillWithRain(World, BlockPos) is directly changing the block state instead of calling the method net.minecraft.block.BlockCauldron.setWaterLevel(World, BlockPos, IBlockState, int).

Destroying ItemFrame using /kill

The reason for this is that the class net.minecraft.entity.item.EntityItemFrame is not overriding the method net.minecraft.entity.Entity.onKillCommand() or does not update comparators if its isDead field is true.

Destroying ItemFrame using explosions

The reason for this is that the method net.minecraft.entity.item.EntityItemFrame.attackEntityFrom(DamageSource, float) only calls the method net.minecraft.entity.item.EntityItemFrame.setDisplayedItem(ItemStack) which updates the comparator level if the damage source was not an explosion. Based on "Destroying ItemFrame invalid position" the comparator level should be updated only if it does not drop an item (because it was destroyed by an explosion). All other cases should be covered by "Destroying ItemFrame invalid position".

Destroying ItemFrame invalid position

The method net.minecraft.entity.item.EntityItemFrame.dropItemOrSelf(Entity, boolean) is not updating the comparator output level, which it should do always, because either the item is removed or the complete ItemFrame. Might overlap with "Destroying ItemFrame using /kill" if that was solved by testing if isDead is true.

Is this still an issue in the latest snapshot 16w44a? If so please update the affected versions.

This is an automated comment on any open or reopened issue with out-of-date affected versions.

Confirmed for 1.13.1.

Confirmed in 1.15.2 and 1.16 Release Candidate 1.

Can confirm in 1.17.1 but this should probably be forward-resolved to MC-120986.

AjaxGb

(Unassigned)

Confirmed

(Unassigned)

Minecraft 15w49a, Minecraft 15w49b, Minecraft 1.8.9, Minecraft 15w50a, Minecraft 15w51a, ..., 1.16 Release Candidate 1, 1.16, 1.17.1, 1.20.2, 1.21.3

Retrieved