171 lines
8.2 KiB
Java
171 lines
8.2 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.world.item;
|
|
|
|
import net.minecraft.advancements.CriteriaTriggers;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.stats.Stats;
|
|
import net.minecraft.tags.FluidTags;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.attribute.EnvironmentAttributes;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.DispensibleContainerItem;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.ItemUtils;
|
|
import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.level.ClipContext;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.BucketPickup;
|
|
import net.minecraft.world.level.block.LiquidBlockContainer;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.gameevent.GameEvent;
|
|
import net.minecraft.world.level.material.FlowingFluid;
|
|
import net.minecraft.world.level.material.Fluid;
|
|
import net.minecraft.world.level.material.Fluids;
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
import net.minecraft.world.phys.HitResult;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public class BucketItem
|
|
extends Item
|
|
implements DispensibleContainerItem {
|
|
private final Fluid content;
|
|
|
|
public BucketItem(Fluid content, Item.Properties properties) {
|
|
super(properties);
|
|
this.content = content;
|
|
}
|
|
|
|
@Override
|
|
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
|
ItemStack itemStack = player.getItemInHand(hand);
|
|
BlockHitResult hitResult = BucketItem.getPlayerPOVHitResult(level, player, this.content == Fluids.EMPTY ? ClipContext.Fluid.SOURCE_ONLY : ClipContext.Fluid.NONE);
|
|
if (hitResult.getType() == HitResult.Type.MISS) {
|
|
return InteractionResult.PASS;
|
|
}
|
|
if (hitResult.getType() == HitResult.Type.BLOCK) {
|
|
BlockPos placePos;
|
|
BlockPos pos = hitResult.getBlockPos();
|
|
Direction direction = hitResult.getDirection();
|
|
BlockPos directionOffsetPos = pos.relative(direction);
|
|
if (!level.mayInteract(player, pos) || !player.mayUseItemAt(directionOffsetPos, direction, itemStack)) {
|
|
return InteractionResult.FAIL;
|
|
}
|
|
if (this.content == Fluids.EMPTY) {
|
|
BucketPickup bucketPickupBlock;
|
|
ItemStack taken;
|
|
BlockState blockState = level.getBlockState(pos);
|
|
Block block = blockState.getBlock();
|
|
if (block instanceof BucketPickup && !(taken = (bucketPickupBlock = (BucketPickup)((Object)block)).pickupBlock(player, level, pos, blockState)).isEmpty()) {
|
|
player.awardStat(Stats.ITEM_USED.get(this));
|
|
bucketPickupBlock.getPickupSound().ifPresent(soundEvent -> player.playSound((SoundEvent)soundEvent, 1.0f, 1.0f));
|
|
level.gameEvent((Entity)player, GameEvent.FLUID_PICKUP, pos);
|
|
ItemStack result = ItemUtils.createFilledResult(itemStack, player, taken);
|
|
if (!level.isClientSide()) {
|
|
CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer)player, taken);
|
|
}
|
|
return InteractionResult.SUCCESS.heldItemTransformedTo(result);
|
|
}
|
|
return InteractionResult.FAIL;
|
|
}
|
|
BlockState clicked = level.getBlockState(pos);
|
|
BlockPos blockPos = placePos = clicked.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? pos : directionOffsetPos;
|
|
if (this.emptyContents(player, level, placePos, hitResult)) {
|
|
this.checkExtraContent(player, level, itemStack, placePos);
|
|
if (player instanceof ServerPlayer) {
|
|
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, placePos, itemStack);
|
|
}
|
|
player.awardStat(Stats.ITEM_USED.get(this));
|
|
ItemStack emptyResult = ItemUtils.createFilledResult(itemStack, player, BucketItem.getEmptySuccessItem(itemStack, player));
|
|
return InteractionResult.SUCCESS.heldItemTransformedTo(emptyResult);
|
|
}
|
|
return InteractionResult.FAIL;
|
|
}
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
public static ItemStack getEmptySuccessItem(ItemStack itemStack, Player player) {
|
|
if (!player.hasInfiniteMaterials()) {
|
|
return new ItemStack(Items.BUCKET);
|
|
}
|
|
return itemStack;
|
|
}
|
|
|
|
@Override
|
|
public void checkExtraContent(@Nullable LivingEntity user, Level level, ItemStack itemStack, BlockPos pos) {
|
|
}
|
|
|
|
@Override
|
|
public boolean emptyContents(@Nullable LivingEntity user, Level level, BlockPos pos, @Nullable BlockHitResult hitResult) {
|
|
boolean canPlaceFluidInsideBlock;
|
|
LiquidBlockContainer container;
|
|
Fluid fluid = this.content;
|
|
if (!(fluid instanceof FlowingFluid)) {
|
|
return false;
|
|
}
|
|
FlowingFluid flowingFluid = (FlowingFluid)fluid;
|
|
BlockState blockState = level.getBlockState(pos);
|
|
Block block = blockState.getBlock();
|
|
boolean mayReplace = blockState.canBeReplaced(this.content);
|
|
boolean shiftKeyDown = user != null && user.isShiftKeyDown();
|
|
boolean placeLiquid = mayReplace || block instanceof LiquidBlockContainer && (container = (LiquidBlockContainer)((Object)block)).canPlaceLiquid(user, level, pos, blockState, this.content);
|
|
boolean bl = canPlaceFluidInsideBlock = blockState.isAir() || placeLiquid && (!shiftKeyDown || hitResult == null);
|
|
if (!canPlaceFluidInsideBlock) {
|
|
return hitResult != null && this.emptyContents(user, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null);
|
|
}
|
|
if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos).booleanValue() && this.content.is(FluidTags.WATER)) {
|
|
int x = pos.getX();
|
|
int y = pos.getY();
|
|
int z = pos.getZ();
|
|
level.playSound((Entity)user, pos, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5f, 2.6f + (level.random.nextFloat() - level.random.nextFloat()) * 0.8f);
|
|
for (int i = 0; i < 8; ++i) {
|
|
level.addParticle(ParticleTypes.LARGE_SMOKE, (double)x + Math.random(), (double)y + Math.random(), (double)z + Math.random(), 0.0, 0.0, 0.0);
|
|
}
|
|
return true;
|
|
}
|
|
if (block instanceof LiquidBlockContainer) {
|
|
LiquidBlockContainer container2 = (LiquidBlockContainer)((Object)block);
|
|
if (this.content == Fluids.WATER) {
|
|
container2.placeLiquid(level, pos, blockState, flowingFluid.getSource(false));
|
|
this.playEmptySound(user, level, pos);
|
|
return true;
|
|
}
|
|
}
|
|
if (!level.isClientSide() && mayReplace && !blockState.liquid()) {
|
|
level.destroyBlock(pos, true);
|
|
}
|
|
if (level.setBlock(pos, this.content.defaultFluidState().createLegacyBlock(), 11) || blockState.getFluidState().isSource()) {
|
|
this.playEmptySound(user, level, pos);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected void playEmptySound(@Nullable LivingEntity user, LevelAccessor level, BlockPos pos) {
|
|
SoundEvent soundEvent = this.content.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
|
|
level.playSound(user, pos, soundEvent, SoundSource.BLOCKS, 1.0f, 1.0f);
|
|
level.gameEvent((Entity)user, GameEvent.FLUID_PLACE, pos);
|
|
}
|
|
|
|
public Fluid getContent() {
|
|
return this.content;
|
|
}
|
|
}
|
|
|