2301_76275164 2025-08-03 12:39 采纳率: 83.3%
浏览 8

问题:无法转换对应目标


package com.GaoHY.GaoHY_mod.handlers;

import com.GaoHY.GaoHY_mod.Init.ItemInit;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionResult;
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.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.minecraft.world.level.material.Fluids;
import org.jetbrains.annotations.NotNull;

public class MachineItem extends Item {
    private static final Logger LOGGER = LogManager.getLogger();
    private static final int MAX_RAYTRACE_DISTANCE = 5;

    public MachineItem(Properties properties) {
        super(properties.durability(1).defaultDurability(1));
    }

    @Override
    public @NotNull InteractionResult useOn(UseOnContext context) {
        Level level = context.getLevel();
        Player player = context.getPlayer();

        // 基础检查
        if (!validateUsageConditions(context, player, level)) {
            return InteractionResult.PASS;
        }

        BlockHitResult hitResult = getPreciseHitResult(player);
        BlockPos pos = hitResult.getBlockPos();

        // 尝试流体转化
        InteractionResult fluidResult = tryFluidConversion(context, level, player, pos);
        if (fluidResult != InteractionResult.PASS) {
            return fluidResult;
        }

        // 尝试方块转化
        return tryBlockConversion(context, level, player, pos, hitResult);
    }

    // 验证使用条件
    private boolean validateUsageConditions(UseOnContext context, Player player, Level level) {
        if (player == null || level.isClientSide()) {
            return false;
        }

        ItemStack machineStack = context.getItemInHand();
        if (!machineStack.is(ItemInit.MACHINE.get()) ||
                machineStack.getDamageValue() >= machineStack.getMaxDamage()) {
            return false;
        }

        if (!hasEyeItem(player)) {
            player.displayClientMessage(Component.literal("你需要神之眼的框架!"), true);
            return false;
        }

        return true;
    }

    // 检查是否有神之眼框架
    private boolean hasEyeItem(Player player) {
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            if (player.getInventory().getItem(i).is(ItemInit.EYE.get())) {
                return true;
            }
        }
        return false;
    }

    // 尝试流体转化
    private InteractionResult tryFluidConversion(UseOnContext context, Level level, Player player, BlockPos pos) {
        FluidState fluidState = level.getFluidState(pos);

        if (fluidState.getType().isSame(Fluids.WATER) && fluidState.isSource()) {
            return convertEye(context, level, player, pos,
                    ItemInit.WATER_GOD_EYE.get(),
                    SoundEvents.AMBIENT_UNDERWATER_ENTER,
                    Blocks.WATER.defaultBlockState());
        }

        if (fluidState.getType().isSame(Fluids.LAVA) && fluidState.isSource()) {
            return convertEye(context, level, player, pos,
                    ItemInit.FIRE_GOD_EYE.get(),
                    SoundEvents.FISH_SWIM,
                    Blocks.LAVA.defaultBlockState());
        }

        return InteractionResult.PASS;
    }

    // 尝试方块转化
    private InteractionResult tryBlockConversion(UseOnContext context, Level level, Player player,
                                                 BlockPos pos, BlockHitResult hitResult) {
        BlockState blockState = level.getBlockState(pos);

        if (blockState.is(Blocks.ICE)) {
            return convertEye(context, level, player, pos,
                    ItemInit.SNOW_GOD_EYE.get(),
                    SoundEvents.GLASS_BREAK,
                    Blocks.ICE.defaultBlockState());
        }

        if (blockState.is(Blocks.GRASS_BLOCK)) {
            return convertEye(context, level, player, pos,
                    ItemInit.GRASS_GOD_EYE.get(),
                    SoundEvents.GRASS_FALL,
                    Blocks.GRASS_BLOCK.defaultBlockState());
        }

        if (blockState.is(Blocks.STONE)) {
            return convertEye(context, level, player, pos,
                    ItemInit.STONE_GOD_EYE.get(),
                    SoundEvents.STONE_FALL,
                    Blocks.STONE.defaultBlockState());
        }

        if (blockState.is(Blocks.LIGHTNING_ROD)) {
            return convertEye(context, level, player, pos,
                    ItemInit.THUNDER_GOD_EYE.get(),
                    SoundEvents.LIGHTNING_BOLT_THUNDER,
                    Blocks.COPPER_BLOCK.defaultBlockState());
        }

        if (hitResult.getType() == HitResult.Type.MISS) {
            return convertEye(context, level, player, pos,
                    ItemInit.WIND_GOD_EYE.get(),
                    SoundEvents.ELYTRA_FLYING,
                    Blocks.AIR.defaultBlockState());
        }

        return InteractionResult.PASS;
    }

    // 通用转化方法
    private InteractionResult convertEye(UseOnContext context, Level level, Player player, BlockPos pos,
                                         Item resultItem, SoundEvent sound, BlockState particleBlock) {
        // 消耗eye物品
        consumeEyeItem(player);

        // 给予结果物品
        giveResultItem(player, new ItemStack(resultItem));

        // 消耗machine
        context.getItemInHand().hurtAndBreak(1, player,
                p -> p.broadcastBreakEvent(context.getHand()));

        // 播放效果
        playConversionEffects(level, pos, sound, particleBlock);

        return InteractionResult.SUCCESS;
    }

    // 消耗eye物品
    private void consumeEyeItem(Player player) {
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            ItemStack stack = player.getInventory().getItem(i);
            if (stack.is(ItemInit.EYE.get())) {
                stack.shrink(1);
                if (stack.isEmpty()) {
                    player.getInventory().setItem(i, ItemStack.EMPTY);
                }
                break;
            }
        }
    }

    // 给予结果物品
    private void giveResultItem(Player player, ItemStack resultStack) {
        if (!player.getInventory().add(resultStack)) {
            player.drop(resultStack, false);
        }
    }

    // 播放转化效果
    private void playConversionEffects(Level level, BlockPos pos, SoundEvent sound, BlockState particleBlock) {
        level.playSound(null, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F);
        level.levelEvent(2001, pos, net.minecraft.world.level.block.Block.getId(particleBlock));
    }

    private BlockHitResult getPreciseHitResult(Player player) {
        return (BlockHitResult) player.pick(MAX_RAYTRACE_DISTANCE, 1.0F, true);
    }

    @Override
    public boolean isRepairable(@NotNull ItemStack stack) {
        return false;
    }
}

