diff --git a/gradle.properties b/gradle.properties index 8155c3e..91e95af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ version = 1.21.1-R0.1-SNAPSHOT mcVersion = 1.21.1 # Upstream commit -purpurCommit = be61a07bf60547c02657b39cb90ceb4c0dc68883 +purpurCommit = d7a7c91a7fd28d77980ce3da06bdf69e8fef92af # Gradle org.gradle.caching = true diff --git a/patches/api/0007-ItemStack-helper-methods.patch b/patches/api/0007-ItemStack-helper-methods.patch index e4851e2..93d7312 100644 --- a/patches/api/0007-ItemStack-helper-methods.patch +++ b/patches/api/0007-ItemStack-helper-methods.patch @@ -5,10 +5,10 @@ Subject: [PATCH] ItemStack helper methods diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 9b8b958ce181b60eb5db89d4720380153152a2ac..c4686f06fd945c77a2813f1b2c31508e65f64ad2 100644 +index b6389b82b4eae033e1e770ae3967c88e950926ab..152dccfc9b445e11fa646d070a762d97bd7fdcfb 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -1591,4 +1591,54 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1678,4 +1678,54 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return random.nextInt(unbreaking + 1) > 0; } // Purpur end diff --git a/patches/api/0029-Extra-item-drop-method.patch b/patches/api/0029-Extra-item-drop-method.patch new file mode 100644 index 0000000..52e6588 --- /dev/null +++ b/patches/api/0029-Extra-item-drop-method.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Wed, 25 Sep 2024 19:28:19 +0300 +Subject: [PATCH] Extra item drop method + + +diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java +index 261475159221ddd528d13991c06be5eaf908030c..8ff204f95bf47c90c4015a5d7e82d4670597b39d 100644 +--- a/src/main/java/org/bukkit/entity/HumanEntity.java ++++ b/src/main/java/org/bukkit/entity/HumanEntity.java +@@ -812,4 +812,14 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder + @Nullable + public Firework fireworkBoost(@NotNull ItemStack fireworkItemStack); + ++ // Kiterino start - Extra item drop method ++ /** ++ * Drops an item at the location of the entity. ++ * ++ * @param item ItemStack to drop ++ * @return ItemDrop entity created as a result of this method ++ */ ++ @NotNull Item dropItem(@NotNull org.bukkit.inventory.ItemStack item); ++ // Kiterino end - Extra item drop method ++ + } diff --git a/patches/api/0030-Add-extra-MaterialTags.patch b/patches/api/0030-Add-extra-MaterialTags.patch new file mode 100644 index 0000000..b6aa600 --- /dev/null +++ b/patches/api/0030-Add-extra-MaterialTags.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Mon, 21 Feb 2022 11:44:15 +0200 +Subject: [PATCH] Add extra MaterialTags + + +diff --git a/src/main/java/com/destroystokyo/paper/MaterialTags.java b/src/main/java/com/destroystokyo/paper/MaterialTags.java +index be212b4fbeabab32a4dab6ae554768c368efaa88..0552272771d1f5e1a4294a77bf266bcb7105676c 100644 +--- a/src/main/java/com/destroystokyo/paper/MaterialTags.java ++++ b/src/main/java/com/destroystokyo/paper/MaterialTags.java +@@ -714,4 +714,21 @@ public class MaterialTags { + .add(Material.NETHERITE_AXE, Material.NETHERITE_HOE, Material.NETHERITE_PICKAXE, Material.NETHERITE_SHOVEL, Material.NETHERITE_SWORD) + .ensureSize("NETHERITE_TOOLS", 5).lock(); + ++ // Kiterino start - Add extra MaterialTags ++ /** ++ * Covers the variants of items that can be equipped in any of the armor slots. ++ */ ++ public static final MaterialSetTag ALL_EQUIPPABLE = new MaterialSetTag(keyFor("all_equippable")) ++ .add(HEAD_EQUIPPABLE) ++ .add(CHEST_EQUIPPABLE) ++ .add(LEGGINGS) ++ .add(BOOTS) ++ .lock(); ++ ++ /** ++ * Covers the minecarts ++ */ ++ public static final MaterialSetTag MINECARTS = new MaterialSetTag(keyFor("minecarts")) ++ .endsWith("MINECART").ensureSize("MINECARTS", 6).lock(); ++ // Kiterino end - Add extra MaterialTags + } diff --git a/patches/api/0031-Add-Paper-PR-FillBottleEvents-for-player-and-dispens.patch b/patches/api/0031-Add-Paper-PR-FillBottleEvents-for-player-and-dispens.patch new file mode 100644 index 0000000..c538a7b --- /dev/null +++ b/patches/api/0031-Add-Paper-PR-FillBottleEvents-for-player-and-dispens.patch @@ -0,0 +1,194 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 26 Feb 2022 16:43:33 -0800 +Subject: [PATCH] Add Paper PR - FillBottleEvents for player and dispenser + +Adds 2 events, PlayerFillBottleEvent and BlockFillBottleEvent. These +events do not have a common superclass due to needing to extend +PlayerEvent and BlockEvent respectively. + +TODO: Add a common interface between Block and AreaEffectCloud, +something like BottleSource to add a "source" field to each event to get +the source of the bottle fill, water block, cauldron, beehive, or +AreaEffectCloud. + +Co-authored-by: Dmitry Sidorov + +diff --git a/src/main/java/io/papermc/paper/event/block/BlockFillBottleEvent.java b/src/main/java/io/papermc/paper/event/block/BlockFillBottleEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4d939e1d936dcb59807b1f39db7197f41426b700 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/block/BlockFillBottleEvent.java +@@ -0,0 +1,79 @@ ++package io.papermc.paper.event.block; ++ ++import org.bukkit.block.Block; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.block.BlockEvent; ++import org.bukkit.inventory.ItemStack; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Called when a {@link org.bukkit.block.Dispenser} fills up a bottle. ++ */ ++public class BlockFillBottleEvent extends BlockEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final ItemStack bottle; ++ private ItemStack resultItem; ++ private boolean cancelled; ++ ++ ++ public BlockFillBottleEvent(@NotNull Block block, @NotNull ItemStack bottle, @NotNull ItemStack resultItem) { ++ super(block); ++ this.bottle = bottle; ++ this.resultItem = resultItem; ++ } ++ ++ /** ++ * Gets the bottle item that's being filled. ++ * ++ * @return the bottle item ++ */ ++ public @NotNull ItemStack getBottle() { ++ return this.bottle; ++ } ++ ++ /** ++ * Gets the result of the glass bottle that's being filled. ++ * ++ * @return the result of the filling ++ */ ++ public @NotNull ItemStack getResultItem() { ++ return this.resultItem; ++ } ++ ++ /** ++ * Sets the result of the glass bottle being filled. ++ * ++ * @param resultItem the result of the filling ++ */ ++ public void setResultItem(@NotNull ItemStack resultItem) { ++ this.resultItem = resultItem; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ /** ++ * {@inheritDoc} ++ *

