diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerMapFilledEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerMapFilledEvent.java new file mode 100644 index 00000000000..67712545625 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerMapFilledEvent.java @@ -0,0 +1,63 @@ +package io.papermc.paper.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a player creates a filled map by right-clicking an empty map. + */ +@NullMarked +public class PlayerMapFilledEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ItemStack originalItem; + private ItemStack createdMap; + + @ApiStatus.Internal + public PlayerMapFilledEvent(final Player player, final ItemStack originalItem, final ItemStack createdMap) { + super(player); + this.originalItem = originalItem; + this.createdMap = createdMap; + } + + /** + * Returns a copy of the empty map before it was consumed. + * + * @return cloned original item + */ + public ItemStack getOriginalItem() { + return this.originalItem.clone(); + } + + /** + * Returns a copy of the filled map which was created. + * + * @return cloned created map item + */ + public ItemStack getCreatedMap() { + return this.createdMap.clone(); + } + + /** + * Sets the filled map that will be created. + * + * @param createdMap map item + */ + public void setCreatedMap(final ItemStack createdMap) { + this.createdMap = createdMap.clone(); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/item/EmptyMapItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EmptyMapItem.java.patch new file mode 100644 index 00000000000..9cd8c1185b5 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/EmptyMapItem.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/item/EmptyMapItem.java ++++ b/net/minecraft/world/item/EmptyMapItem.java +@@ -17,10 +_,16 @@ + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); + if (level instanceof ServerLevel serverLevel) { ++ org.bukkit.inventory.ItemStack emptyMap = itemInHand.asBukkitCopy(); // Paper - PlayerMapFilledEvent + itemInHand.consume(1, player); + player.awardStat(Stats.ITEM_USED.get(this)); + serverLevel.playSound(null, player, SoundEvents.UI_CARTOGRAPHY_TABLE_TAKE_RESULT, player.getSoundSource(), 1.0F, 1.0F); + ItemStack itemStack = MapItem.create(serverLevel, player.getBlockX(), player.getBlockZ(), (byte)0, true, false); ++ // Paper start - PlayerMapFilledEvent ++ io.papermc.paper.event.player.PlayerMapFilledEvent event = new io.papermc.paper.event.player.PlayerMapFilledEvent((org.bukkit.entity.Player) player.getBukkitEntity(), emptyMap, org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack)); ++ event.callEvent(); ++ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getCreatedMap()); ++ // Paper end - PlayerMapFilledEvent + if (itemInHand.isEmpty()) { + return InteractionResult.SUCCESS.heldItemTransformedTo(itemStack); + } else {