minecraft-src/net/minecraft/world/item/HoeItem.java
2025-07-04 03:45:38 +03:00

92 lines
3.9 KiB
Java

package net.minecraft.world.item;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.mojang.datafixers.util.Pair;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.GameEvent.Context;
public class HoeItem extends Item {
protected static final Map<Block, Pair<Predicate<UseOnContext>, Consumer<UseOnContext>>> TILLABLES = Maps.<Block, Pair<Predicate<UseOnContext>, Consumer<UseOnContext>>>newHashMap(
ImmutableMap.of(
Blocks.GRASS_BLOCK,
Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.FARMLAND.defaultBlockState())),
Blocks.DIRT_PATH,
Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.FARMLAND.defaultBlockState())),
Blocks.DIRT,
Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.FARMLAND.defaultBlockState())),
Blocks.COARSE_DIRT,
Pair.of(HoeItem::onlyIfAirAbove, changeIntoState(Blocks.DIRT.defaultBlockState())),
Blocks.ROOTED_DIRT,
Pair.of(useOnContext -> true, changeIntoStateAndDropItem(Blocks.DIRT.defaultBlockState(), Items.HANGING_ROOTS))
)
);
public HoeItem(ToolMaterial material, float attackDamage, float attackSpeed, Item.Properties properties) {
super(properties.hoe(material, attackDamage, attackSpeed));
}
@Override
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
BlockPos blockPos = context.getClickedPos();
Pair<Predicate<UseOnContext>, Consumer<UseOnContext>> pair = (Pair<Predicate<UseOnContext>, Consumer<UseOnContext>>)TILLABLES.get(
level.getBlockState(blockPos).getBlock()
);
if (pair == null) {
return InteractionResult.PASS;
} else {
Predicate<UseOnContext> predicate = pair.getFirst();
Consumer<UseOnContext> consumer = pair.getSecond();
if (predicate.test(context)) {
Player player = context.getPlayer();
level.playSound(player, blockPos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F);
if (!level.isClientSide) {
consumer.accept(context);
if (player != null) {
context.getItemInHand().hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand()));
}
}
return InteractionResult.SUCCESS;
} else {
return InteractionResult.PASS;
}
}
}
public static Consumer<UseOnContext> changeIntoState(BlockState state) {
return useOnContext -> {
useOnContext.getLevel().setBlock(useOnContext.getClickedPos(), state, 11);
useOnContext.getLevel().gameEvent(GameEvent.BLOCK_CHANGE, useOnContext.getClickedPos(), Context.of(useOnContext.getPlayer(), state));
};
}
public static Consumer<UseOnContext> changeIntoStateAndDropItem(BlockState state, ItemLike itemToDrop) {
return useOnContext -> {
useOnContext.getLevel().setBlock(useOnContext.getClickedPos(), state, 11);
useOnContext.getLevel().gameEvent(GameEvent.BLOCK_CHANGE, useOnContext.getClickedPos(), Context.of(useOnContext.getPlayer(), state));
Block.popResourceFromFace(useOnContext.getLevel(), useOnContext.getClickedPos(), useOnContext.getClickedFace(), new ItemStack(itemToDrop));
};
}
public static boolean onlyIfAirAbove(UseOnContext context) {
return context.getClickedFace() != Direction.DOWN && context.getLevel().getBlockState(context.getClickedPos().above()).isAir();
}
}