++ * Cancelling this event will prevent {@link #getBottle()} from being ++ * replaced/consumed. ++ */ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @Override ++ public @NotNull HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ public static @NotNull HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} +diff --git a/src/main/java/io/papermc/paper/event/player/PlayerFillBottleEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerFillBottleEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..22f3f867e8ff5041816926ddd599e3758387ea03 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/PlayerFillBottleEvent.java +@@ -0,0 +1,87 @@ ++package io.papermc.paper.event.player; ++ ++import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.bukkit.inventory.EquipmentSlot; ++import org.bukkit.inventory.ItemStack; ++import org.jetbrains.annotations.NotNull; ++ ++public class PlayerFillBottleEvent extends PlayerEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final EquipmentSlot hand; ++ private final ItemStack bottle; ++ private ItemStack resultItem; ++ private boolean cancelled; ++ ++ public PlayerFillBottleEvent(@NotNull Player player, @NotNull EquipmentSlot hand, @NotNull ItemStack bottle, @NotNull ItemStack resultItem) { ++ super(player); ++ this.hand = hand; ++ this.bottle = bottle; ++ this.resultItem = resultItem; ++ } ++ ++ /** ++ * The hand used to fill the bottle. ++ * ++ * @return the hand ++ */ ++ public @NotNull EquipmentSlot getHand() { ++ return this.hand; ++ } ++ ++ /** ++ * Gets the bottle item that's being filled. ++ * ++ * @return the bottle item ++ */ ++ public @NotNull ItemStack getBottle() { ++ return this.bottle; ++ } ++ ++ /** ++ * Gets the result of the bottle that's being filled. ++ * ++ * @return the result of the filling ++ */ ++ public @NotNull ItemStack getResultItem() { ++ return this.resultItem; ++ } ++ ++ /** ++ * Sets the result of the bottle being filled. ++ * ++ * @param resultItem the result of the filling ++ */ ++ public void setResultItem(@NotNull ItemStack resultItem) { ++ this.resultItem = resultItem; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ /** ++ * {@inheritDoc} ++ *

++ * Cancelling this event will prevent {@link #getBottle()} from being ++ * replaced/consumed. ++ */ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @Override ++ public @NotNull HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ public static @NotNull HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} diff --git a/patches/server/0018-Data-driven-items.patch b/patches/server/0018-Data-driven-items.patch index c54059c..fd9162b 100644 --- a/patches/server/0018-Data-driven-items.patch +++ b/patches/server/0018-Data-driven-items.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Data-driven items diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -index 98b096339fe48b2fc8169ae0376e05d59236fc9a..aac4192aa369ce5c1a59cdc01d1baec6034011e8 100644 +index d59e77811e4090d0f8207e4fff3300d17b1753b2..b2b3d8013ba6bdbd30bf2441efd069e04705cba9 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -77,7 +77,7 @@ public final class PaperRegistries { + entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new), entry(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new), - entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new), entry(Registries.BLOCK, RegistryKey.BLOCK, BlockType.class, CraftBlockType::new), - entry(Registries.ITEM, RegistryKey.ITEM, ItemType.class, CraftItemType::new), + writable(Registries.ITEM, RegistryKey.ITEM, ItemType.class, CraftItemType::new, me.sosedik.kiterino.registry.data.KiterinoItemRegistryEntity.KiterinoBuilder::new).delayed(), // Kiterino - Data-driven items diff --git a/patches/server/0021-Data-driven-mob-effects.patch b/patches/server/0021-Data-driven-mob-effects.patch index d89fd2f..b484a68 100644 --- a/patches/server/0021-Data-driven-mob-effects.patch +++ b/patches/server/0021-Data-driven-mob-effects.patch @@ -5,18 +5,18 @@ Subject: [PATCH] Data-driven mob effects diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -index aac4192aa369ce5c1a59cdc01d1baec6034011e8..c1663ecd1fe46529e7e9ce50a52112ab16611d57 100644 +index b2b3d8013ba6bdbd30bf2441efd069e04705cba9..469c8ce4b4ea0a9d2efc8237c7ce6c3c200dac69 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -@@ -74,7 +74,7 @@ public final class PaperRegistries { - // built-ins +@@ -75,7 +75,7 @@ public final class PaperRegistries { writable(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new, PaperGameEventRegistryEntry.PaperBuilder::new), + entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new), entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new), - entry(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new), + writable(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new, me.sosedik.kiterino.registry.data.KiterinoMobEffectRegistryEntity.KiterinoBuilder::new).delayed(), // Kiterino - Data-driven mob effects - entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new), entry(Registries.BLOCK, RegistryKey.BLOCK, BlockType.class, CraftBlockType::new), writable(Registries.ITEM, RegistryKey.ITEM, ItemType.class, CraftItemType::new, me.sosedik.kiterino.registry.data.KiterinoItemRegistryEntity.KiterinoBuilder::new).delayed(), // Kiterino - Data-driven items + entry(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT, Cat.Type.class, CraftCat.CraftType::new), diff --git a/src/main/java/io/papermc/paper/registry/data/util/Conversions.java b/src/main/java/io/papermc/paper/registry/data/util/Conversions.java index 48de73884cdece86ff19e36d930e3990066de3bf..b5d6fe97a9a9a1c7e923ec37828fda2389895a7b 100644 --- a/src/main/java/io/papermc/paper/registry/data/util/Conversions.java diff --git a/patches/server/0031-Keep-rider-when-teleporting.patch b/patches/server/0031-Keep-rider-when-teleporting.patch index 00d6b19..44b07a8 100644 --- a/patches/server/0031-Keep-rider-when-teleporting.patch +++ b/patches/server/0031-Keep-rider-when-teleporting.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Keep rider when teleporting diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index d91aef1bb668e87998b4270ecf2a3e730cb9929f..fe897009d48193527db225138b02188babfc90e0 100644 +index 4eb0032aa0481c8afe95a5246e63e05d6cb4f5ea..1ddf4d746fca0a69f63a69b68e589ebacc63f201 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -5146,7 +5146,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5148,7 +5148,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - Expose entity id counter // Purpur start @Nullable diff --git a/patches/server/0042-Less-limited-recipe-matcher.patch b/patches/server/0042-Less-limited-recipe-matcher.patch index 63d7f87..aca422a 100644 --- a/patches/server/0042-Less-limited-recipe-matcher.patch +++ b/patches/server/0042-Less-limited-recipe-matcher.patch @@ -6,7 +6,6 @@ Subject: [PATCH] Less limited recipe matcher Adds the options to allow using damaged/enchanted/renamed items in the recipe matcher used by e.g. the recipe book autofill or the crafter block. - diff --git a/src/main/java/me/sosedik/kiterino/KiterinoConfig.java b/src/main/java/me/sosedik/kiterino/KiterinoConfig.java index c53d495beeda9c057efc5af1b06613be1b5fa9f4..665879a04af47617fe2007348dae94ee27f22fa3 100644 --- a/src/main/java/me/sosedik/kiterino/KiterinoConfig.java diff --git a/patches/server/0043-Extra-item-drop-method.patch b/patches/server/0043-Extra-item-drop-method.patch new file mode 100644 index 0000000..1e35adb --- /dev/null +++ b/patches/server/0043-Extra-item-drop-method.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Wed, 25 Sep 2024 19:28:18 +0300 +Subject: [PATCH] Extra item drop method + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +index 46856d2b7e24c5d223b7b1627ccb451749b183e7..25e5f70d5558720280fe05c8ba2a0ad6d90a0c8d 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +@@ -872,4 +872,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + public org.bukkit.entity.Entity copy(Location location) { + throw new UnsupportedOperationException("Cannot copy human entities"); + } ++ ++ // Kiterino start - Extra item drop method ++ @Override ++ public org.bukkit.entity.Item dropItem(ItemStack item) { ++ if (!(getHandle() instanceof ServerPlayer player)) { ++ return getWorld().dropItemNaturally(getLocation(), item); ++ } ++ var drop = player.drop(CraftItemStack.asNMSCopy(item), false, true); ++ return drop != null && drop.getBukkitEntity() instanceof org.bukkit.entity.Item droppedItem ? droppedItem : null; ++ } ++ // Kiterino end - Extra item drop method + } diff --git a/patches/server/0044-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch b/patches/server/0044-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch new file mode 100644 index 0000000..b792fe3 --- /dev/null +++ b/patches/server/0044-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch @@ -0,0 +1,177 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 26 Feb 2022 16:41:11 -0800 +Subject: [PATCH] Paper PR - Add FillBottleEvents for player and dispenser + +Adds 2 events, PlayerFillBottleEvent and BlockFillBottleEvent. These +events do not have a common superclass due to needing to extend +PlayerEvent and BlockEvent respectively. + +TODO: Add a common interface between Block and AreaEffectCloud, +something like BottleSource to add a "source" field to each event to get +the source of the bottle fill, water block, cauldron, beehive, or +AreaEffectCloud. + +Co-authored-by: Dmitry Sidorov + +diff --git a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java +index f301c20e808b77cb3fcffd9a7c8102928306456e..ca881521aa054926007ceeedee456297387e631a 100644 +--- a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java ++++ b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java +@@ -117,7 +117,14 @@ public interface CauldronInteraction { + // CraftBukkit end + Item item = itemstack.getItem(); + +- entityhuman.setItemInHand(enumhand, ItemUtils.createFilledResult(itemstack, entityhuman, PotionContents.createItemStack(Items.POTION, Potions.WATER))); ++ // Paper start - Glass bottle events ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(entityhuman, enumhand, itemstack, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ if (event.isCancelled()) { ++ // doesn't seem to require updating the client ++ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; // PASS to not increment statistics ++ } ++ entityhuman.setItemInHand(enumhand, ItemUtils.createFilledResult(itemstack, entityhuman, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()))); ++ // Paper end - Glass bottle events + entityhuman.awardStat(Stats.USE_CAULDRON); + entityhuman.awardStat(Stats.ITEM_USED.get(item)); + // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit +diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +index bd07743817f2510c179614a6215434e7b333824a..6aea76bd5bbdc82bc8bb95e17975fb9220185cd7 100644 +--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +@@ -855,12 +855,24 @@ public interface DispenseItemBehavior { + if (iblockdata.is(BlockTags.BEEHIVES, (blockbase_blockdata) -> { + return blockbase_blockdata.hasProperty(BeehiveBlock.HONEY_LEVEL) && blockbase_blockdata.getBlock() instanceof BeehiveBlock; + }) && (Integer) iblockdata.getValue(BeehiveBlock.HONEY_LEVEL) >= 5) { ++ // Paper start - Glass bottle events ++ final io.papermc.paper.event.block.BlockFillBottleEvent bottleEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFillBottleEvent(worldserver, pointer.pos(), stack, new ItemStack(Items.HONEY_BOTTLE)); ++ if (bottleEvent.isCancelled()) { ++ return stack; ++ } ++ // Paper end - Glass bottle events + ((BeehiveBlock) iblockdata.getBlock()).releaseBeesAndResetHoneyLevel(worldserver, iblockdata, blockposition, (Player) null, BeehiveBlockEntity.BeeReleaseStatus.BEE_RELEASED); + this.setSuccess(true); +- return this.takeLiquid(pointer, stack, new ItemStack(Items.HONEY_BOTTLE)); ++ return this.takeLiquid(pointer, stack, CraftItemStack.asNMSCopy(bottleEvent.getResultItem())); // Paper - Glass bottle events + } else if (worldserver.getFluidState(blockposition).is(FluidTags.WATER)) { ++ // Paper start - Glass bottle events ++ final io.papermc.paper.event.block.BlockFillBottleEvent bottleEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFillBottleEvent(worldserver, pointer.pos(), stack, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ if (bottleEvent.isCancelled()) { ++ return stack; ++ } ++ // Paper end - Glass bottle events + this.setSuccess(true); +- return this.takeLiquid(pointer, stack, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ return this.takeLiquid(pointer, stack, CraftItemStack.asNMSCopy(bottleEvent.getResultItem())); // Paper - Glass bottle events + } else { + return super.execute(pointer, stack); + } +diff --git a/src/main/java/net/minecraft/world/item/BottleItem.java b/src/main/java/net/minecraft/world/item/BottleItem.java +index dbcffbce0298058ab536101465d64cb50445577d..b64b9dc5f19d119c5c4019be05fe90c2a53e17e4 100644 +--- a/src/main/java/net/minecraft/world/item/BottleItem.java ++++ b/src/main/java/net/minecraft/world/item/BottleItem.java +@@ -33,6 +33,17 @@ public class BottleItem extends Item { + ); + ItemStack itemStack = user.getItemInHand(hand); + if (!list.isEmpty()) { ++ // Paper start - Glass bottle events ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(user, hand, itemStack, new ItemStack(Items.DRAGON_BREATH)); ++ if (event.isCancelled()) { ++ user.containerMenu.sendAllDataToRemote(); // client expects the itemstack to be used ++ return InteractionResultHolder.pass(itemStack); ++ } ++ final ItemStack resultItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()); ++ if (resultItem.is(itemStack.getItem())) { ++ user.containerMenu.sendAllDataToRemote(); // client expects the itemstack to be used ++ } ++ // Paper end - Glass bottle events + AreaEffectCloud areaEffectCloud = list.get(0); + areaEffectCloud.setRadius(areaEffectCloud.getRadius() - 0.5F); + world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.BOTTLE_FILL_DRAGONBREATH, SoundSource.NEUTRAL, 1.0F, 1.0F); +@@ -41,7 +52,7 @@ public class BottleItem extends Item { + CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(serverPlayer, itemStack, areaEffectCloud); + } + +- return InteractionResultHolder.sidedSuccess(this.turnBottleIntoItem(itemStack, user, new ItemStack(Items.DRAGON_BREATH)), world.isClientSide()); ++ return InteractionResultHolder.sidedSuccess(this.turnBottleIntoItem(itemStack, user, resultItem), world.isClientSide()); // Paper - Glass bottle events + } else { + BlockHitResult blockHitResult = getPlayerPOVHitResult(world, user, ClipContext.Fluid.SOURCE_ONLY); + if (blockHitResult.getType() == HitResult.Type.MISS) { +@@ -54,10 +65,21 @@ public class BottleItem extends Item { + } + + if (world.getFluidState(blockPos).is(FluidTags.WATER)) { ++ // Paper start - Glass bottle events ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(user, hand, itemStack, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ if (event.isCancelled()) { ++ user.containerMenu.sendAllDataToRemote(); // client expects the itemstack to be used ++ return InteractionResultHolder.pass(itemStack); ++ } ++ final ItemStack resultItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()); ++ if (resultItem.is(itemStack.getItem())) { ++ user.containerMenu.sendAllDataToRemote(); // client expects the itemstack to be used ++ } ++ // Paper end - Glass bottle events + world.playSound(user, user.getX(), user.getY(), user.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); + world.gameEvent(user, GameEvent.FLUID_PICKUP, blockPos); + return InteractionResultHolder.sidedSuccess( +- this.turnBottleIntoItem(itemStack, user, PotionContents.createItemStack(Items.POTION, Potions.WATER)), world.isClientSide() ++ this.turnBottleIntoItem(itemStack, user, resultItem), world.isClientSide() // Paper - Glass bottle events + ); + } + } +diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +index 4669b1877be5eecf6738eefd81a35bde531759d6..e2a7a462cc14754c7a305825b13486f508fd9c57 100644 +--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +@@ -156,12 +156,25 @@ public class BeehiveBlock extends BaseEntityBlock { + flag = true; + world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos); + } else if (stack.is(Items.GLASS_BOTTLE)) { ++ // Paper start - Glass bottle events ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(player, hand, stack, new ItemStack(Items.HONEY_BOTTLE)); ++ if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); // client expects the itemstack to be used ++ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; ++ } ++ final ItemStack resultItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()); ++ if (resultItem.is(stack.getItem())) { ++ player.containerMenu.sendAllDataToRemote(); // client expects the itemstack to be used ++ } ++ // Paper end - Glass bottle events + stack.shrink(1); + world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS, 1.0F, 1.0F); + if (stack.isEmpty()) { +- player.setItemInHand(hand, new ItemStack(Items.HONEY_BOTTLE)); +- } else if (!player.getInventory().add(new ItemStack(Items.HONEY_BOTTLE))) { +- player.drop(new ItemStack(Items.HONEY_BOTTLE), false); ++ // Paper start - Glass bottle events ++ player.setItemInHand(hand, resultItem); ++ } else if (!player.getInventory().add(resultItem)) { ++ player.drop(resultItem, false); ++ // Paper end - Glass bottle events + } + + flag = true; +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 858c6c860d9b8aaa1d3f9f77a9e410726239d7cc..5aa75933ea1096efc27074cf456aa35de6ca5c9d 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -2277,4 +2277,18 @@ public class CraftEventFactory { + return event; + } + // Paper end - add EntityFertilizeEggEvent ++ ++ // Paper start - Glass bottle events ++ public static io.papermc.paper.event.player.PlayerFillBottleEvent callPlayerFillBottleEvent(net.minecraft.world.entity.player.Player player, InteractionHand hand, ItemStack glassBottle, ItemStack resultItem) { ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = new io.papermc.paper.event.player.PlayerFillBottleEvent(((org.bukkit.entity.Player) player.getBukkitEntity()), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), CraftItemStack.asBukkitCopy(glassBottle), CraftItemStack.asCraftMirror(resultItem)); ++ event.callEvent(); ++ return event; ++ } ++ ++ public static io.papermc.paper.event.block.BlockFillBottleEvent callBlockFillBottleEvent(LevelAccessor level, BlockPos blockPos, ItemStack glassBottle, ItemStack resultItem) { ++ final io.papermc.paper.event.block.BlockFillBottleEvent event = new io.papermc.paper.event.block.BlockFillBottleEvent(CraftBlock.at(level, blockPos), CraftItemStack.asBukkitCopy(glassBottle), CraftItemStack.asCraftMirror(resultItem)); ++ event.callEvent(); ++ return event; ++ } ++ // Paper end - Glass bottle events + }