--- a/net/minecraft/world/item/LeadItem.java +++ b/net/minecraft/world/item/LeadItem.java @@ -28,23 +_,43 @@ if (blockState.is(BlockTags.FENCES)) { Player player = context.getPlayer(); if (!level.isClientSide && player != null) { - return bindPlayerMobs(player, level, clickedPos); + return bindPlayerMobs(player, level, clickedPos, context.getHand()); // CraftBukkit - Pass hand } } return InteractionResult.PASS; } - public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos) { + public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos, net.minecraft.world.InteractionHand interactionHand) { // CraftBukkit - Add InteractionHand LeashFenceKnotEntity leashFenceKnotEntity = null; List list = leashableInArea(level, pos, leashable1 -> leashable1.getLeashHolder() == player); - for (Leashable leashable : list) { + for (java.util.Iterator iterator = list.iterator(); iterator.hasNext();) { // Paper - use iterator to remove + Leashable leashable = iterator.next(); // Paper - use iterator to remove if (leashFenceKnotEntity == null) { leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos); + // CraftBukkit start - fire HangingPlaceEvent + org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(interactionHand); + org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) leashFenceKnotEntity.getBukkitEntity(), player != null ? (org.bukkit.entity.Player) player.getBukkitEntity() : null, org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.block.BlockFace.SELF, hand); + level.getCraftServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + leashFenceKnotEntity.discard(null); // CraftBukkit - add Bukkit remove cause + return InteractionResult.PASS; + } + // CraftBukkit end leashFenceKnotEntity.playPlacementSound(); } + // CraftBukkit start + if (leashable instanceof Entity leashed) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, leashFenceKnotEntity, player, interactionHand).isCancelled()) { + iterator.remove(); + continue; + } + } + // CraftBukkit end + leashable.setLeashedTo(leashFenceKnotEntity, true); } @@ -52,9 +_,20 @@ level.gameEvent(GameEvent.BLOCK_ATTACH, pos, GameEvent.Context.of(player)); return InteractionResult.SUCCESS_SERVER; } else { + // CraftBukkit start - remove leash if we do not leash any entity because of the cancelled event + if (leashFenceKnotEntity != null) { + leashFenceKnotEntity.discard(null); + } + // CraftBukkit end return InteractionResult.PASS; } } + + // CraftBukkit start + public static InteractionResult bindPlayerMobs(Player player, Level world, BlockPos pos) { + return LeadItem.bindPlayerMobs(player, world, pos, net.minecraft.world.InteractionHand.MAIN_HAND); + } + // CraftBukkit end public static List leashableInArea(Level level, BlockPos pos, Predicate predicate) { double d = 7.0;