Murzik Gaming
Murzik Gaming

Reputation: 1

Level.setBlock() places invisible blocks

I'm trying to create an item that places blocks that are in another hand above the block on which the item is used, but it only places the first block normally, and the others are invisible, which become normal if you right-click on them or rejoin the world

How can this be fixed?

package "my package";

import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

public class BlockPlacerItem extends Item {
    public BlockPlacerItem(Properties pProperties) {
        super(pProperties.stacksTo(1).durability(100));
    }

    @Override
    public @NotNull InteractionResult useOn(UseOnContext pContext) {
        if(!pContext.getLevel().isClientSide()) {
            Level level = pContext.getLevel();
            BlockPos position = pContext.getClickedPos();
            Player player = pContext.getPlayer();
            assert player != null;
            ItemStack item = player.getItemBySlot(EquipmentSlot.OFFHAND);
            int count = item.getCount();
            Block blockType = Block.byItem(item.getItem());

            if(blockType != Blocks.AIR) {
                for (int i = 1; i < count + 1; i++) {
                    BlockPos newPos = position.above(i);
                    level.setBlock(newPos, blockType.defaultBlockState(), 1);
                    level.setBlock(newPos, blockType.defaultBlockState(), 1);
                }
                if(!player.isCreative() && !player.isSpectator()) {
                    item.setCount(0);
                    pContext.getItemInHand().hurtAndBreak(1, Objects.requireNonNull(pContext.getPlayer()), pl -> pl.broadcastBreakEvent(pl.getUsedItemHand()));
                }
            }
        }

        return InteractionResult.SUCCESS;
    }
}

Upvotes: 0

Views: 47

Answers (1)

Gbotdays
Gbotdays

Reputation: 23

The problem here is the probably the blockFlag being used in your level.setBlock()s. Block flags dictate what the block does when it is created. The flag 1 is not sufficient for (most) level.setBlock() calls because it does not update the client or the server. There's more to it, but all you should need to do is replace the 1 with a 3 in your level.setBlock()s.

I would highly recomend going into the decompiled Level class and poking around the setBlock() and markAndNotifyBlock() method(s). You are, however, forewarned: the logic is hard to follow sometimes.

Upvotes: 0

Related Questions