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?