William_Shi
观察到,手持物品右键空气为 use 方法(MCP 和 Mojang Mapping),右键方块为 useOn 方法(或 yarn 中的 useOnBlock 方法)。BuildData 中没有反混淆这两个方法,不论。

其中 use 方法的返回值,要求提供被使用后的物品堆,很有可能是数量已经消耗后的物品堆。比如 1.18.2 Mojang Mapping 鸡蛋物品:

    public InteractionResultHolder use(Level world, Player entityhuman, InteractionHand enumhand) {
    ...
        if (!entityhuman.getAbilities().instabuild) {
            itemstack.shrink(1);
        }
        return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
    }

也就是说如果玩家不在创造模式下,就令手中的鸡蛋物品堆数量减一,然后将这个物品堆传入 InteractionResultHolder 中。

而 useOn 方法,不要求提供被使用后的物品堆。该方法的返回值只是简单记录了右键成功与否。比如 BlockItem(即方块、物品堆形式共用同一物品的情况):



    @Override
    public InteractionResult useOn(UseOnContext itemactioncontext) {
        InteractionResult enuminteractionresult = this.place(new BlockPlaceContext(itemactioncontext));
        ...
        return enuminteractionresult;
    }

    public InteractionResult place(BlockPlaceContext blockactioncontext) {
        ...
        if (!(entityhuman != null && entityhuman.getAbilities().instabuild || itemstack == ItemStack.EMPTY)) {
            itemstack.shrink(1);
        }
        return InteractionResult.sidedSuccess(world.isClientSide);
    }

换句话说,这两个方法其实都会在方法体中处理好物品堆数量的问题(或者 NBT 更改,考虑斧子给原木削皮等消耗耐久度的情况),为什么一个需要返回物品堆,一个不需要返回物品堆呢?InteractionResultHolder 和 InteractionResult 为什么不合并?