为什么这里其他方块都能成功转换,选择目标为miss时无法转换为wind_god_eye?

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-08-03 12:40
    关注

    中午好🌞🌞🌞
    本答案参考通义千问

    你提供的代码片段在 tryBlockConversion 方法中出现了不完整的情况,特别是最后一行:

    return convertEye(context, leve
    

    这显然是一个语法错误或拼写错误。问题出在 level 拼写错误为 leve,导致编译失败。


    问题分析

    1. 语法错误:convertEye(context, leve...) 中,levelevel 的拼写错误。
    2. 逻辑完整性: 由于代码未完成,无法判断是否还有其他潜在的逻辑错误。
    3. 依赖检查: 需要确保 ItemInit.EYE.get()ItemInit.MACHINE.get() 等引用正确无误。
    4. 方法调用一致性: convertEye(...) 方法需要有完整的定义,否则会导致编译错误。

    解决方案

    以下是修复和优化该代码的步骤:

    1. 修正拼写错误

    leve 改为 level

    2. 补全方法

    确保 tryBlockConversion 方法完整,并且 convertEye 方法存在。

    3. 添加日志与调试信息(可选)

    帮助开发者追踪问题。


    修改后的完整代码示例

    private InteractionResult tryBlockConversion(UseOnContext context, Level level, Player player,
                                                 BlockPos pos, BlockHitResult hitResult) {
        BlockState blockState = level.getBlockState(pos);
    
        if (blockState.is(Blocks.ICE)) {
            return convertEye(context, level, player, pos,
                    ItemInit.ICE_GOD_EYE.get(),
                    SoundEvents.AMBIENT_UNDERWATER_ENTER,
                    Blocks.ICE.defaultBlockState());
        }
    
        // 可以继续添加其他块的转换逻辑
        // 例如:
        // if (blockState.is(Blocks.DIRT)) { ... }
    
        return InteractionResult.PASS;
    }
    

    补充说明

    • convertEye 方法需实现:请确保你已经实现了 convertEye 方法,如下所示:
    private InteractionResult convertEye(UseOnContext context, Level level, Player player, BlockPos pos,
                                         Item eyeItem, SoundEvent soundEvent, net.minecraft.world.level.block.state.BlockState replaceState) {
        // 检查玩家是否有足够的物品
        if (!player.getInventory().removeItem(ItemInit.EYE.get(), 1)) {
            player.displayClientMessage(Component.literal("缺少神之眼框架!"), true);
            return InteractionResult.FAIL;
        }
    
        // 播放音效
        level.playSound(null, pos, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F);
    
        // 替换方块
        level.setBlock(pos, replaceState);
    
        // 减少机器耐久
        ItemStack machineStack = context.getItemInHand();
        machineStack.hurtAndBreak(1, player, (p) -> p.broadcastBreakEvent(context.getHand()));
    
        return InteractionResult.SUCCESS;
    }
    

    总结

    | 步骤 | 说明 | |------|------| | 1 | 修正拼写错误:将 leve 改为 level | | 2 | 补全方法:确保 tryBlockConversion 完整 | | 3 | 实现 convertEye 方法:用于处理实际的转化逻辑 | | 4 | 添加日志/调试信息(可选):便于排查问题 |


    如果你能提供完整的 convertEye 方法或更多上下文,我可以进一步帮助你完善代码逻辑。

    评论

报告相同问题?

问题事件

  • 创建了问题 8月3日