Connor Robb
Connor Robb

Reputation: 1

How do I properly cancel block placement from PlayerInteractEvent.RightClickBlock?

I'm just getting into Minecraft modding and I'm writing a simple mod where you can hold control and right-click with cobblestone on obsidian to get a "rock" item. The intended functionality is that when the player performs this action, they will expend a cobblestone and gain a rock, without placing down the cobblestone. It's pretty much working, though I get a strange effect when I activate it. It seems like the client makes it look like the block was placed for a tick or so before the server removes it. (At least, that's what it looks like anyway.)

Here's my code:

    @SubscribeEvent
    public static void onStoneSmash(final PlayerInteractEvent.RightClickBlock event) {

        System.out.println("Is Server: " + event.getSide().isServer());

        final World world = event.getWorld();

        if (world.isRemote()) {
            return;
        }

        if (world != null && event.getUseBlock() != Result.DENY) {
            final PlayerEntity player = event.getPlayer();

            if (player != null && !player.isSpectator() && !world.isAirBlock(event.getPos())) {
                final BlockPos pos = event.getPos();

                if (InputMappings.isKeyDown(Minecraft.getInstance().getMainWindow().getHandle(), GLFW.GLFW_KEY_LEFT_CONTROL) && world.getBlockState(pos).getBlock().equals(Blocks.OBSIDIAN) && player.inventory.getCurrentItem().getItem().equals(Blocks.COBBLESTONE.asItem())) {
                    player.inventory.addItemStackToInventory(new ItemStack(ItemInit.ROCK.get(), 1));
                    if (!player.isCreative()) {
                        player.inventory.decrStackSize(player.inventory.currentItem, 1);
                    }

                    System.out.println("Rock smashed.");

                    event.setCanceled(true);

                }
            }
        }

        System.out.println("Use Block: " + event.getUseBlock());
        System.out.println("Use Item: " + event.getUseItem());

    }

As I said, I'm quite new to the modding scene, so I'm sure that there's a lot in here that won't look so pretty.

Additional Information:

MC Version: 1.16.4

Forge Version: 1.16.4 - 35.1.4

I'll provide more information on request if need be.

Thanks!

EDIT: Here's a gif of the problem I'm referring to.

https://i.sstatic.net/9sfEJ.jpg

Upvotes: 0

Views: 1763

Answers (2)

Connor Robb
Connor Robb

Reputation: 1

So, after getting some help from experienced modders, I learned that I'm sorta going about this the wrong way. I need to run a check to find whether the player is holding control on the client, then send a packet to the server and continue from there. Unfortunately, I haven't finished my solution yet since I'm still trying to figure out how to use packets, but I'll update this answer when I have something of a solution.

Hopefully, this might help someone.

Upvotes: 0

TaljaFox
TaljaFox

Reputation: 13

You can do event.setCancelled(true) sorry if i spelt Cancel incorrect because its very late for me.

Edit: event.setCancelled(true) should work if you want to stop a placement like say a oak plank then you would want to check if it is then set the event to cancelled

Edit2: Oh wait your using interact event why? Wait for another edit i can answer this

Edit3:

Okay so here is a block place event which is what your supposed to use for placing blocks so this should help you also recommend learning a bit more about Spigot API then learning Forge

    @EventHandler // this is spigot you could replace this and find the block place event using forge api
    public void onBlockPlace(BlockPlaceEvent e) {
        
    }

Upvotes: 0

Related Questions