diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch index b0412dae18..4b9ddbae38 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch @@ -19,16 +19,27 @@ } @Override -@@ -460,7 +462,7 @@ +@@ -446,6 +448,10 @@ + if (entityplayer == null && this.partner.getLoveCause() != null) { + entityplayer = this.partner.getLoveCause(); + } ++ // Paper start - Add EntityFertilizeEggEvent event ++ io.papermc.paper.event.entity.EntityFertilizeEggEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this.animal, this.partner); ++ if (event.isCancelled()) return; ++ // Paper end - Add EntityFertilizeEggEvent event + + if (entityplayer != null) { + entityplayer.awardStat(Stats.ANIMALS_BRED); +@@ -460,7 +466,7 @@ RandomSource randomsource = this.animal.getRandom(); if (getServerLevel((Level) this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1)); -+ this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper; ++ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event } } -@@ -492,16 +494,21 @@ +@@ -492,16 +498,21 @@ if (!this.turtle.isInWater() && this.isReachedTarget()) { if (this.turtle.layEggCounter < 1) { @@ -52,7 +63,7 @@ this.turtle.setHasEgg(false); this.turtle.setLayingEgg(false); this.turtle.setInLoveTime(600); -@@ -567,7 +574,7 @@ +@@ -567,7 +578,7 @@ @Override public boolean canUse() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch new file mode 100644 index 0000000000..f849bb1ffc --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/entity/animal/frog/Frog.java ++++ b/net/minecraft/world/entity/animal/frog/Frog.java +@@ -270,7 +270,12 @@ + + @Override + public void spawnChildFromBreeding(ServerLevel world, Animal other) { +- this.finalizeSpawnChildFromBreeding(world, other, null); ++ // Paper start - Add EntityFertilizeEggEvent event ++ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other); ++ if (result.isCancelled()) return; ++ ++ this.finalizeSpawnChildFromBreeding(world, other, null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount ++ // Paper end - Add EntityFertilizeEggEvent event + this.getBrain().setMemory(MemoryModuleType.IS_PREGNANT, Unit.INSTANCE); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch index 8e752b40ac..a6567df470 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch @@ -23,10 +23,21 @@ return this; } -@@ -338,8 +345,9 @@ +@@ -333,13 +340,19 @@ + + @Override + public void spawnChildFromBreeding(ServerLevel world, Animal other) { ++ // Paper start - Add EntityFertilizeEggEvent event ++ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other); ++ if (result.isCancelled()) return; ++ // Paper end - Add EntityFertilizeEggEvent event ++ + ItemStack itemstack = new ItemStack(Items.SNIFFER_EGG); + ItemEntity entityitem = new ItemEntity(world, this.position().x(), this.position().y(), this.position().z(), itemstack); entityitem.setDefaultPickUpDelay(); - this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null); +- this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null); ++ this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null, result.getExperience()); // Paper - Add EntityFertilizeEggEvent event + if (this.spawnAtLocation(world, entityitem) != null) { // Paper - Call EntityDropItemEvent this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F); - world.addFreshEntity(entityitem); @@ -34,7 +45,7 @@ } @Override -@@ -444,7 +452,7 @@ +@@ -444,7 +457,7 @@ @Override public Brain getBrain() { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 48d39015da..ec5c16f64d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -2195,4 +2195,28 @@ public class CraftEventFactory { return event.callEvent(); } // Paper end + + // Paper start - add EntityFertilizeEggEvent + /** + * Calls the {@link io.papermc.paper.event.entity.EntityFertilizeEggEvent}. + * If the event is cancelled, this method also resets the love on both the {@code breeding} and {@code other} entity. + * + * @param breeding the entity on which #spawnChildFromBreeding was called. + * @param other the partner of the entity. + * @return the event after it was called. The instance may be used to retrieve the experience of the event. + */ + public static io.papermc.paper.event.entity.EntityFertilizeEggEvent callEntityFertilizeEggEvent(Animal breeding, Animal other) { + ServerPlayer serverPlayer = breeding.getLoveCause(); + if (serverPlayer == null) serverPlayer = other.getLoveCause(); + final int experience = breeding.getRandom().nextInt(7) + 1; // From Animal#spawnChildFromBreeding(ServerLevel, Animal) + + final io.papermc.paper.event.entity.EntityFertilizeEggEvent event = new io.papermc.paper.event.entity.EntityFertilizeEggEvent((LivingEntity) breeding.getBukkitEntity(), (LivingEntity) other.getBukkitEntity(), serverPlayer == null ? null : serverPlayer.getBukkitEntity(), breeding.breedItem == null ? null : CraftItemStack.asCraftMirror(breeding.breedItem).clone(), experience); + if (!event.callEvent()) { + breeding.resetLove(); + other.resetLove(); // stop the pathfinding to avoid infinite loop + } + + return event; + } + // Paper end - add EntityFertilizeEggEvent }