/* * 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; } }