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 index 864d32c20..f0db76086 100644 --- a/paper-server/patches/sources/net/minecraft/core/cauldron/CauldronInteraction.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/cauldron/CauldronInteraction.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/cauldron/CauldronInteraction.java +++ b/net/minecraft/core/cauldron/CauldronInteraction.java -@@ -35,15 +35,20 @@ +@@ -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; @@ -26,7 +26,26 @@ static CauldronInteraction.InteractionMap newInteractionMap(String name) { Object2ObjectOpenHashMap object2objectopenhashmap = new Object2ObjectOpenHashMap(); -@@ -68,12 +73,17 @@ + +- 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) { @@ -45,9 +64,19 @@ world.playSound((Player) null, blockposition, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PLACE, blockposition); } -@@ -93,12 +103,17 @@ +@@ -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) -> { ++ 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)) { @@ -64,6 +93,14 @@ 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)) { @@ -81,10 +118,51 @@ world.playSound((Player) null, blockposition, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PLACE, blockposition); } -@@ -194,12 +214,17 @@ +@@ -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; @@ -100,10 +178,26 @@ world.playSound((Player) null, pos, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F); world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PICKUP, pos); } -@@ -210,12 +235,17 @@ +@@ -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; @@ -111,7 +205,8 @@ + // CraftBukkit end Item item = stack.getItem(); - player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.BUCKET))); +- 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); @@ -119,7 +214,33 @@ world.playSound((Player) null, pos, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F); world.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PLACE, pos); } -@@ -242,11 +272,16 @@ +@@ -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) { @@ -135,9 +256,16 @@ - LayeredCauldronBlock.lowerFillLevel(state, world, pos); + // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit } - +- return InteractionResult.SUCCESS; -@@ -260,12 +295,17 @@ + } + } + +- 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) { @@ -156,7 +284,14 @@ } return InteractionResult.SUCCESS; -@@ -279,9 +319,14 @@ + } + } + +- 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) { @@ -172,7 +307,7 @@ } return InteractionResult.SUCCESS; -@@ -294,8 +339,10 @@ +@@ -294,8 +367,10 @@ return fluid.is(FluidTags.WATER); } @@ -184,7 +319,7 @@ Map map = CauldronInteraction.INTERACTIONS; Objects.requireNonNull(map); -@@ -305,6 +352,8 @@ +@@ -305,6 +380,8 @@ LAVA = newInteractionMap("lava"); POWDER_SNOW = newInteractionMap("powder_snow"); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch new file mode 100644 index 000000000..e2c8cb7f0 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/AbstractCauldronBlock.java ++++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java +@@ -56,7 +56,7 @@ + @Override + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem()); +- return cauldronInteraction.interact(state, world, pos, player, hand, stack); ++ return cauldronInteraction.interact(state, world, pos, player, hand, stack, hit.getDirection()); // Paper - pass hit direction + } + + @Override