You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Minecraft Forge中EntityInteract事件取消失效问题求助

解决PlayerInteractEvent.EntityInteract取消后仍打开马物品栏的问题

我明白你遇到的困扰——事件触发了、消息也发了,但服务器还是执意打开马的物品栏。这大概率是因为你漏处理了一个关键的交互事件,咱们一步步来搞定它:

1. 同时处理EntityInteractEntityInteractSpecific事件

当玩家精准点击马的身体部位时,Forge会优先触发PlayerInteractEvent.EntityInteractSpecific而非普通的EntityInteract,这是很多开发者容易踩的坑。你需要同时注册这两个事件的处理方法,覆盖所有交互场景。

整理后的代码示例:

// 处理普通实体交互事件
@SubscribeEvent(priority = EventPriority.HIGHEST)
public void onEntityInteract(PlayerInteractEvent.EntityInteract event) {
    handleHorseInteraction(event.getPlayer(), event.getTarget(), event);
}

// 处理精准实体交互事件(重点!马的交互大多触发这个)
@SubscribeEvent(priority = EventPriority.HIGHEST)
public void onEntityInteractSpecific(PlayerInteractEvent.EntityInteractSpecific event) {
    handleHorseInteraction(event.getPlayer(), event.getTarget(), event);
}

// 提取公共逻辑,避免重复代码
private void handleHorseInteraction(PlayerEntity player, Entity target, PlayerInteractEvent event) {
    if (player == null || player.world.isClient || !(target instanceof AbstractHorseEntity)) {
        return;
    }

    AbstractHorseEntity horseEntity = (AbstractHorseEntity) target;
    if (player.isCrouching()) {
        Item mainItem = player.getHeldItemMainhand().getItem();
        for (Item allowedItem : allowed) {
            if (mainItem.equals(allowedItem)) {
                String[] result = new HorseStats().getHorseStats(horseEntity);
                for (String s : result) {
                    if (s != null && !s.isEmpty()) {
                        player.sendMessage(new TranslationTextComponent(s));
                    }
                }
                // 正确设置事件状态,彻底阻止后续处理
                event.setResult(Event.Result.DENY);
                event.setCanceled(true);
                event.setCancellationResult(ActionResultType.SUCCESS);
                return;
            }
        }
    }
}

2. 确保在服务器端处理取消逻辑

代码里加了player.world.isClient的判断,避免在客户端执行不必要的操作。核心的取消逻辑必须在服务器端执行,这样服务器才会终止打开马栏的请求流程。

3. 额外优化:阻止客户端的交互反馈

如果客户端还会显示打开马栏的动画,你可以在客户端也处理这两个事件并取消,这样客户端既不会向服务器发送交互数据包,也不会有视觉上的多余反馈:

@SubscribeEvent(priority = EventPriority.HIGHEST)
@OnlyIn(Dist.CLIENT)
public void onClientEntityInteract(PlayerInteractEvent.EntityInteract event) {
    handleClientHorseInteraction(event.getPlayer(), event.getTarget(), event);
}

@SubscribeEvent(priority = EventPriority.HIGHEST)
@OnlyIn(Dist.CLIENT)
public void onClientEntityInteractSpecific(PlayerInteractEvent.EntityInteractSpecific event) {
    handleClientHorseInteraction(event.getPlayer(), event.getTarget(), event);
}

@OnlyIn(Dist.CLIENT)
private void handleClientHorseInteraction(PlayerEntity player, Entity target, PlayerInteractEvent event) {
    if (player == null || !(target instanceof AbstractHorseEntity)) {
        return;
    }

    AbstractHorseEntity horseEntity = (AbstractHorseEntity) target;
    if (player.isCrouching()) {
        Item mainItem = player.getHeldItemMainhand().getItem();
        for (Item allowedItem : allowed) {
            if (mainItem.equals(allowedItem)) {
                event.setResult(Event.Result.DENY);
                event.setCanceled(true);
                return;
            }
        }
    }
}

这样修改后,再蹲下手持允许物品点击马,服务器就不会处理打开马栏的请求,同时还能正常显示马的属性消息啦。

内容的提问来源于stack exchange,提问作者recklessGreed

火山引擎 最新活动