mojira.dev
MC-222484

Farmland or dirt path cannot be created below a light block

The bug

If there is a light block above a dirt, the dirt cannot farmed or become a dirt path.

How to reproduce

  1. Place a light block on a dirt or grass block.

  2. Right click the dirt or grass block by a hoe or shovel.
    → ❌ The block should become a farmland or a dirt path but not.

Code analysis

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

Linked issues

Attachments

Comments 14

Avoma

Can confirm. Also affects 21w14a.

Avoma

Can confirm in 21w15a.

Avoma

Can confirm in 21w16a.

Avoma

Can confirm in 21w17a.

corey manlen

because lighjt blocks are full blocks with hitboxes and you can't till farmland under a block

4 more comments
Avoma

I can confirm this behavior in 1.18.

Here's a code analysis of this issue. The following is based on a decompiled version of Minecraft 1.18 using MCP-Reborn. Please note that I'm quite tentative about this analysis, although I'm persuaded to believe that this is likely the cause of the problem. 🙂

Code Analysis (tentative):

net.minecraft.world.item.HoeItem.java

public class HoeItem extends DiggerItem {
   protected static final Map<Block, Pair<Predicate<UseOnContext>, Consumer<UseOnContext>>> TILLABLES = Maps.newHashMap(ImmutableMap.of(Blocks.GRASS_BLOCK, Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.FARMLAND.defaultBlockState())), Blocks.DIRT_PATH, Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.FARMLAND.defaultBlockState())), Blocks.DIRT, Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.FARMLAND.defaultBlockState())), Blocks.COARSE_DIRT, Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.DIRT.defaultBlockState())), Blocks.ROOTED_DIRT, Pair.of(($$0) -> {
      return true;
   }, changeIntoStateAndDropItem(Blocks.DIRT.defaultBlockState(), Items.HANGING_ROOTS))));
   ...
   public static boolean onlyIfAirAbove(UseOnContext $$1) {
      return $$1.getClickedFace() != Direction.DOWN && $$1.getLevel().getBlockState($$1.getClickedPos().above()).isAir();
   }
}

net.minecraft.world.item.ShovelItem.java

public class ShovelItem extends DiggerItem {
   protected static final Map<Block, BlockState> FLATTENABLES = Maps.newHashMap((new Builder()).put(Blocks.GRASS_BLOCK, Blocks.DIRT_PATH.defaultBlockState()).put(Blocks.DIRT, Blocks.DIRT_PATH.defaultBlockState()).put(Blocks.PODZOL, Blocks.DIRT_PATH.defaultBlockState()).put(Blocks.COARSE_DIRT, Blocks.DIRT_PATH.defaultBlockState()).put(Blocks.MYCELIUM, Blocks.DIRT_PATH.defaultBlockState()).put(Blocks.ROOTED_DIRT, Blocks.DIRT_PATH.defaultBlockState()).build());
   ...
   public InteractionResult useOn(UseOnContext $$0) {
      Level level = $$0.getLevel();
      BlockPos blockpos = $$0.getClickedPos();
      BlockState blockstate = level.getBlockState(blockpos);
      if ($$0.getClickedFace() == Direction.DOWN) {
         return InteractionResult.PASS;
      } else {
         Player player = $$0.getPlayer();
         BlockState blockstate1 = FLATTENABLES.get(blockstate.getBlock());
         BlockState blockstate2 = null;
         if (blockstate1 != null && level.getBlockState(blockpos.above()).isAir()) {
            level.playSound(player, blockpos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
            ...

If we look at the above classes, we can see that you can only convert blocks using shovels and hoes if air is above them. This is evident through the following line of codes:

net.minecraft.world.item.HoeItem.java

HoeItem::onlyIfAirAbove

net.minecraft.world.item.ShovelItem.java

if (blockstate1 != null && level.getBlockState(blockpos.above()).isAir())
Avoma

Can confirm in 1.18.1.

Avoma

Can confirm in 1.18.2.

Avoma

Can confirm in 1.19.

Avoma

Can confirm in 1.19.2.

wayne

(Unassigned)

Confirmed

Platform

Normal

Block states

light

21w13a, 21w14a, 21w15a, 21w16a, 21w17a, ..., 1.20.1, 23w32a, 23w33a, 1.20.4, 1.21

Retrieved