From fa792cf719c1ebb5ce21d3315a1863aade43220a Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:21:16 -0500 Subject: [PATCH] /net/minecraft/core/cauldron/CauldronInteraction --- .../cauldron/CauldronInteraction.java.patch | 302 ++++++++++++++++ .../cauldron/CauldronInteraction.java.patch | 330 ------------------ 2 files changed, 302 insertions(+), 330 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/core/cauldron/CauldronInteraction.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/core/cauldron/CauldronInteraction.java.patch diff --git a/paper-server/patches/sources/net/minecraft/core/cauldron/CauldronInteraction.java.patch b/paper-server/patches/sources/net/minecraft/core/cauldron/CauldronInteraction.java.patch new file mode 100644 index 0000000000..ddd596f865 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/core/cauldron/CauldronInteraction.java.patch @@ -0,0 +1,302 @@ +--- a/net/minecraft/core/cauldron/CauldronInteraction.java ++++ b/net/minecraft/core/cauldron/CauldronInteraction.java +@@ -42,26 +_,31 @@ + + static CauldronInteraction.InteractionMap newInteractionMap(String name) { + Object2ObjectOpenHashMap map = new Object2ObjectOpenHashMap<>(); +- map.defaultReturnValue((state, level, pos, player, hand, stack) -> InteractionResult.TRY_WITH_EMPTY_HAND); ++ map.defaultReturnValue((state, level, pos, player, hand, stack, hitDirection) -> InteractionResult.TRY_WITH_EMPTY_HAND); // Paper - add hitDirection + CauldronInteraction.InteractionMap interactionMap = new CauldronInteraction.InteractionMap(name, map); + INTERACTIONS.put(name, interactionMap); + return interactionMap; + } + +- InteractionResult interact(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack); ++ InteractionResult interact(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection); // Paper - add hitDirection + + static void bootStrap() { + Map map = EMPTY.map(); + addDefaultInteractions(map); +- map.put(Items.POTION, (state, level, pos, player, hand, stack) -> { ++ map.put(Items.POTION, (state, level, pos, player, hand, stack, hitDirection) -> { // Paper - add hitDirection + PotionContents potionContents = stack.get(DataComponents.POTION_CONTENTS); + if (potionContents != null && potionContents.is(Potions.WATER)) { + if (!level.isClientSide) { ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, Blocks.WATER_CAULDRON.defaultBlockState(), player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + Item item = stack.getItem(); + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE))); + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(item)); +- level.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState()); ++ // world.setBlockAndUpdate(blockposition, Blocks.WATER_CAULDRON.defaultBlockState()); // CraftBukkit + level.playSound(null, pos, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); + level.gameEvent(null, GameEvent.FLUID_PLACE, pos); + } +@@ -75,7 +_,7 @@ + addDefaultInteractions(map1); + map1.put( + Items.BUCKET, +- (state, level, pos, player, hand, stack) -> fillBucket( ++ (state, level, pos, player, hand, stack, hitDirection) -> fillBucket( // Paper - add hitDirection + state, + level, + pos, +@@ -84,33 +_,44 @@ + stack, + new ItemStack(Items.WATER_BUCKET), + blockState -> blockState.getValue(LayeredCauldronBlock.LEVEL) == 3, +- SoundEvents.BUCKET_FILL ++ SoundEvents.BUCKET_FILL, ++ hitDirection + ) + ); +- map1.put(Items.GLASS_BOTTLE, (state, level, pos, player, hand, stack) -> { ++ map1.put(Items.GLASS_BOTTLE, (state, level, pos, player, hand, stack, hitDirection) -> { // Paper - add hitDirection + if (!level.isClientSide) { ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.lowerFillLevel(state, level, pos, player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.BOTTLE_FILL)) { ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + Item item = stack.getItem(); + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, PotionContents.createItemStack(Items.POTION, Potions.WATER))); + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(item)); +- LayeredCauldronBlock.lowerFillLevel(state, level, pos); ++ // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit + level.playSound(null, pos, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS, 1.0F, 1.0F); + level.gameEvent(null, GameEvent.FLUID_PICKUP, pos); + } + + return InteractionResult.SUCCESS; + }); +- map1.put(Items.POTION, (state, level, pos, player, hand, stack) -> { ++ map1.put(Items.POTION, (state, level, pos, player, hand, stack, hitDirection) -> { // Paper - add hitDirection + if (state.getValue(LayeredCauldronBlock.LEVEL) == 3) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else { + PotionContents potionContents = stack.get(DataComponents.POTION_CONTENTS); + if (potionContents != null && potionContents.is(Potions.WATER)) { + if (!level.isClientSide) { ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, state.cycle(LayeredCauldronBlock.LEVEL), player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE))); + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(stack.getItem())); +- level.setBlockAndUpdate(pos, state.cycle(LayeredCauldronBlock.LEVEL)); ++ // level.setBlockAndUpdate(pos, state.cycle(LayeredCauldronBlock.LEVEL)); // CraftBukkit + level.playSound(null, pos, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); + level.gameEvent(null, GameEvent.FLUID_PLACE, pos); + } +@@ -162,15 +_,15 @@ + Map map2 = LAVA.map(); + map2.put( + Items.BUCKET, +- (state, level, pos, player, hand, stack) -> fillBucket( +- state, level, pos, player, hand, stack, new ItemStack(Items.LAVA_BUCKET), blockState -> true, SoundEvents.BUCKET_FILL_LAVA ++ (state, level, pos, player, hand, stack, hitDirection) -> fillBucket( // Paper - add hitDirection ++ state, level, pos, player, hand, stack, new ItemStack(Items.LAVA_BUCKET), blockState -> true, SoundEvents.BUCKET_FILL_LAVA, hitDirection // Paper - add hitDirection + ) + ); + addDefaultInteractions(map2); + Map map3 = POWDER_SNOW.map(); + map3.put( + Items.BUCKET, +- (state, level, pos, player, hand, stack) -> fillBucket( ++ (state, level, pos, player, hand, stack, hitDirection) -> fillBucket( // Paper - add hitDirection + state, + level, + pos, +@@ -179,7 +_,7 @@ + stack, + new ItemStack(Items.POWDER_SNOW_BUCKET), + blockState -> blockState.getValue(LayeredCauldronBlock.LEVEL) == 3, +- SoundEvents.BUCKET_FILL_POWDER_SNOW ++ SoundEvents.BUCKET_FILL_POWDER_SNOW, hitDirection // Paper - add hitDirection + ) + ); + addDefaultInteractions(map3); +@@ -202,15 +_,34 @@ + Predicate statePredicate, + SoundEvent fillSound + ) { ++ // Paper start - add hitDirection ++ return fillBucket(state, level, pos, player, hand, emptyStack, filledStack, statePredicate, fillSound, null); // Paper - add hitDirection ++ } ++ static InteractionResult fillBucket(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack emptyStack, ItemStack filledStack, Predicate statePredicate, SoundEvent fillSound, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { ++ // Paper end - add hitDirection + if (!statePredicate.test(state)) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else { + if (!level.isClientSide) { ++ // Paper start - fire PlayerBucketFillEvent ++ if (hitDirection != null) { ++ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((net.minecraft.server.level.ServerLevel) level, player, pos, pos, hitDirection, emptyStack, filledStack.getItem(), hand); ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ filledStack = event.getItemStack() != null ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; ++ } ++ // Paper end - fire PlayerBucketFillEvent ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, Blocks.CAULDRON.defaultBlockState(), player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL, false)) { // Paper - Call CauldronLevelChangeEvent ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + Item item = emptyStack.getItem(); + player.setItemInHand(hand, ItemUtils.createFilledResult(emptyStack, player, filledStack)); + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(item)); +- level.setBlockAndUpdate(pos, Blocks.CAULDRON.defaultBlockState()); ++ // level.setBlockAndUpdate(pos, Blocks.CAULDRON.defaultBlockState()); // CraftBukkit + level.playSound(null, pos, fillSound, SoundSource.BLOCKS, 1.0F, 1.0F); + level.gameEvent(null, GameEvent.FLUID_PICKUP, pos); + } +@@ -222,12 +_,32 @@ + static InteractionResult emptyBucket( + Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStackl, BlockState state, SoundEvent emptySound + ) { ++ // Paper start - add hitDirection ++ return emptyBucket(level, pos, player, hand, filledStackl, state, emptySound, null); ++ } ++ static InteractionResult emptyBucket(Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStackl, BlockState state, SoundEvent emptySound, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { ++ // Paper end - add hitDirection + if (!level.isClientSide) { ++ // Paper start - fire PlayerBucketEmptyEvent ++ ItemStack output = new ItemStack(Items.BUCKET); ++ if (hitDirection != null) { ++ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent((net.minecraft.server.level.ServerLevel) level, player, pos, pos, hitDirection, filledStackl, hand); ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ output = event.getItemStack() != null ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; ++ } ++ // Paper end - fire PlayerBucketEmptyEvent ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, state, player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + Item item = filledStackl.getItem(); +- player.setItemInHand(hand, ItemUtils.createFilledResult(filledStackl, player, new ItemStack(Items.BUCKET))); ++ player.setItemInHand(hand, ItemUtils.createFilledResult(filledStackl, player, output)); // Paper + player.awardStat(Stats.FILL_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(item)); +- level.setBlockAndUpdate(pos, state); ++ // level.setBlockAndUpdate(pos, state); // CraftBukkit + level.playSound(null, pos, emptySound, SoundSource.BLOCKS, 1.0F, 1.0F); + level.gameEvent(null, GameEvent.FLUID_PLACE, pos); + } +@@ -236,7 +_,7 @@ + } + + private static InteractionResult fillWaterInteraction( +- BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack ++ BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack, final net.minecraft.core.Direction hitDirection // Paper - add hitDirection + ) { + return emptyBucket( + level, +@@ -245,20 +_,20 @@ + hand, + filledStack, + Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, Integer.valueOf(3)), +- SoundEvents.BUCKET_EMPTY ++ SoundEvents.BUCKET_EMPTY, hitDirection // Paper - add hitDirection + ); + } + + private static InteractionResult fillLavaInteraction( +- BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack ++ BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack, final net.minecraft.core.Direction hitDirection // Paper - add hitDirection + ) { + return (InteractionResult)(isUnderWater(level, pos) + ? InteractionResult.CONSUME +- : emptyBucket(level, pos, player, hand, filledStack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA)); ++ : emptyBucket(level, pos, player, hand, filledStack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA, hitDirection)); // Paper - add hitDirection + } + + private static InteractionResult fillPowderSnowInteraction( +- BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack ++ BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack, final net.minecraft.core.Direction hitDirection // Paper - add hitDirection + ) { + return (InteractionResult)(isUnderWater(level, pos) + ? InteractionResult.CONSUME +@@ -269,50 +_,65 @@ + hand, + filledStack, + Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, Integer.valueOf(3)), +- SoundEvents.BUCKET_EMPTY_POWDER_SNOW ++ SoundEvents.BUCKET_EMPTY_POWDER_SNOW, hitDirection // Paper - add hitDirection + )); + } + +- private static InteractionResult shulkerBoxInteraction(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { ++ private static InteractionResult shulkerBoxInteraction(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection + Block block = Block.byItem(stack.getItem()); + if (!(block instanceof ShulkerBoxBlock)) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else { + if (!level.isClientSide) { ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.lowerFillLevel(state, level, pos, player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.SHULKER_WASH)) { ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + ItemStack itemStack = stack.transmuteCopy(Blocks.SHULKER_BOX, 1); + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, itemStack, false)); + player.awardStat(Stats.CLEAN_SHULKER_BOX); +- LayeredCauldronBlock.lowerFillLevel(state, level, pos); ++ // LayeredCauldronBlock.lowerFillLevel(state, level, pos); // CraftBukkit + } + + return InteractionResult.SUCCESS; + } + } + +- private static InteractionResult bannerInteraction(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { ++ private static InteractionResult bannerInteraction(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection + BannerPatternLayers bannerPatternLayers = stack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY); + if (bannerPatternLayers.layers().isEmpty()) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else { + if (!level.isClientSide) { ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.lowerFillLevel(state, level, pos, player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.BANNER_WASH)) { ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + ItemStack itemStack = stack.copyWithCount(1); + itemStack.set(DataComponents.BANNER_PATTERNS, bannerPatternLayers.removeLast()); + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, itemStack, false)); + player.awardStat(Stats.CLEAN_BANNER); +- LayeredCauldronBlock.lowerFillLevel(state, level, pos); ++ // LayeredCauldronBlock.lowerFillLevel(state, level, pos); // CraftBukkit + } + + return InteractionResult.SUCCESS; + } + } + +- private static InteractionResult dyedItemIteration(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { ++ private static InteractionResult dyedItemIteration(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection + if (!stack.is(ItemTags.DYEABLE)) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else if (!stack.has(DataComponents.DYED_COLOR)) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else { + if (!level.isClientSide) { ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.lowerFillLevel(state, level, pos, player, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.ARMOR_WASH)) { ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + stack.remove(DataComponents.DYED_COLOR); + player.awardStat(Stats.CLEAN_ARMOR); + LayeredCauldronBlock.lowerFillLevel(state, level, pos); diff --git a/paper-server/patches/unapplied/net/minecraft/core/cauldron/CauldronInteraction.java.patch b/paper-server/patches/unapplied/net/minecraft/core/cauldron/CauldronInteraction.java.patch deleted file mode 100644 index f0db760867..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/core/cauldron/CauldronInteraction.java.patch +++ /dev/null @@ -1,330 +0,0 @@ ---- a/net/minecraft/core/cauldron/CauldronInteraction.java -+++ b/net/minecraft/core/cauldron/CauldronInteraction.java -@@ -35,20 +35,25 @@ - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.material.FluidState; -+// CraftBukkit start -+import org.bukkit.event.block.CauldronLevelChangeEvent; -+// CraftBukkit end - - public interface CauldronInteraction { - - Map INTERACTIONS = new Object2ObjectArrayMap(); -- Codec CODEC; -- CauldronInteraction.InteractionMap EMPTY; -- CauldronInteraction.InteractionMap WATER; -- CauldronInteraction.InteractionMap LAVA; -- CauldronInteraction.InteractionMap POWDER_SNOW; -+ // CraftBukkit start - decompile errors -+ Codec CODEC = Codec.stringResolver(CauldronInteraction.InteractionMap::name, CauldronInteraction.INTERACTIONS::get); -+ CauldronInteraction.InteractionMap EMPTY = CauldronInteraction.newInteractionMap("empty"); -+ CauldronInteraction.InteractionMap WATER = CauldronInteraction.newInteractionMap("water"); -+ CauldronInteraction.InteractionMap LAVA = CauldronInteraction.newInteractionMap("lava"); -+ CauldronInteraction.InteractionMap POWDER_SNOW = CauldronInteraction.newInteractionMap("powder_snow"); -+ // CraftBukkit end - - static CauldronInteraction.InteractionMap newInteractionMap(String name) { - Object2ObjectOpenHashMap object2objectopenhashmap = new Object2ObjectOpenHashMap(); - -- object2objectopenhashmap.defaultReturnValue((iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ object2objectopenhashmap.defaultReturnValue((iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - return InteractionResult.TRY_WITH_EMPTY_HAND; - }); - CauldronInteraction.InteractionMap cauldroninteraction_a = new CauldronInteraction.InteractionMap(name, object2objectopenhashmap); -@@ -57,23 +62,28 @@ - return cauldroninteraction_a; - } - -- InteractionResult interact(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack); -+ InteractionResult interact(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection); // Paper - add hitDirection - - static void bootStrap() { - Map map = CauldronInteraction.EMPTY.map(); - - CauldronInteraction.addDefaultInteractions(map); -- map.put(Items.POTION, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ map.put(Items.POTION, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - PotionContents potioncontents = (PotionContents) itemstack.get(DataComponents.POTION_CONTENTS); - - if (potioncontents != null && potioncontents.is(Potions.WATER)) { - if (!world.isClientSide) { -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - Item item = itemstack.getItem(); - - entityhuman.setItemInHand(enumhand, ItemUtils.createFilledResult(itemstack, entityhuman, new ItemStack(Items.GLASS_BOTTLE))); - entityhuman.awardStat(Stats.USE_CAULDRON); - entityhuman.awardStat(Stats.ITEM_USED.get(item)); -- world.setBlockAndUpdate(blockposition, Blocks.WATER_CAULDRON.defaultBlockState()); -+ // world.setBlockAndUpdate(blockposition, Blocks.WATER_CAULDRON.defaultBlockState()); // CraftBukkit - world.playSound((Player) null, blockposition, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); - world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PLACE, blockposition); - } -@@ -86,26 +96,31 @@ - Map map1 = CauldronInteraction.WATER.map(); - - CauldronInteraction.addDefaultInteractions(map1); -- map1.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ map1.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - return CauldronInteraction.fillBucket(iblockdata, world, blockposition, entityhuman, enumhand, itemstack, new ItemStack(Items.WATER_BUCKET), (iblockdata1) -> { - return (Integer) iblockdata1.getValue(LayeredCauldronBlock.LEVEL) == 3; -- }, SoundEvents.BUCKET_FILL); -+ }, SoundEvents.BUCKET_FILL, hitDirection); // Paper - add hitDirection - }); -- map1.put(Items.GLASS_BOTTLE, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ map1.put(Items.GLASS_BOTTLE, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - if (!world.isClientSide) { -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_FILL)) { -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - Item item = itemstack.getItem(); - - entityhuman.setItemInHand(enumhand, ItemUtils.createFilledResult(itemstack, entityhuman, PotionContents.createItemStack(Items.POTION, Potions.WATER))); - entityhuman.awardStat(Stats.USE_CAULDRON); - entityhuman.awardStat(Stats.ITEM_USED.get(item)); -- LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); -+ // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit - world.playSound((Player) null, blockposition, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS, 1.0F, 1.0F); - world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PICKUP, blockposition); - } - - return InteractionResult.SUCCESS; - }); -- map1.put(Items.POTION, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ map1.put(Items.POTION, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - if ((Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL) == 3) { - return InteractionResult.TRY_WITH_EMPTY_HAND; - } else { -@@ -113,10 +128,15 @@ - - if (potioncontents != null && potioncontents.is(Potions.WATER)) { - if (!world.isClientSide) { -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - entityhuman.setItemInHand(enumhand, ItemUtils.createFilledResult(itemstack, entityhuman, new ItemStack(Items.GLASS_BOTTLE))); - entityhuman.awardStat(Stats.USE_CAULDRON); - entityhuman.awardStat(Stats.ITEM_USED.get(itemstack.getItem())); -- world.setBlockAndUpdate(blockposition, (BlockState) iblockdata.cycle(LayeredCauldronBlock.LEVEL)); -+ // world.setBlockAndUpdate(blockposition, (IBlockData) iblockdata.cycle(LayeredCauldronBlock.LEVEL)); // CraftBukkit - world.playSound((Player) null, blockposition, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); - world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PLACE, blockposition); - } -@@ -167,18 +187,18 @@ - map1.put(Items.YELLOW_SHULKER_BOX, CauldronInteraction::shulkerBoxInteraction); - Map map2 = CauldronInteraction.LAVA.map(); - -- map2.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ map2.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - return CauldronInteraction.fillBucket(iblockdata, world, blockposition, entityhuman, enumhand, itemstack, new ItemStack(Items.LAVA_BUCKET), (iblockdata1) -> { - return true; -- }, SoundEvents.BUCKET_FILL_LAVA); -+ }, SoundEvents.BUCKET_FILL_LAVA, hitDirection); // Paper - add hitDirection - }); - CauldronInteraction.addDefaultInteractions(map2); - Map map3 = CauldronInteraction.POWDER_SNOW.map(); - -- map3.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ map3.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - return CauldronInteraction.fillBucket(iblockdata, world, blockposition, entityhuman, enumhand, itemstack, new ItemStack(Items.POWDER_SNOW_BUCKET), (iblockdata1) -> { - return (Integer) iblockdata1.getValue(LayeredCauldronBlock.LEVEL) == 3; -- }, SoundEvents.BUCKET_FILL_POWDER_SNOW); -+ }, SoundEvents.BUCKET_FILL_POWDER_SNOW, hitDirection); // Paper - add hitDirection - }); - CauldronInteraction.addDefaultInteractions(map3); - } -@@ -190,16 +210,35 @@ - } - - static InteractionResult fillBucket(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, ItemStack output, Predicate fullPredicate, SoundEvent soundEvent) { -+ // Paper start - add hitDirection -+ return fillBucket(state, world, pos, player, hand, stack, output, fullPredicate, soundEvent, null); // Paper - add hitDirection -+ } -+ static InteractionResult fillBucket(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, ItemStack output, Predicate fullPredicate, SoundEvent soundEvent, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { -+ // Paper end - add hitDirection - if (!fullPredicate.test(state)) { - return InteractionResult.TRY_WITH_EMPTY_HAND; - } else { - if (!world.isClientSide) { -+ // Paper start - fire PlayerBucketFillEvent -+ if (hitDirection != null) { -+ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((net.minecraft.server.level.ServerLevel) world, player, pos, pos, hitDirection, stack, output.getItem(), hand); -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ output = event.getItemStack() != null ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; -+ } -+ // Paper end - fire PlayerBucketFillEvent -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL, false)) { // Paper - Call CauldronLevelChangeEvent -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - Item item = stack.getItem(); - - player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, output)); - player.awardStat(Stats.USE_CAULDRON); - player.awardStat(Stats.ITEM_USED.get(item)); -- world.setBlockAndUpdate(pos, Blocks.CAULDRON.defaultBlockState()); -+ // world.setBlockAndUpdate(blockposition, Blocks.CAULDRON.defaultBlockState()); // CraftBukkit - world.playSound((Player) null, pos, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F); - world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PICKUP, pos); - } -@@ -209,13 +248,33 @@ - } - - static InteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent) { -+ // Paper start - add hitDirection -+ return emptyBucket(world, pos, player, hand, stack, state, soundEvent, null); -+ } -+ static InteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { -+ // Paper end - add hitDirection - if (!world.isClientSide) { -+ // Paper start - fire PlayerBucketEmptyEvent -+ ItemStack output = new ItemStack(Items.BUCKET); -+ if (hitDirection != null) { -+ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent((net.minecraft.server.level.ServerLevel) world, player, pos, pos, hitDirection, stack, hand); -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ output = event.getItemStack() != null ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; -+ } -+ // Paper end - fire PlayerBucketEmptyEvent -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - Item item = stack.getItem(); - -- player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.BUCKET))); -+ player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, output)); // Paper - player.awardStat(Stats.FILL_CAULDRON); - player.awardStat(Stats.ITEM_USED.get(item)); -- world.setBlockAndUpdate(pos, state); -+ // world.setBlockAndUpdate(blockposition, iblockdata); // CraftBukkit - world.playSound((Player) null, pos, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F); - world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PLACE, pos); - } -@@ -223,65 +282,79 @@ - return InteractionResult.SUCCESS; - } - -- private static InteractionResult fillWaterInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { -- return CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY); -+ private static InteractionResult fillWaterInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection -+ return CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY, hitDirection); // Paper - add hitDirection - } - -- private static InteractionResult fillLavaInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { -- return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA)); -+ private static InteractionResult fillLavaInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection -+ return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA, hitDirection)); // Paper - add hitDirection - } - -- private static InteractionResult fillPowderSnowInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { -- return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY_POWDER_SNOW)); -+ private static InteractionResult fillPowderSnowInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection -+ return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY_POWDER_SNOW, hitDirection)); // Paper - add hitDirection - } - -- private static InteractionResult shulkerBoxInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { -+ private static InteractionResult shulkerBoxInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection - Block block = Block.byItem(stack.getItem()); - - if (!(block instanceof ShulkerBoxBlock)) { - return InteractionResult.TRY_WITH_EMPTY_HAND; - } else { - if (!world.isClientSide) { -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.lowerFillLevel(state, world, pos, player, CauldronLevelChangeEvent.ChangeReason.SHULKER_WASH)) { -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - ItemStack itemstack1 = stack.transmuteCopy(Blocks.SHULKER_BOX, 1); - - player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, itemstack1, false)); - player.awardStat(Stats.CLEAN_SHULKER_BOX); -- LayeredCauldronBlock.lowerFillLevel(state, world, pos); -+ // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit - } -- - return InteractionResult.SUCCESS; - } - } - -- private static InteractionResult bannerInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { -+ private static InteractionResult bannerInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection - BannerPatternLayers bannerpatternlayers = (BannerPatternLayers) stack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY); - - if (bannerpatternlayers.layers().isEmpty()) { - return InteractionResult.TRY_WITH_EMPTY_HAND; - } else { - if (!world.isClientSide) { -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.lowerFillLevel(state, world, pos, player, CauldronLevelChangeEvent.ChangeReason.BANNER_WASH)) { -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - ItemStack itemstack1 = stack.copyWithCount(1); - - itemstack1.set(DataComponents.BANNER_PATTERNS, bannerpatternlayers.removeLast()); - player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, itemstack1, false)); - player.awardStat(Stats.CLEAN_BANNER); -- LayeredCauldronBlock.lowerFillLevel(state, world, pos); -+ // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit - } - - return InteractionResult.SUCCESS; - } - } - -- private static InteractionResult dyedItemIteration(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { -+ private static InteractionResult dyedItemIteration(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection - if (!stack.is(ItemTags.DYEABLE)) { - return InteractionResult.TRY_WITH_EMPTY_HAND; - } else if (!stack.has(DataComponents.DYED_COLOR)) { - return InteractionResult.TRY_WITH_EMPTY_HAND; - } else { - if (!world.isClientSide) { -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.lowerFillLevel(state, world, pos, player, CauldronLevelChangeEvent.ChangeReason.ARMOR_WASH)) { -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - stack.remove(DataComponents.DYED_COLOR); - player.awardStat(Stats.CLEAN_ARMOR); -- LayeredCauldronBlock.lowerFillLevel(state, world, pos); -+ // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit - } - - return InteractionResult.SUCCESS; -@@ -294,8 +367,10 @@ - return fluid.is(FluidTags.WATER); - } - -+ // CraftBukkit start - decompile errors -+ /* - static { -- Function function = CauldronInteraction.InteractionMap::name; -+ Function function = CauldronInteraction.a::name; - Map map = CauldronInteraction.INTERACTIONS; - - Objects.requireNonNull(map); -@@ -305,6 +380,8 @@ - LAVA = newInteractionMap("lava"); - POWDER_SNOW = newInteractionMap("powder_snow"); - } -+ */ -+ // CraftBukkit end - - public static record InteractionMap(String name, Map map) { -