diff --git a/patches/server/Fix-several-issues-with-EntityBreedEvent.patch b/patches/server/Fix-several-issues-with-EntityBreedEvent.patch new file mode 100644 index 0000000000..51966f9eeb --- /dev/null +++ b/patches/server/Fix-several-issues-with-EntityBreedEvent.patch @@ -0,0 +1,118 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Thu, 15 Dec 2022 00:14:44 -0800 +Subject: [PATCH] Fix several issues with EntityBreedEvent + +Upstream did not account for different hands when storing +the breed item for later use in the event. Also they only +stored a reference to the stack, not a copy so if the stack +changed after love mode was started, the breed item in the event +also changed. Also in several places, the breed item was stored after +it was decreased by one to consume the item. + +diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java +@@ -0,0 +0,0 @@ public abstract class Animal extends AgeableMob { + int i = this.getAge(); + + if (!this.level().isClientSide && i == 0 && this.canFallInLove()) { ++ final ItemStack breedCopy = itemstack.copy(); // Paper + this.usePlayerItem(player, hand, itemstack); +- this.setInLove(player); ++ this.setInLove(player, breedCopy); // Paper + return InteractionResult.SUCCESS; + } + +@@ -0,0 +0,0 @@ public abstract class Animal extends AgeableMob { + return this.inLove <= 0; + } + ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper + public void setInLove(@Nullable Player player) { ++ // Paper start - pass breed stack ++ this.setInLove(player, null); ++ } ++ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) { ++ if (breedItemCopy != null) this.breedItem = breedItemCopy; ++ // Paper end + // CraftBukkit start + EntityEnterLoveModeEvent entityEnterLoveModeEvent = CraftEventFactory.callEntityEnterLoveModeEvent(player, this, 600); + if (entityEnterLoveModeEvent.isCancelled()) { ++ this.breedItem = null; // Paper - clear if cancelled + return; + } + this.inLove = entityEnterLoveModeEvent.getTicksInLove(); +@@ -0,0 +0,0 @@ public abstract class Animal extends AgeableMob { + if (player != null) { + this.loveCause = player.getUUID(); + } +- this.breedItem = player.getInventory().getSelected(); // CraftBukkit ++ // Paper - set breed item in better place + + this.level().broadcastEntityEvent(this, (byte) 18); + } +diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java +@@ -0,0 +0,0 @@ public class Panda extends Animal { + this.usePlayerItem(player, hand, itemstack); + this.ageUp((int) ((float) (-this.getAge() / 20) * 0.1F), true); + } else if (!this.level().isClientSide && this.getAge() == 0 && this.canFallInLove()) { ++ final ItemStack breedCopy = itemstack.copy(); // Paper + this.usePlayerItem(player, hand, itemstack); +- this.setInLove(player); ++ this.setInLove(player, breedCopy); // Paper + } else { + if (this.level().isClientSide || this.isSitting() || this.isInWater()) { + return InteractionResult.PASS; +diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java ++++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +@@ -0,0 +0,0 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl + + boolean bl2 = this.isTamed() && this.getAge() == 0 && this.canFallInLove(); + if (bl2) { +- this.setInLove(player); ++ this.setInLove(player, item.copy()); // Paper + } + + boolean bl3 = this.isBaby(); +diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java ++++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java +@@ -0,0 +0,0 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, + b0 = 5; + if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) { + flag = true; +- this.setInLove(player); ++ this.setInLove(player, item.copy()); // Paper + } + } else if (item.is(Items.GOLDEN_APPLE) || item.is(Items.ENCHANTED_GOLDEN_APPLE)) { + f = 10.0F; +@@ -0,0 +0,0 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, + b0 = 10; + if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) { + flag = true; +- this.setInLove(player); ++ this.setInLove(player, item.copy()); // Paper + } + } + +diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java ++++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java +@@ -0,0 +0,0 @@ public class Llama extends AbstractChestedHorse implements VariantHolder