首页 > 解决方案 > 如何从 PlayerInteractEvent.RightClickBlock 正确取消块放置?

问题描述

我刚刚进入 Minecraft 模组,我正在编写一个简单的模组,您可以在其中保持控制并右键单击黑曜石上的鹅卵石以获得“岩石”物品。预期的功能是,当玩家执行此操作时,他们将花费一块圆石并获得一块石头,而无需放下圆石。它几乎可以正常工作,尽管当我激活它时会产生奇怪的效果。看起来客户端让它看起来像是在服务器删除它之前放置了一个滴答声左右。(至少,无论如何,这就是它的样子。)

这是我的代码:

    @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());

    }

正如我所说,我对改装场景还很陌生,所以我敢肯定这里有很多看起来不那么漂亮的东西。

附加信息:

MC版本:1.16.4

锻造版本:1.16.4 - 35.1.4

如果需要,我会根据要求提供更多信息。

谢谢!

编辑:这是我所指问题的 gif 图像。

https://imgur.com/ix5V7CB

标签: javaminecraftminecraft-forge

解决方案


所以,在从经验丰富的改装者那里得到一些帮助后,我了解到我正在以错误的方式解决这个问题。我需要检查一下玩家是否控制了客户端,然后向服务器发送一个数据包并从那里继续。不幸的是,我还没有完成我的解决方案,因为我仍在尝试弄清楚如何使用数据包,但是当我有解决方案时,我会更新这个答案。

希望这可能对某人有所帮助。


推荐阅读