diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/AbstractSchoolingFish.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/AbstractSchoolingFish.java.patch similarity index 95% rename from paper-server/patches/unapplied/net/minecraft/world/entity/animal/AbstractSchoolingFish.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/animal/AbstractSchoolingFish.java.patch index 69bd0b2aef..450e26f925 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/AbstractSchoolingFish.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/AbstractSchoolingFish.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/AbstractSchoolingFish.java +++ b/net/minecraft/world/entity/animal/AbstractSchoolingFish.java -@@ -51,6 +51,7 @@ +@@ -51,6 +_,7 @@ } public void stopFollowing() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch new file mode 100644 index 0000000000..a8935bd393 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch @@ -0,0 +1,118 @@ +--- a/net/minecraft/world/entity/animal/Animal.java ++++ b/net/minecraft/world/entity/animal/Animal.java +@@ -39,6 +_,7 @@ + public int inLove; + @Nullable + public UUID loveCause; ++ public ItemStack breedItem; // CraftBukkit - Add breedItem variable + + protected Animal(EntityType entityType, Level level) { + super(entityType, level); +@@ -78,9 +_,13 @@ + } + + @Override +- protected void actuallyHurt(ServerLevel level, DamageSource damageSource, float amount) { ++ // CraftBukkit start - void -> boolean ++ public boolean actuallyHurt(ServerLevel worldserver, DamageSource damagesource, float f, org.bukkit.event.entity.EntityDamageEvent event) { ++ boolean damageResult = super.actuallyHurt(worldserver, damagesource, f, event); ++ if (!damageResult) return false; + this.resetLove(); +- super.actuallyHurt(level, damageSource, amount); ++ return true; ++ // CraftBukkit end + } + + @Override +@@ -138,8 +_,9 @@ + if (this.isFood(itemInHand)) { + int age = this.getAge(); + if (!this.level().isClientSide && age == 0 && this.canFallInLove()) { ++ final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying + this.usePlayerItem(player, hand, itemInHand); +- this.setInLove(player); ++ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying + this.playEatingSound(); + return InteractionResult.SUCCESS_SERVER; + } +@@ -176,11 +_,26 @@ + return this.inLove <= 0; + } + ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Fix EntityBreedEvent copying + public void setInLove(@Nullable Player player) { +- this.inLove = 600; ++ // Paper start - Fix EntityBreedEvent copying ++ this.setInLove(player, null); ++ } ++ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) { ++ if (breedItemCopy != null) this.breedItem = breedItemCopy; ++ // Paper end - Fix EntityBreedEvent copying ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityEnterLoveModeEvent entityEnterLoveModeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityEnterLoveModeEvent(player, this, 600); ++ if (entityEnterLoveModeEvent.isCancelled()) { ++ this.breedItem = null; // Paper - Fix EntityBreedEvent copying; clear if cancelled ++ return; ++ } ++ this.inLove = entityEnterLoveModeEvent.getTicksInLove(); ++ // CraftBukkit end + if (player != null) { + this.loveCause = player.getUUID(); + } ++ // Paper - Fix EntityBreedEvent copying; set breed item in better place + + this.level().broadcastEntityEvent(this, (byte)18); + } +@@ -220,23 +_,45 @@ + if (breedOffspring != null) { + breedOffspring.setBaby(true); + breedOffspring.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); +- this.finalizeSpawnChildFromBreeding(level, mate, breedOffspring); +- level.addFreshEntityWithPassengers(breedOffspring); ++ // CraftBukkit start - call EntityBreedEvent ++ ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(mate.getLoveCause())).orElse(null); ++ int experience = this.getRandom().nextInt(7) + 1; ++ org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(breedOffspring, this, mate, breeder, this.breedItem, experience); ++ if (entityBreedEvent.isCancelled()) { ++ return; ++ } ++ experience = entityBreedEvent.getExperience(); ++ this.finalizeSpawnChildFromBreeding(level, mate, breedOffspring, experience); ++ level.addFreshEntityWithPassengers(breedOffspring, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); ++ // CraftBukkit end + } + } + + public void finalizeSpawnChildFromBreeding(ServerLevel level, Animal animal, @Nullable AgeableMob baby) { +- Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(animal.getLoveCause())).ifPresent(player -> { +- player.awardStat(Stats.ANIMALS_BRED); +- CriteriaTriggers.BRED_ANIMALS.trigger(player, this, animal, baby); +- }); ++ // CraftBukkit start ++ this.finalizeSpawnChildFromBreeding(level, animal, baby, this.getRandom().nextInt(7) + 1); ++ } ++ public void finalizeSpawnChildFromBreeding(ServerLevel level, Animal animal, @Nullable AgeableMob baby, int experience) { ++ // CraftBukkit end ++ // Paper start ++ ServerPlayer entityplayer = this.getLoveCause(); ++ if (entityplayer == null) entityplayer = animal.getLoveCause(); ++ if (entityplayer != null) { ++ // Paper end ++ entityplayer.awardStat(Stats.ANIMALS_BRED); ++ CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, animal, baby); ++ } // Paper + this.setAge(6000); + animal.setAge(6000); + this.resetLove(); + animal.resetLove(); + level.broadcastEntityEvent(this, (byte)18); + if (level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +- level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1)); ++ // CraftBukkit start - use event experience ++ if (experience > 0) { ++ level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, baby)); // Paper ++ } ++ // CraftBukkit end + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch new file mode 100644 index 0000000000..3891fbabb2 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch @@ -0,0 +1,153 @@ +--- a/net/minecraft/world/entity/animal/Bee.java ++++ b/net/minecraft/world/entity/animal/Bee.java +@@ -144,7 +_,22 @@ + + public Bee(EntityType entityType, Level level) { + super(entityType, level); +- this.moveControl = new FlyingMoveControl(this, 20, true); ++ // Paper start - Fix MC-167279 ++ class BeeFlyingMoveControl extends FlyingMoveControl { ++ public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) { ++ super(entity, maxPitchChange, noGravity); ++ } ++ ++ @Override ++ public void tick() { ++ if (this.mob.getY() <= Bee.this.level().getMinY()) { ++ this.mob.setNoGravity(false); ++ } ++ super.tick(); ++ } ++ } ++ this.moveControl = new BeeFlyingMoveControl(this, 20, true); ++ // Paper end - Fix MC-167279 + this.lookControl = new Bee.BeeLookControl(this); + this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F); + this.setPathfindingMalus(PathType.WATER, -1.0F); +@@ -191,12 +_,19 @@ + + @Override + public void addAdditionalSaveData(CompoundTag compound) { ++ // CraftBukkit start - selectively save data ++ this.addAdditionalSaveData(compound, true); ++ } ++ ++ @Override ++ public void addAdditionalSaveData(CompoundTag compound, boolean includeAll) { ++ // CraftBukkit end + super.addAdditionalSaveData(compound); +- if (this.hasHive()) { ++ if (includeAll && this.hasHive()) { // CraftBukkit - selectively save hive + compound.put("hive_pos", NbtUtils.writeBlockPos(this.getHivePos())); + } + +- if (this.hasSavedFlowerPos()) { ++ if (includeAll && this.hasSavedFlowerPos()) { // CraftBukkit - selectively save hive + compound.put("flower_pos", NbtUtils.writeBlockPos(this.getSavedFlowerPos())); + } + +@@ -237,7 +_,7 @@ + } + + if (i > 0) { +- livingEntity.addEffect(new MobEffectInstance(MobEffects.POISON, i * 20, 0), this); ++ livingEntity.addEffect(new MobEffectInstance(MobEffects.POISON, i * 20, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit + } + } + +@@ -489,11 +_,12 @@ + + @Nullable + BeehiveBlockEntity getBeehiveBlockEntity() { +- if (this.hivePos == null) { +- return null; +- } else { +- return this.isTooFarAway(this.hivePos) ? null : this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null); ++ // Paper start - move over logic to accommodate isTooFarAway with chunk load check ++ if (this.hivePos != null && !this.isTooFarAway(this.hivePos) && this.level().getChunkIfLoadedImmediately(this.hivePos.getX() >> 4, this.hivePos.getZ() >> 4) != null) { ++ return (BeehiveBlockEntity) this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null); + } ++ return null; ++ // Paper end + } + + boolean isHiveValid() { +@@ -520,11 +_,13 @@ + this.setFlag(4, hasStung); + } + ++ public net.kyori.adventure.util.TriState rollingOverride = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Rolling override + public boolean isRolling() { + return this.getFlag(2); + } + + public void setRolling(boolean isRolling) { ++ isRolling = rollingOverride.toBooleanOrElse(isRolling); // Paper - Rolling override + this.setFlag(2, isRolling); + } + +@@ -581,7 +_,7 @@ + if (beeInteractionEffect != null) { + this.usePlayerItem(player, hand, itemInHand); + if (!this.level().isClientSide) { +- this.addEffect(beeInteractionEffect); ++ this.addEffect(beeInteractionEffect, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // Paper - Add missing effect cause + } + + return InteractionResult.SUCCESS; +@@ -650,8 +_,9 @@ + if (this.isInvulnerableTo(level, damageSource)) { + return false; + } else { ++ if (!super.hurtServer(level, damageSource, amount)) return false; // CraftBukkit - Only stop pollinating if entity was damaged + this.beePollinateGoal.stopPollinating(); +- return super.hurtServer(level, damageSource, amount); ++ return true; // CraftBukkit - Only stop pollinating if entity was damaged + } + } + +@@ -772,7 +_,7 @@ + @VisibleForDebug + public class BeeGoToHiveGoal extends Bee.BaseBeeGoal { + public static final int MAX_TRAVELLING_TICKS = 2400; +- int travellingTicks = Bee.this.level().random.nextInt(10); ++ int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues + private static final int MAX_BLACKLISTED_TARGETS = 3; + final List blacklistedTargets = Lists.newArrayList(); + @Nullable +@@ -888,7 +_,7 @@ + + public class BeeGoToKnownFlowerGoal extends Bee.BaseBeeGoal { + private static final int MAX_TRAVELLING_TICKS = 2400; +- int travellingTicks = Bee.this.level().random.nextInt(10); ++ int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues + + BeeGoToKnownFlowerGoal() { + this.setFlags(EnumSet.of(Goal.Flag.MOVE)); +@@ -986,7 +_,7 @@ + } + } + +- if (blockState1 != null) { ++ if (blockState1 != null && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(Bee.this, blockPos, blockState1)) { // CraftBukkit + Bee.this.level().levelEvent(2011, blockPos, 15); + Bee.this.level().setBlockAndUpdate(blockPos, blockState1); + Bee.this.incrementNumCropsGrownSincePollination(); +@@ -1010,7 +_,7 @@ + @Override + protected void alertOther(Mob mob, LivingEntity target) { + if (mob instanceof Bee && this.mob.hasLineOfSight(target)) { +- mob.setTarget(target); ++ mob.setTarget(target, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason + } + } + } +@@ -1168,7 +_,7 @@ + Bee.this.dropFlower(); + this.pollinating = false; + Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; +- } else { ++ } else if (Bee.this.savedFlowerPos != null) { // Paper - add null check since API can manipulate this + Vec3 vec3 = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0, 0.6F, 0.0); + if (vec3.distanceTo(Bee.this.position()) > 1.0) { + this.hoverPos = vec3; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Bucketable.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Bucketable.java.patch new file mode 100644 index 0000000000..7d0041cf64 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Bucketable.java.patch @@ -0,0 +1,32 @@ +--- a/net/minecraft/world/entity/animal/Bucketable.java ++++ b/net/minecraft/world/entity/animal/Bucketable.java +@@ -88,9 +_,19 @@ + static Optional bucketMobPickup(Player player, InteractionHand hand, T entity) { + ItemStack itemInHand = player.getItemInHand(hand); + if (itemInHand.getItem() == Items.WATER_BUCKET && entity.isAlive()) { +- entity.playSound(entity.getPickupSound(), 1.0F, 1.0F); ++ // CraftBukkit start ++ // entity.playSound(entity.getPickupSound(), 1.0F, 1.0F); // CraftBukkit - moved down + ItemStack bucketItemStack = entity.getBucketItemStack(); + entity.saveToBucketTag(bucketItemStack); ++ org.bukkit.event.player.PlayerBucketEntityEvent playerBucketFishEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFishBucketEvent(entity, player, itemInHand, bucketItemStack, hand); ++ bucketItemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket()); ++ if (playerBucketFishEvent.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket ++ entity.resendPossiblyDesyncedEntityData((ServerPlayer) player); // Paper ++ return Optional.of(InteractionResult.FAIL); ++ } ++ entity.playSound(entity.getPickupSound(), 1.0F, 1.0F); ++ // CraftBukkit end + ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, bucketItemStack, false); + player.setItemInHand(hand, itemStack); + Level level = entity.level(); +@@ -98,7 +_,7 @@ + CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer)player, bucketItemStack); + } + +- entity.discard(); ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + return Optional.of(InteractionResult.SUCCESS); + } else { + return Optional.empty(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch new file mode 100644 index 0000000000..01deda0a89 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch @@ -0,0 +1,75 @@ +--- a/net/minecraft/world/entity/animal/Cat.java ++++ b/net/minecraft/world/entity/animal/Cat.java +@@ -342,7 +_,7 @@ + TagKey tagKey = flag ? CatVariantTags.FULL_MOON_SPAWNS : CatVariantTags.DEFAULT_SPAWNS; + BuiltInRegistries.CAT_VARIANT.getRandomElementOf(tagKey, level.getRandom()).ifPresent(this::setVariant); + ServerLevel level1 = level.getLevel(); +- if (level1.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK).isValid()) { ++ if (level1.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK, level).isValid()) { // Paper - Fix swamp hut cat generation deadlock + this.setVariant(BuiltInRegistries.CAT_VARIANT.getOrThrow(CatVariant.ALL_BLACK)); + this.setPersistenceRequired(); + } +@@ -359,6 +_,11 @@ + if (item instanceof DyeItem dyeItem) { + DyeColor dyeColor = dyeItem.getDyeColor(); + if (dyeColor != this.getCollarColor()) { ++ // Paper start - Add EntityDyeEvent and CollarColorable interface ++ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) enumcolor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity()); ++ if (!event.callEvent()) return InteractionResult.FAIL; ++ dyeColor = DyeColor.byId(event.getColor().getWoolData()); ++ // Paper end - Add EntityDyeEvent and CollarColorable interface + if (!this.level().isClientSide()) { + this.setCollarColor(dyeColor); + itemInHand.consume(1, player); +@@ -371,7 +_,7 @@ + if (!this.level().isClientSide()) { + this.usePlayerItem(player, hand, itemInHand); + FoodProperties foodProperties = itemInHand.get(DataComponents.FOOD); +- this.heal(foodProperties != null ? foodProperties.nutrition() : 1.0F); ++ this.heal(foodProperties != null ? foodProperties.nutrition() : 1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // Paper - Add missing regain reason + this.playEatingSound(); + } + +@@ -433,7 +_,7 @@ + } + + private void tryToTame(Player player) { +- if (this.random.nextInt(3) == 0) { ++ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit + this.tame(player); + this.setOrderedToSit(true); + this.level().broadcastEntityEvent(this, (byte)7); +@@ -567,15 +_,20 @@ + .dropFromGiftLootTable( + getServerLevel(this.cat), + BuiltInLootTables.CAT_MORNING_GIFT, +- (serverLevel, itemStack) -> serverLevel.addFreshEntity( +- new ItemEntity( ++ (serverLevel, itemStack) -> { ++ // CraftBukkit start ++ ItemEntity item = new ItemEntity( + serverLevel, + (double)mutableBlockPos.getX() - Mth.sin(this.cat.yBodyRot * (float) (Math.PI / 180.0)), + mutableBlockPos.getY(), + (double)mutableBlockPos.getZ() + Mth.cos(this.cat.yBodyRot * (float) (Math.PI / 180.0)), + itemStack +- ) +- ) ++ ); ++ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.cat.getBukkitEntity(), (org.bukkit.entity.Item) item.getBukkitEntity()); ++ if (!event.callEvent()) return; ++ serverLevel.addFreshEntity(item); ++ // CraftBukkit end ++ } + ); + } + +@@ -602,7 +_,7 @@ + + static class CatTemptGoal extends TemptGoal { + @Nullable +- private Player selectedPlayer; ++ private LivingEntity selectedPlayer; // CraftBukkit + private final Cat cat; + + public CatTemptGoal(Cat cat, double speedModifier, Predicate items, boolean canScare) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch new file mode 100644 index 0000000000..a95bdb6673 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/entity/animal/Chicken.java ++++ b/net/minecraft/world/entity/animal/Chicken.java +@@ -91,10 +_,12 @@ + + this.flap = this.flap + this.flapping * 2.0F; + if (this.level() instanceof ServerLevel serverLevel && this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggTime <= 0) { ++ this.forceDrops = true; // CraftBukkit + if (this.dropFromGiftLootTable(serverLevel, BuiltInLootTables.CHICKEN_LAY, this::spawnAtLocation)) { + this.playSound(SoundEvents.CHICKEN_EGG, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + this.gameEvent(GameEvent.ENTITY_PLACE); + } ++ this.forceDrops = false; // CraftBukkit + + this.eggTime = this.random.nextInt(6000) + 6000; + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch new file mode 100644 index 0000000000..c8bd9cb88e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/entity/animal/Cow.java ++++ b/net/minecraft/world/entity/animal/Cow.java +@@ -88,8 +_,15 @@ + public InteractionResult mobInteract(Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); + if (itemInHand.is(Items.BUCKET) && !this.isBaby()) { ++ // CraftBukkit start - Got milk? ++ org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); ++ if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + player.playSound(SoundEvents.COW_MILK, 1.0F, 1.0F); +- ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, Items.MILK_BUCKET.getDefaultInstance()); ++ ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit + player.setItemInHand(hand, itemStack); + return InteractionResult.SUCCESS; + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch new file mode 100644 index 0000000000..281bb05b75 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch @@ -0,0 +1,77 @@ +--- a/net/minecraft/world/entity/animal/Dolphin.java ++++ b/net/minecraft/world/entity/animal/Dolphin.java +@@ -63,6 +_,12 @@ + import net.minecraft.world.phys.Vec3; + + public class Dolphin extends AgeableWaterCreature { ++ // CraftBukkit start - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() ++ @Override ++ public int getDefaultMaxAirSupply() { ++ return TOTAL_AIR_SUPPLY; ++ } ++ // CraftBukkit end + private static final EntityDataAccessor TREASURE_POS = SynchedEntityData.defineId(Dolphin.class, EntityDataSerializers.BLOCK_POS); + private static final EntityDataAccessor GOT_FISH = SynchedEntityData.defineId(Dolphin.class, EntityDataSerializers.BOOLEAN); + private static final EntityDataAccessor MOISTNESS_LEVEL = SynchedEntityData.defineId(Dolphin.class, EntityDataSerializers.INT); +@@ -196,7 +_,7 @@ + + @Override + public int getMaxAirSupply() { +- return 4800; ++ return this.maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() + } + + @Override +@@ -229,11 +_,15 @@ + if (this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty()) { + ItemStack item = entity.getItem(); + if (this.canHoldItem(item)) { ++ // CraftBukkit start - call EntityPickupItemEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entity, 0, false).isCancelled()) return; ++ item = entity.getItem(); // CraftBukkit- update ItemStack from event ++ // CraftBukkit end + this.onItemPickup(entity); + this.setItemSlot(EquipmentSlot.MAINHAND, item); + this.setGuaranteedDrop(EquipmentSlot.MAINHAND); + this.take(entity, item.getCount()); +- entity.discard(); ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } + } + } +@@ -341,7 +_,7 @@ + + @Nullable + @Override +- protected SoundEvent getDeathSound() { ++ public SoundEvent getDeathSound() { // Paper - decompile error + return SoundEvents.DOLPHIN_DEATH; + } + +@@ -497,7 +_,7 @@ + + @Override + public void start() { +- this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin); ++ this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit + } + + @Override +@@ -516,7 +_,7 @@ + } + + if (this.player.isSwimming() && this.player.level().random.nextInt(6) == 0) { +- this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin); ++ this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit + } + } + } +@@ -586,7 +_,7 @@ + 0.3F * Mth.cos(Dolphin.this.getYRot() * (float) (Math.PI / 180.0)) * Mth.cos(Dolphin.this.getXRot() * (float) (Math.PI / 180.0)) + + Mth.sin(f1) * f2 + ); +- Dolphin.this.level().addFreshEntity(itemEntity); ++ Dolphin.this.spawnAtLocation(getServerLevel(Dolphin.this), itemEntity); // Paper - Call EntityDropItemEvent + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch new file mode 100644 index 0000000000..2db8810362 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch @@ -0,0 +1,143 @@ +--- a/net/minecraft/world/entity/animal/Fox.java ++++ b/net/minecraft/world/entity/animal/Fox.java +@@ -413,7 +_,7 @@ + + this.setSleeping(compound.getBoolean("Sleeping")); + this.setVariant(Fox.Variant.byName(compound.getString("Type"))); +- this.setSitting(compound.getBoolean("Sitting")); ++ this.setSitting(compound.getBoolean("Sitting"), false); // Paper - Add EntityToggleSitEvent + this.setIsCrouching(compound.getBoolean("Crouching")); + if (this.level() instanceof ServerLevel) { + this.setTargetGoals(); +@@ -425,6 +_,12 @@ + } + + public void setSitting(boolean sitting) { ++ // Paper start - Add EntityToggleSitEvent ++ this.setSitting(sitting, true); ++ } ++ public void setSitting(boolean sitting, boolean fireEvent) { ++ if (fireEvent && !new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), sitting).callEvent()) return; ++ // Paper end - Add EntityToggleSitEvent + this.setFlag(1, sitting); + } + +@@ -484,19 +_,20 @@ + itemEntity.setPickUpDelay(40); + itemEntity.setThrower(this); + this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F); +- this.level().addFreshEntity(itemEntity); ++ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), itemEntity); // Paper - Call EntityDropItemEvent + } + } + + private void dropItemStack(ItemStack stack) { + ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), stack); +- this.level().addFreshEntity(itemEntity); ++ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), itemEntity); // Paper - Call EntityDropItemEvent + } + + @Override + protected void pickUpItem(ServerLevel level, ItemEntity entity) { + ItemStack item = entity.getItem(); +- if (this.canHoldItem(item)) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entity, item.getCount() - 1, !this.canHoldItem(item)).isCancelled()) { // CraftBukkit - call EntityPickupItemEvent ++ item = entity.getItem(); // CraftBukkit - update item after event + int count = item.getCount(); + if (count > 1) { + this.dropItemStack(item.split(count - 1)); +@@ -507,7 +_,7 @@ + this.setItemSlot(EquipmentSlot.MAINHAND, item.split(1)); + this.setGuaranteedDrop(EquipmentSlot.MAINHAND); + this.take(entity, item.getCount()); +- entity.discard(); ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + this.ticksSinceEaten = 0; + } + } +@@ -671,15 +_,33 @@ + return this.getTrustedUUIDs().contains(uuid); + } + +- @Override +- protected void dropAllDeathLoot(ServerLevel level, DamageSource damageSource) { ++ // Paper start - handle the bitten item separately like vanilla ++ @Override ++ protected boolean shouldSkipLoot(EquipmentSlot slot) { ++ return slot == EquipmentSlot.MAINHAND; ++ } ++ // Paper end ++ ++ @Override ++ // Paper start - Cancellable death event ++ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(ServerLevel level, DamageSource damageSource) { + ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.MAINHAND); +- if (!itemBySlot.isEmpty()) { ++ boolean releaseMouth = false; ++ if (!itemBySlot.isEmpty() && level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Fix MC-153010 + this.spawnAtLocation(level, itemBySlot); ++ releaseMouth = true; ++ } ++ ++ org.bukkit.event.entity.EntityDeathEvent deathEvent = super.dropAllDeathLoot(level, damageSource); ++ // Below is code to drop ++ if (deathEvent == null || deathEvent.isCancelled()) return deathEvent; ++ ++ if (releaseMouth) { ++ // Paper end + this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); + } + +- super.dropAllDeathLoot(level, damageSource); ++ return deathEvent; // Paper - Cancellable death event + } + + public static boolean isPathClear(Fox fox, LivingEntity livingEntity) { +@@ -853,6 +_,14 @@ + if (loveCause1 != null && loveCause != loveCause1) { + fox.addTrustedUUID(loveCause1.getUUID()); + } ++ // CraftBukkit start - call EntityBreedEvent ++ fox.setAge(-24000); ++ fox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F); ++ int experience = this.animal.getRandom().nextInt(7) + 1; ++ org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(fox, this.animal, this.partner, loveCause, this.animal.breedItem, experience); ++ if (entityBreedEvent.isCancelled()) return; ++ experience = entityBreedEvent.getExperience(); ++ // CraftBukkit end + + if (serverPlayer != null) { + serverPlayer.awardStat(Stats.ANIMALS_BRED); +@@ -863,15 +_,17 @@ + this.partner.setAge(6000); + this.animal.resetLove(); + this.partner.resetLove(); +- fox.setAge(-24000); +- fox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F); +- serverLevel.addFreshEntityWithPassengers(fox); ++ level.addFreshEntityWithPassengers(fox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + this.level.broadcastEntityEvent(this.animal, (byte)18); + if (serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +- this.level +- .addFreshEntity( +- new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1) +- ); ++ // CraftBukkit start - use event experience ++ if (experience > 0) { ++ this.level ++ .addFreshEntity( ++ new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper ++ ); ++ } ++ // CraftBukkit end + } + } + } +@@ -934,6 +_,7 @@ + private void pickSweetBerries(BlockState state) { + int ageValue = state.getValue(SweetBerryBushBlock.AGE); + state.setValue(SweetBerryBushBlock.AGE, Integer.valueOf(1)); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(Fox.this, this.blockPos, state.setValue(SweetBerryBushBlock.AGE, 1))) return; // CraftBukkit - call EntityChangeBlockEvent + int i = 1 + Fox.this.level().random.nextInt(2) + (ageValue == 3 ? 1 : 0); + ItemStack itemBySlot = Fox.this.getItemBySlot(EquipmentSlot.MAINHAND); + if (itemBySlot.isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch new file mode 100644 index 0000000000..3af59e7fb7 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/entity/animal/IronGolem.java ++++ b/net/minecraft/world/entity/animal/IronGolem.java +@@ -104,7 +_,7 @@ + @Override + protected void doPush(Entity entity) { + if (entity instanceof Enemy && !(entity instanceof Creeper) && this.getRandom().nextInt(20) == 0) { +- this.setTarget((LivingEntity)entity); ++ this.setTarget((LivingEntity)entity, org.bukkit.event.entity.EntityTargetLivingEntityEvent.TargetReason.COLLISION, true); // CraftBukkit - set reason + } + + super.doPush(entity); +@@ -303,7 +_,7 @@ + BlockPos blockPos = this.blockPosition(); + BlockPos blockPos1 = blockPos.below(); + BlockState blockState = level.getBlockState(blockPos1); +- if (!blockState.entityCanStandOn(level, blockPos1, this)) { ++ if (!blockState.entityCanStandOn(level, blockPos1, this) && !this.level().paperConfig().entities.spawning.ironGolemsCanSpawnInAir) { // Paper - Add option to allow iron golems to spawn in air + return false; + } else { + for (int i = 1; i < 3; i++) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch new file mode 100644 index 0000000000..3b9b4c2f06 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch @@ -0,0 +1,59 @@ +--- a/net/minecraft/world/entity/animal/MushroomCow.java ++++ b/net/minecraft/world/entity/animal/MushroomCow.java +@@ -110,7 +_,17 @@ + return InteractionResult.SUCCESS; + } else if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) { + if (this.level() instanceof ServerLevel serverLevel) { +- this.shear(serverLevel, SoundSource.PLAYERS, itemInHand); ++ // CraftBukkit start ++ // Paper start - custom shear drops ++ java.util.List drops = this.generateDefaultDrops(serverLevel, itemInHand); ++ org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemInHand, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) return InteractionResult.PASS; ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops ++ } ++ // CraftBukkit end ++ this.shear(serverLevel, SoundSource.PLAYERS, itemInHand, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); + } +@@ -163,15 +_,32 @@ + + @Override + public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { ++ // Paper start - custom shear drops ++ this.shear(level, soundSource, shears, this.generateDefaultDrops(level, shears)); ++ } ++ ++ @Override ++ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (ignored, stack) -> { ++ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1)); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List drops) { ++ // Paper end + level.playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, soundSource, 1.0F, 1.0F); + this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), mob -> { + level.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0); +- this.dropFromShearingLootTable(level, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (serverLevel, itemStack) -> { +- for (int i = 0; i < itemStack.getCount(); i++) { +- serverLevel.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), itemStack.copyWithCount(1))); +- } ++ // Paper start - custom shear drops; moved drop generation to separate method ++ drops.forEach(drop -> { ++ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop); ++ this.spawnAtLocation(level, entityitem); + }); +- }); ++ // Paper end - custom shear drops ++ }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch new file mode 100644 index 0000000000..0d5245ce20 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/entity/animal/Ocelot.java ++++ b/net/minecraft/world/entity/animal/Ocelot.java +@@ -125,7 +_,7 @@ + + @Override + public boolean removeWhenFarAway(double distanceToClosestPlayer) { +- return !this.isTrusting() && this.tickCount > 2400; ++ return !this.isTrusting() && this.tickCount > 2400 && !this.hasCustomName() && !this.isLeashed(); // Paper - honor name and leash + } + + public static AttributeSupplier.Builder createAttributes() { +@@ -159,7 +_,7 @@ + if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemInHand) && player.distanceToSqr(this) < 9.0) { + this.usePlayerItem(player, hand, itemInHand); + if (!this.level().isClientSide) { +- if (this.random.nextInt(3) == 0) { ++ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call and isCancelled check + this.setTrusting(true); + this.spawnTrustingParticles(true); + this.level().broadcastEntityEvent(this, (byte)41); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch new file mode 100644 index 0000000000..3e9a850886 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch @@ -0,0 +1,81 @@ +--- a/net/minecraft/world/entity/animal/Panda.java ++++ b/net/minecraft/world/entity/animal/Panda.java +@@ -127,6 +_,7 @@ + } + + public void sit(boolean sitting) { ++ if (!new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), sitting).callEvent()) return; // Paper - Add EntityToggleSitEvent + this.setFlag(8, sitting); + } + +@@ -516,24 +_,28 @@ + + for (Panda panda : level.getEntitiesOfClass(Panda.class, this.getBoundingBox().inflate(10.0))) { + if (!panda.isBaby() && panda.onGround() && !panda.isInWater() && panda.canPerformAction()) { ++ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper - Entity Jump API + panda.jumpFromGround(); ++ } else { this.setJumping(false); } // Paper - Entity Jump API; setJumping(false) stops a potential loop + } + } + + if (this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ this.forceDrops = true; // Paper - Add missing forceDrop toggles + this.dropFromGiftLootTable(serverLevel, BuiltInLootTables.PANDA_SNEEZE, this::spawnAtLocation); ++ this.forceDrops = false; // Paper - Add missing forceDrop toggles + } + } + + @Override + protected void pickUpItem(ServerLevel level, ItemEntity entity) { +- if (this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty() && canPickUpAndEat(entity)) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entity, 0, !(this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty() && Panda.canPickUpAndEat(entity))).isCancelled()) { // CraftBukkit + this.onItemPickup(entity); + ItemStack item = entity.getItem(); + this.setItemSlot(EquipmentSlot.MAINHAND, item); + this.setGuaranteedDrop(EquipmentSlot.MAINHAND); + this.take(entity, item.getCount()); +- entity.discard(); ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } + } + +@@ -624,8 +_,9 @@ + this.usePlayerItem(player, hand, itemInHand); + this.ageUp((int)(-this.getAge() / 20 * 0.1F), true); + } else if (!this.level().isClientSide && this.getAge() == 0 && this.canFallInLove()) { ++ final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying + this.usePlayerItem(player, hand, itemInHand); +- this.setInLove(player); ++ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying + } else { + if (!(this.level() instanceof ServerLevel serverLevel) || this.isSitting() || this.isInWater()) { + return InteractionResult.PASS; +@@ -635,7 +_,9 @@ + this.eat(true); + ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.MAINHAND); + if (!itemBySlot.isEmpty() && !player.hasInfiniteMaterials()) { ++ this.forceDrops = true; // Paper - Add missing forceDrop toggles + this.spawnAtLocation(serverLevel, itemBySlot); ++ this.forceDrops = false; // Paper - Add missing forceDrop toggles + } + + this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemInHand.getItem(), 1)); +@@ -861,7 +_,7 @@ + @Override + protected void alertOther(Mob mob, LivingEntity target) { + if (mob instanceof Panda && mob.isAggressive()) { +- mob.setTarget(target); ++ mob.setTarget(target, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit + } + } + } +@@ -1090,7 +_,9 @@ + public void stop() { + ItemStack itemBySlot = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND); + if (!itemBySlot.isEmpty()) { ++ Panda.this.forceDrops = true; // Paper - Add missing forceDrop toggles + Panda.this.spawnAtLocation(getServerLevel(Panda.this.level()), itemBySlot); ++ Panda.this.forceDrops = false; // Paper - Add missing forceDrop toggles + Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); + int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10; + this.cooldown = Panda.this.tickCount + i * 20; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Parrot.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch similarity index 73% rename from paper-server/patches/unapplied/net/minecraft/world/entity/animal/Parrot.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch index e42863c2b1..554ab3d969 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Parrot.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch @@ -1,24 +1,24 @@ --- a/net/minecraft/world/entity/animal/Parrot.java +++ b/net/minecraft/world/entity/animal/Parrot.java -@@ -248,7 +248,7 @@ +@@ -257,7 +_,7 @@ } if (!this.level().isClientSide) { - if (this.random.nextInt(10) == 0) { + if (this.random.nextInt(10) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit this.tame(player); - this.level().broadcastEntityEvent(this, (byte) 7); + this.level().broadcastEntityEvent(this, (byte)7); } else { -@@ -269,7 +269,7 @@ +@@ -278,7 +_,7 @@ } } else { - this.usePlayerItem(player, hand, itemstack); + this.usePlayerItem(player, hand, itemInHand); - this.addEffect(new MobEffectInstance(MobEffects.POISON, 900)); + this.addEffect(new MobEffectInstance(MobEffects.POISON, 900), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // CraftBukkit if (player.isCreative() || !this.isInvulnerable()) { this.hurt(this.damageSources().playerAttack(player), Float.MAX_VALUE); } -@@ -362,8 +362,8 @@ +@@ -373,8 +_,8 @@ } @Override @@ -29,19 +29,16 @@ } @Override -@@ -378,8 +378,14 @@ - if (this.isInvulnerableTo(world, source)) { +@@ -387,10 +_,11 @@ + @Override + public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { + if (this.isInvulnerableTo(level, damageSource)) { ++ if (!super.hurtServer(level, damageSource, amount)) return false; // CraftBukkit return false; } else { -+ // CraftBukkit start -+ boolean result = super.hurtServer(world, source, amount); -+ if (!result) { -+ return result; -+ } -+ // CraftBukkit end this.setOrderedToSit(false); -- return super.hurtServer(world, source, amount); -+ return result; // CraftBukkit +- return super.hurtServer(level, damageSource, amount); ++ return true; // CraftBukkit } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch new file mode 100644 index 0000000000..31833a8584 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/entity/animal/Pig.java ++++ b/net/minecraft/world/entity/animal/Pig.java +@@ -214,7 +_,14 @@ + } + + mob.setPersistenceRequired(); +- }); ++ // CraftBukkit start ++ }, null, null); ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPigZapEvent(this, lightning, zombifiedPiglin).isCancelled()) { ++ return; ++ } ++ level.addFreshEntity(zombifiedPiglin, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause ++ // CraftBukkit end + if (zombifiedPiglin == null) { + super.thunderHit(level, lightning); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Pufferfish.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch similarity index 67% rename from paper-server/patches/unapplied/net/minecraft/world/entity/animal/Pufferfish.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch index 32042a8ba6..bd25f044bc 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Pufferfish.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Pufferfish.java +++ b/net/minecraft/world/entity/animal/Pufferfish.java -@@ -102,25 +102,39 @@ +@@ -95,24 +_,36 @@ public void tick() { if (!this.level().isClientSide && this.isAlive() && this.isEffectiveAi()) { if (this.inflateCounter > 0) { @@ -17,9 +17,8 @@ + } else { increase = false; } // Paper - Add PufferFishStateChangeEvent } -+ if (increase) { // Paper - Add PufferFishStateChangeEvent - ++this.inflateCounter; -+ } // Paper - Add PufferFishStateChangeEvent ++ if (increase) // Paper - Add PufferFishStateChangeEvent + this.inflateCounter++; } else if (this.getPuffState() != 0) { + boolean increase = true; // Paper - Add PufferFishStateChangeEvent if (this.deflateTimer > 60 && this.getPuffState() == 2) { @@ -34,27 +33,25 @@ + } else { increase = false; } // Paper - Add PufferFishStateChangeEvent } -+ if (increase) { // Paper - Add PufferFishStateChangeEvent - ++this.deflateTimer; -+ } // Paper - Add PufferFishStateChangeEvent ++ if (increase) // Paper - Add PufferFishStateChangeEvent + this.deflateTimer++; } } - -@@ -155,7 +169,7 @@ - int i = this.getPuffState(); - - if (target.hurtServer(world, this.damageSources().mobAttack(this), (float) (1 + i))) { -- target.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * i, 0), this); -+ target.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * i, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit +@@ -136,7 +_,7 @@ + private void touch(ServerLevel level, Mob mob) { + int puffState = this.getPuffState(); + if (mob.hurtServer(level, this.damageSources().mobAttack(this), 1 + puffState)) { +- mob.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * puffState, 0), this); ++ mob.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * puffState, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit this.playSound(SoundEvents.PUFFER_FISH_STING, 1.0F, 1.0F); } - -@@ -171,7 +185,7 @@ - entityplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.PUFFER_FISH_STING, 0.0F)); - } - -- player.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * i, 0), this); -+ player.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * i, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit + } +@@ -151,7 +_,7 @@ + serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.PUFFER_FISH_STING, 0.0F)); } - } + +- entity.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * puffState, 0), this); ++ entity.addEffect(new MobEffectInstance(MobEffects.POISON, 60 * puffState, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch new file mode 100644 index 0000000000..d5d3f133b3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/world/entity/animal/Rabbit.java ++++ b/net/minecraft/world/entity/animal/Rabbit.java +@@ -88,7 +_,7 @@ + super(entityType, level); + this.jumpControl = new Rabbit.RabbitJumpControl(this); + this.moveControl = new Rabbit.RabbitMoveControl(this); +- this.setSpeedModifier(0.0); ++ //this.setSpeedModifier(0.0); // CraftBukkit + } + + @Override +@@ -561,9 +_,11 @@ + if (this.canRaid && block instanceof CarrotBlock) { + int ageValue = blockState.getValue(CarrotBlock.AGE); + if (ageValue == 0) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockPos, blockState.getFluidState().createLegacyBlock())) return; // CraftBukkit // Paper - fix wrong block state + level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 2); + level.destroyBlock(blockPos, true, this.rabbit); + } else { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockPos, blockState.setValue(CarrotBlock.AGE, ageValue - 1))) return; // CraftBukkit // Paper - fix wrong block state + level.setBlock(blockPos, blockState.setValue(CarrotBlock.AGE, Integer.valueOf(ageValue - 1)), 2); + level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(this.rabbit)); + level.levelEvent(2001, blockPos, Block.getId(blockState)); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Sheep.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Sheep.java.patch new file mode 100644 index 0000000000..07a19159a6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Sheep.java.patch @@ -0,0 +1,75 @@ +--- a/net/minecraft/world/entity/animal/Sheep.java ++++ b/net/minecraft/world/entity/animal/Sheep.java +@@ -40,7 +_,6 @@ + import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; + import net.minecraft.world.entity.item.ItemEntity; + import net.minecraft.world.entity.player.Player; +-import net.minecraft.world.item.DyeColor; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.item.Items; + import net.minecraft.world.level.Level; +@@ -158,7 +_,19 @@ + ItemStack itemInHand = player.getItemInHand(hand); + if (itemInHand.is(Items.SHEARS)) { + if (this.level() instanceof ServerLevel serverLevel && this.readyForShearing()) { +- this.shear(serverLevel, SoundSource.PLAYERS, itemInHand); ++ // CraftBukkit start ++ // Paper start - custom shear drops ++ java.util.List drops = this.generateDefaultDrops(serverLevel, itemInHand); ++ org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemInHand, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops ++ } ++ // CraftBukkit end ++ this.shear(serverLevel, SoundSource.PLAYERS, itemInHand, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); + return InteractionResult.SUCCESS_SERVER; +@@ -172,14 +_,28 @@ + + @Override + public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { ++ // Paper start - custom shear drops ++ this.shear(level, soundSource, shears, this.generateDefaultDrops(level, shears)); ++ } ++ ++ @Override ++ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SHEEP, shears, (ignored, stack) -> { ++ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1)); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List drops) { ++ // Paper end - custom shear drops + level.playSound(null, this, SoundEvents.SHEEP_SHEAR, soundSource, 1.0F, 1.0F); +- this.dropFromShearingLootTable( +- level, +- BuiltInLootTables.SHEAR_SHEEP, +- shears, +- (serverLevel, itemStack) -> { +- for (int i = 0; i < itemStack.getCount(); i++) { +- ItemEntity itemEntity = this.spawnAtLocation(serverLevel, itemStack.copyWithCount(1), 1.0F); ++ drops.forEach(itemstack1 -> { // Paper - custom drops - loop in generated default drops ++ if (true) { // Paper - custom drops - loop in generated default drops ++ this.forceDrops = true; // CraftBukkit ++ ItemEntity itemEntity = this.spawnAtLocation(level, itemstack1, 1.0F); // Paper - custom drops - copy already done above ++ this.forceDrops = false; // CraftBukkit + if (itemEntity != null) { + itemEntity.setDeltaMovement( + itemEntity.getDeltaMovement() +@@ -287,6 +_,7 @@ + + @Override + public void ate() { ++ if (!new org.bukkit.event.entity.SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity()).callEvent()) return; // CraftBukkit + super.ate(); + this.setSheared(false); + if (this.isBaby()) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch new file mode 100644 index 0000000000..367ba239ff --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/animal/ShoulderRidingEntity.java ++++ b/net/minecraft/world/entity/animal/ShoulderRidingEntity.java +@@ -19,7 +_,7 @@ + compoundTag.putString("id", this.getEncodeId()); + this.saveWithoutId(compoundTag); + if (player.setEntityOnShoulder(compoundTag)) { +- this.discard(); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + return true; + } else { + return false; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch new file mode 100644 index 0000000000..c168577210 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch @@ -0,0 +1,74 @@ +--- a/net/minecraft/world/entity/animal/SnowGolem.java ++++ b/net/minecraft/world/entity/animal/SnowGolem.java +@@ -92,7 +_,7 @@ + super.aiStep(); + if (this.level() instanceof ServerLevel serverLevel) { + if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) { +- this.hurtServer(serverLevel, this.damageSources().onFire(), 1.0F); ++ this.hurtServer(serverLevel, this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING + } + + if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { +@@ -107,7 +_,7 @@ + int floor2 = Mth.floor(this.getZ() + (i / 2 % 2 * 2 - 1) * 0.25F); + BlockPos blockPos = new BlockPos(floor, floor1, floor2); + if (this.level().getBlockState(blockPos).isAir() && blockState.canSurvive(this.level(), blockPos)) { +- this.level().setBlockAndUpdate(blockPos, blockState); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this.level(), blockPos, blockState, this)) continue; // CraftBukkit + this.level().gameEvent(GameEvent.BLOCK_PLACE, blockPos, GameEvent.Context.of(this, blockState)); + } + } +@@ -135,7 +_,19 @@ + ItemStack itemInHand = player.getItemInHand(hand); + if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) { + if (this.level() instanceof ServerLevel serverLevel) { +- this.shear(serverLevel, SoundSource.PLAYERS, itemInHand); ++ // CraftBukkit start ++ // Paper start - custom shear drops ++ java.util.List drops = this.generateDefaultDrops(serverLevel, itemInHand); ++ org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemInHand, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops ++ } ++ // CraftBukkit end ++ this.shear(serverLevel, SoundSource.PLAYERS, itemInHand, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); + } +@@ -148,11 +_,29 @@ + + @Override + public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { ++ // Paper start - custom shear drops ++ this.shear(level, soundSource, shears, this.generateDefaultDrops(level, shears)); ++ } ++ ++ @Override ++ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (ignored, stack) -> { ++ drops.add(stack); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List drops) { ++ // Paper end - custom shear drops + level.playSound(null, this, SoundEvents.SNOW_GOLEM_SHEAR, soundSource, 1.0F, 1.0F); + this.setPumpkin(false); +- this.dropFromShearingLootTable( +- level, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (serverLevel, itemStack) -> this.spawnAtLocation(serverLevel, itemStack, this.getEyeHeight()) +- ); ++ drops.forEach(itemstack1 -> { // Paper - custom shear drops ++ this.forceDrops = true; // CraftBukkit ++ this.spawnAtLocation(level, itemstack1, this.getEyeHeight()); ++ this.forceDrops = false; // CraftBukkit ++ }); + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Squid.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Squid.java.patch new file mode 100644 index 0000000000..e2fffe7466 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Squid.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/animal/Squid.java ++++ b/net/minecraft/world/entity/animal/Squid.java +@@ -46,7 +_,7 @@ + + public Squid(EntityType entityType, Level level) { + super(entityType, level); +- this.random.setSeed(this.getId()); ++ //this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random + this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; + } + 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 new file mode 100644 index 0000000000..e9232e5c94 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch @@ -0,0 +1,75 @@ +--- a/net/minecraft/world/entity/animal/Turtle.java ++++ b/net/minecraft/world/entity/animal/Turtle.java +@@ -303,7 +_,9 @@ + protected void ageBoundaryReached() { + super.ageBoundaryReached(); + if (!this.isBaby() && this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ this.forceDrops = true; // CraftBukkit + this.spawnAtLocation(serverLevel, Items.TURTLE_SCUTE, 1); ++ this.forceDrops = false; // CraftBukkit + } + } + +@@ -328,7 +_,7 @@ + + @Override + public void thunderHit(ServerLevel level, LightningBolt lightning) { +- this.hurtServer(level, this.damageSources().lightningBolt(), Float.MAX_VALUE); ++ this.hurtServer(level, this.damageSources().lightningBolt().customEventDamager(lightning), Float.MAX_VALUE); // CraftBukkit // Paper - fix DamageSource API + } + + @Override +@@ -355,6 +_,10 @@ + if (loveCause == null && this.partner.getLoveCause() != null) { + loveCause = 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 (loveCause != null) { + loveCause.awardStat(Stats.ANIMALS_BRED); +@@ -368,7 +_,7 @@ + this.partner.resetLove(); + RandomSource random = this.animal.getRandom(); + if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), random.nextInt(7) + 1)); ++ 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, loveCause)); // Paper - Add EntityFertilizeEggEvent event + } + } + } +@@ -392,7 +_,7 @@ + this.turtle.hasEgg() + || this.turtle.getRandom().nextInt(reducedTickDelay(700)) == 0 + && !this.turtle.getHomePos().closerToCenterThan(this.turtle.position(), 64.0) +- ); ++ ) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity()).callEvent(); // Paper - Turtle API + } + + @Override +@@ -500,16 +_,22 @@ + BlockPos blockPos = this.turtle.blockPosition(); + if (!this.turtle.isInWater() && this.isReachedTarget()) { + if (this.turtle.layEggCounter < 1) { +- this.turtle.setLayingEgg(true); ++ this.turtle.setLayingEgg(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level(), this.blockPos)).callEvent()); // Paper - Turtle API + } else if (this.turtle.layEggCounter > this.adjustedTickDelay(200)) { ++ // Paper start - Turtle API ++ int eggCount = this.turtle.random.nextInt(4) + 1; ++ com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level(), this.blockPos.above()), eggCount); ++ if (layEggEvent.callEvent() && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()))) { ++ // Paper end + Level level = this.turtle.level(); + level.playSound(null, blockPos, SoundEvents.TURTLE_LAY_EGG, SoundSource.BLOCKS, 0.3F, 0.9F + level.random.nextFloat() * 0.2F); + BlockPos blockPos1 = this.blockPos.above(); + BlockState blockState = Blocks.TURTLE_EGG + .defaultBlockState() +- .setValue(TurtleEggBlock.EGGS, Integer.valueOf(this.turtle.random.nextInt(4) + 1)); ++ .setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()); // Paper + level.setBlock(blockPos1, blockState, 3); + level.gameEvent(GameEvent.BLOCK_PLACE, blockPos1, GameEvent.Context.of(this.turtle, blockState)); ++ } // Paper + this.turtle.setHasEgg(false); + this.turtle.setLayingEgg(false); + this.turtle.setInLoveTime(600); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/WaterAnimal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/WaterAnimal.java.patch new file mode 100644 index 0000000000..f871cf2552 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/WaterAnimal.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/entity/animal/WaterAnimal.java ++++ b/net/minecraft/world/entity/animal/WaterAnimal.java +@@ -70,6 +_,10 @@ + ) { + int seaLevel = level.getSeaLevel(); + int i = seaLevel - 13; ++ // Paper start - Make water animal spawn height configurable ++ seaLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(seaLevel); ++ i = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(i); ++ // Paper end - Make water animal spawn height configurable + return pos.getY() >= i + && pos.getY() <= seaLevel + && level.getFluidState(pos.below()).is(FluidTags.WATER) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch new file mode 100644 index 0000000000..f162736896 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch @@ -0,0 +1,95 @@ +--- a/net/minecraft/world/entity/animal/Wolf.java ++++ b/net/minecraft/world/entity/animal/Wolf.java +@@ -344,8 +_,9 @@ + if (this.isInvulnerableTo(level, damageSource)) { + return false; + } else { ++ if (!super.hurtServer(level, damageSource, amount)) return false; // CraftBukkit + this.setOrderedToSit(false); +- return super.hurtServer(level, damageSource, amount); ++ return true; // CraftBUkkit + } + } + +@@ -355,10 +_,11 @@ + } + + @Override +- protected void actuallyHurt(ServerLevel level, DamageSource damageSource, float amount) { ++ public boolean actuallyHurt(ServerLevel level, DamageSource damageSource, float amount, org.bukkit.event.entity.EntityDamageEvent event) { // CraftBukkit - void -> boolean + if (!this.canArmorAbsorb(damageSource)) { +- super.actuallyHurt(level, damageSource, amount); ++ super.actuallyHurt(level, damageSource, amount, event); // CraftBukkit + } else { ++ if (event.isCancelled()) return false; // CraftBukkit - SPIGOT-7815: if the damage was cancelled, no need to run the wolf armor behaviour + ItemStack bodyArmorItem = this.getBodyArmorItem(); + int damageValue = bodyArmorItem.getDamageValue(); + int maxDamage = bodyArmorItem.getMaxDamage(); +@@ -378,6 +_,7 @@ + ); + } + } ++ return true; // CraftBukkit // Paper - return false ONLY if event was cancelled + } + + private boolean canArmorAbsorb(DamageSource damageSource) { +@@ -388,7 +_,7 @@ + protected void applyTamingSideEffects() { + if (this.isTame()) { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(40.0); +- this.setHealth(40.0F); ++ this.setHealth(this.getMaxHealth()); // CraftBukkit - 40.0 -> getMaxHealth() + } else { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(8.0); + } +@@ -408,7 +_,7 @@ + this.usePlayerItem(player, hand, itemInHand); + FoodProperties foodProperties = itemInHand.get(DataComponents.FOOD); + float f = foodProperties != null ? foodProperties.nutrition() : 1.0F; +- this.heal(2.0F * f); ++ this.heal(2.0F * f, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit + return InteractionResult.SUCCESS; + } + +@@ -441,7 +_,7 @@ + this.setOrderedToSit(!this.isOrderedToSit()); + this.jumping = false; + this.navigation.stop(); +- this.setTarget(null); ++ this.setTarget(null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason + return InteractionResult.SUCCESS.withoutItem(); + } + +@@ -453,7 +_,9 @@ + ItemStack bodyArmorItem = this.getBodyArmorItem(); + this.setBodyArmorItem(ItemStack.EMPTY); + if (this.level() instanceof ServerLevel serverLevel) { ++ this.forceDrops = true; // CraftBukkit + this.spawnAtLocation(serverLevel, bodyArmorItem); ++ this.forceDrops = false; // CraftBukkit + } + + return InteractionResult.SUCCESS; +@@ -461,6 +_,13 @@ + + DyeColor dyeColor = dyeItem.getDyeColor(); + if (dyeColor != this.getCollarColor()) { ++ // Paper start - Add EntityDyeEvent and CollarColorable interface ++ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) dyeColor.getId()), player.getBukkitEntity()); ++ if (!event.callEvent()) { ++ return InteractionResult.FAIL; ++ } ++ dyeColor = DyeColor.byId(event.getColor().getWoolData()); ++ // Paper end - Add EntityDyeEvent and CollarColorable interface + this.setCollarColor(dyeColor); + itemInHand.consume(1, player); + return InteractionResult.SUCCESS; +@@ -475,7 +_,7 @@ + } + + private void tryToTame(Player player) { +- if (this.random.nextInt(3) == 0) { ++ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call and isCancelled check. + this.tame(player); + this.navigation.stop(); + this.setTarget(null); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Animal.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Animal.java.patch deleted file mode 100644 index f8c533216c..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Animal.java.patch +++ /dev/null @@ -1,141 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Animal.java -+++ b/net/minecraft/world/entity/animal/Animal.java -@@ -35,12 +35,20 @@ - import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.pathfinder.PathType; - -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityBreedEvent; -+import org.bukkit.event.entity.EntityDamageEvent; -+import org.bukkit.event.entity.EntityEnterLoveModeEvent; -+// CraftBukkit end -+ - public abstract class Animal extends AgeableMob { - - protected static final int PARENT_AGE_AFTER_BREEDING = 6000; - public int inLove; - @Nullable - public UUID loveCause; -+ public ItemStack breedItem; // CraftBukkit - Add breedItem variable - - protected Animal(EntityType type, Level world) { - super(type, world); -@@ -82,9 +90,15 @@ - } - - @Override -- protected void actuallyHurt(ServerLevel world, DamageSource source, float amount) { -+ // CraftBukkit start - void -> boolean -+ public boolean actuallyHurt(ServerLevel worldserver, DamageSource damagesource, float f, EntityDamageEvent event) { -+ boolean damageResult = super.actuallyHurt(worldserver, damagesource, f, event); -+ if (!damageResult) { -+ return false; -+ } - this.resetLove(); -- super.actuallyHurt(world, source, amount); -+ return true; -+ // CraftBukkit end - } - - @Override -@@ -144,8 +158,9 @@ - int i = this.getAge(); - - if (!this.level().isClientSide && i == 0 && this.canFallInLove()) { -+ final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying - this.usePlayerItem(player, hand, itemstack); -- this.setInLove(player); -+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying - this.playEatingSound(); - return InteractionResult.SUCCESS_SERVER; - } -@@ -187,11 +202,26 @@ - return this.inLove <= 0; - } - -+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Fix EntityBreedEvent copying - public void setInLove(@Nullable Player player) { -- this.inLove = 600; -+ // Paper start - Fix EntityBreedEvent copying -+ this.setInLove(player, null); -+ } -+ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) { -+ if (breedItemCopy != null) this.breedItem = breedItemCopy; -+ // Paper end - Fix EntityBreedEvent copying -+ // CraftBukkit start -+ EntityEnterLoveModeEvent entityEnterLoveModeEvent = CraftEventFactory.callEntityEnterLoveModeEvent(player, this, 600); -+ if (entityEnterLoveModeEvent.isCancelled()) { -+ this.breedItem = null; // Paper - Fix EntityBreedEvent copying; clear if cancelled -+ return; -+ } -+ this.inLove = entityEnterLoveModeEvent.getTicksInLove(); -+ // CraftBukkit end - if (player != null) { - this.loveCause = player.getUUID(); - } -+ // Paper - Fix EntityBreedEvent copying; set breed item in better place - - this.level().broadcastEntityEvent(this, (byte) 18); - } -@@ -233,25 +263,48 @@ - if (entityageable != null) { - entityageable.setBaby(true); - entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); -- this.finalizeSpawnChildFromBreeding(world, other, entityageable); -- world.addFreshEntityWithPassengers(entityageable); -+ // CraftBukkit start - call EntityBreedEvent -+ ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> { -+ return Optional.ofNullable(other.getLoveCause()); -+ }).orElse(null); -+ int experience = this.getRandom().nextInt(7) + 1; -+ EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, other, breeder, this.breedItem, experience); -+ if (entityBreedEvent.isCancelled()) { -+ return; -+ } -+ experience = entityBreedEvent.getExperience(); -+ this.finalizeSpawnChildFromBreeding(world, other, entityageable, experience); -+ world.addFreshEntityWithPassengers(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); -+ // CraftBukkit end - } - } - - public void finalizeSpawnChildFromBreeding(ServerLevel world, Animal other, @Nullable AgeableMob baby) { -- Optional.ofNullable(this.getLoveCause()).or(() -> { -- return Optional.ofNullable(other.getLoveCause()); -- }).ifPresent((entityplayer) -> { -+ // CraftBukkit start -+ this.finalizeSpawnChildFromBreeding(world, other, baby, this.getRandom().nextInt(7) + 1); -+ } -+ -+ public void finalizeSpawnChildFromBreeding(ServerLevel worldserver, Animal entityanimal, @Nullable AgeableMob entityageable, int experience) { -+ // CraftBukkit end -+ // Paper start -+ ServerPlayer entityplayer = this.getLoveCause(); -+ if (entityplayer == null) entityplayer = entityanimal.getLoveCause(); -+ if (entityplayer != null) { -+ // Paper end - entityplayer.awardStat(Stats.ANIMALS_BRED); -- CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, other, baby); -- }); -+ CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable); -+ } // Paper - this.setAge(6000); -- other.setAge(6000); -+ entityanimal.setAge(6000); - this.resetLove(); -- other.resetLove(); -- world.broadcastEntityEvent(this, (byte) 18); -- if (world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -- world.addFreshEntity(new ExperienceOrb(world, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1)); -+ entityanimal.resetLove(); -+ worldserver.broadcastEntityEvent(this, (byte) 18); -+ if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -+ // CraftBukkit start - use event experience -+ if (experience > 0) { -+ worldserver.addFreshEntity(new ExperienceOrb(worldserver, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityageable)); // Paper -+ } -+ // CraftBukkit end - } - - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Bee.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Bee.java.patch deleted file mode 100644 index 748c94de8e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Bee.java.patch +++ /dev/null @@ -1,205 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Bee.java -+++ b/net/minecraft/world/entity/animal/Bee.java -@@ -92,6 +92,11 @@ - import net.minecraft.world.level.pathfinder.Path; - import net.minecraft.world.level.pathfinder.PathType; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityPotionEffectEvent; -+import org.bukkit.event.entity.EntityTargetEvent; -+// CraftBukkit end - - public class Bee extends Animal implements NeutralMob, FlyingAnimal { - -@@ -149,7 +154,22 @@ - public Bee(EntityType type, Level world) { - super(type, world); - this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); -- this.moveControl = new FlyingMoveControl(this, 20, true); -+ // Paper start - Fix MC-167279 -+ class BeeFlyingMoveControl extends FlyingMoveControl { -+ public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) { -+ super(entity, maxPitchChange, noGravity); -+ } -+ -+ @Override -+ public void tick() { -+ if (this.mob.getY() <= Bee.this.level().getMinY()) { -+ this.mob.setNoGravity(false); -+ } -+ super.tick(); -+ } -+ } -+ this.moveControl = new BeeFlyingMoveControl(this, 20, true); -+ // Paper end - Fix MC-167279 - this.lookControl = new Bee.BeeLookControl(this); - this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F); - this.setPathfindingMalus(PathType.WATER, -1.0F); -@@ -198,21 +218,28 @@ - - @Override - public void addAdditionalSaveData(CompoundTag nbt) { -- super.addAdditionalSaveData(nbt); -- if (this.hasHive()) { -- nbt.put("hive_pos", NbtUtils.writeBlockPos(this.getHivePos())); -+ // CraftBukkit start - selectively save data -+ this.addAdditionalSaveData(nbt, true); -+ } -+ -+ @Override -+ public void addAdditionalSaveData(CompoundTag nbttagcompound, boolean includeAll) { -+ // CraftBukkit end -+ super.addAdditionalSaveData(nbttagcompound); -+ if (includeAll && this.hasHive()) { // CraftBukkit - selectively save hive -+ nbttagcompound.put("hive_pos", NbtUtils.writeBlockPos(this.getHivePos())); - } - -- if (this.hasSavedFlowerPos()) { -- nbt.put("flower_pos", NbtUtils.writeBlockPos(this.getSavedFlowerPos())); -+ if (includeAll && this.hasSavedFlowerPos()) { // CraftBukkit - selectively save flower -+ nbttagcompound.put("flower_pos", NbtUtils.writeBlockPos(this.getSavedFlowerPos())); - } - -- nbt.putBoolean("HasNectar", this.hasNectar()); -- nbt.putBoolean("HasStung", this.hasStung()); -- nbt.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive); -- nbt.putInt("CannotEnterHiveTicks", this.stayOutOfHiveCountdown); -- nbt.putInt("CropsGrownSincePollination", this.numCropsGrownSincePollination); -- this.addPersistentAngerSaveData(nbt); -+ nbttagcompound.putBoolean("HasNectar", this.hasNectar()); -+ nbttagcompound.putBoolean("HasStung", this.hasStung()); -+ nbttagcompound.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive); -+ nbttagcompound.putInt("CannotEnterHiveTicks", this.stayOutOfHiveCountdown); -+ nbttagcompound.putInt("CropsGrownSincePollination", this.numCropsGrownSincePollination); -+ this.addPersistentAngerSaveData(nbttagcompound); - } - - @Override -@@ -223,8 +250,8 @@ - this.ticksWithoutNectarSinceExitingHive = nbt.getInt("TicksSincePollination"); - this.stayOutOfHiveCountdown = nbt.getInt("CannotEnterHiveTicks"); - this.numCropsGrownSincePollination = nbt.getInt("CropsGrownSincePollination"); -- this.hivePos = (BlockPos) NbtUtils.readBlockPos(nbt, "hive_pos").orElse((Object) null); -- this.savedFlowerPos = (BlockPos) NbtUtils.readBlockPos(nbt, "flower_pos").orElse((Object) null); -+ this.hivePos = (BlockPos) NbtUtils.readBlockPos(nbt, "hive_pos").orElse(null); // CraftBukkit - decompile error -+ this.savedFlowerPos = (BlockPos) NbtUtils.readBlockPos(nbt, "flower_pos").orElse(null); // CraftBukkit - decompile error - this.readPersistentAngerSaveData(this.level(), nbt); - } - -@@ -248,7 +275,7 @@ - } - - if (b0 > 0) { -- entityliving.addEffect(new MobEffectInstance(MobEffects.POISON, b0 * 20, 0), this); -+ entityliving.addEffect(new MobEffectInstance(MobEffects.POISON, b0 * 20, 0), this, EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit - } - } - -@@ -506,7 +533,12 @@ - - @Nullable - BeehiveBlockEntity getBeehiveBlockEntity() { -- return this.hivePos == null ? null : (this.isTooFarAway(this.hivePos) ? null : (BeehiveBlockEntity) this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse((Object) null)); -+ // Paper start - move over logic to accommodate isTooFarAway with chunk load check -+ if (this.hivePos != null && !this.isTooFarAway(this.hivePos) && this.level().getChunkIfLoadedImmediately(this.hivePos.getX() >> 4, this.hivePos.getZ() >> 4) != null) { -+ return (BeehiveBlockEntity) this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null); -+ } -+ return null; -+ // Paper end - } - - boolean isHiveValid() { -@@ -533,11 +565,13 @@ - this.setFlag(4, hasStung); - } - -+ public net.kyori.adventure.util.TriState rollingOverride = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Rolling override - public boolean isRolling() { - return this.getFlag(2); - } - - public void setRolling(boolean nearTarget) { -+ nearTarget = rollingOverride.toBooleanOrElse(nearTarget); // Paper - Rolling override - this.setFlag(2, nearTarget); - } - -@@ -602,7 +636,7 @@ - if (mobeffect != null) { - this.usePlayerItem(player, hand, itemstack); - if (!this.level().isClientSide) { -- this.addEffect(mobeffect); -+ this.addEffect(mobeffect, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // Paper - Add missing effect cause - } - - return InteractionResult.SUCCESS; -@@ -671,8 +705,14 @@ - if (this.isInvulnerableTo(world, source)) { - return false; - } else { -+ // CraftBukkit start - Only stop pollinating if entity was damaged -+ boolean result = super.hurtServer(world, source, amount); -+ if (!result) { -+ return result; -+ } -+ // CraftBukkit end - this.beePollinateGoal.stopPollinating(); -- return super.hurtServer(world, source, amount); -+ return result; // CraftBukkit - } - } - -@@ -934,7 +974,7 @@ - Bee.this.dropFlower(); - this.pollinating = false; - Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; -- } else { -+ } else if (Bee.this.savedFlowerPos != null) { // Paper - add null check since API can manipulate this - Vec3 vec3d = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0D, 0.6000000238418579D, 0.0D); - - if (vec3d.distanceTo(Bee.this.position()) > 1.0D) { -@@ -1082,7 +1122,7 @@ - - BeeGoToHiveGoal() { - super(); -- this.travellingTicks = Bee.this.level().random.nextInt(10); -+ this.travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues - this.blacklistedTargets = Lists.newArrayList(); - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); - } -@@ -1196,7 +1236,7 @@ - - BeeGoToKnownFlowerGoal() { - super(); -- this.travellingTicks = Bee.this.level().random.nextInt(10); -+ this.travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); - } - -@@ -1301,7 +1341,7 @@ - } - } - -- if (iblockdata1 != null) { -+ if (iblockdata1 != null && CraftEventFactory.callEntityChangeBlockEvent(Bee.this, blockposition, iblockdata1)) { // CraftBukkit - Bee.this.level().levelEvent(2011, blockposition, 15); - Bee.this.level().setBlockAndUpdate(blockposition, iblockdata1); - Bee.this.incrementNumCropsGrownSincePollination(); -@@ -1378,7 +1418,7 @@ - @Override - protected void alertOther(Mob mob, LivingEntity target) { - if (mob instanceof Bee && this.mob.hasLineOfSight(target)) { -- mob.setTarget(target); -+ mob.setTarget(target, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason - } - - } -@@ -1387,7 +1427,7 @@ - private static class BeeBecomeAngryTargetGoal extends NearestAttackableTargetGoal { - - BeeBecomeAngryTargetGoal(Bee bee) { -- Objects.requireNonNull(bee); -+ // Objects.requireNonNull(entitybee); // CraftBukkit - decompile error - super(bee, Player.class, 10, true, false, bee::isAngryAt); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Bucketable.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Bucketable.java.patch deleted file mode 100644 index 804bc3e693..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Bucketable.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Bucketable.java -+++ b/net/minecraft/world/entity/animal/Bucketable.java -@@ -16,6 +16,11 @@ - import net.minecraft.world.item.Items; - import net.minecraft.world.item.component.CustomData; - import net.minecraft.world.level.Level; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.event.player.PlayerBucketEntityEvent; -+// CraftBukkit end - - public interface Bucketable { - -@@ -93,10 +98,21 @@ - ItemStack itemstack = player.getItemInHand(hand); - - if (itemstack.getItem() == Items.WATER_BUCKET && entity.isAlive()) { -- entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F); -+ // CraftBukkit start -+ // t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F); // CraftBukkit - moved down - ItemStack itemstack1 = ((Bucketable) entity).getBucketItemStack(); - - ((Bucketable) entity).saveToBucketTag(itemstack1); -+ -+ PlayerBucketEntityEvent playerBucketFishEvent = CraftEventFactory.callPlayerFishBucketEvent(entity, player, itemstack, itemstack1, hand); -+ itemstack1 = CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket()); -+ if (playerBucketFishEvent.isCancelled()) { -+ ((ServerPlayer) player).containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket -+ entity.resendPossiblyDesyncedEntityData((ServerPlayer) player); // Paper -+ return Optional.of(InteractionResult.FAIL); -+ } -+ entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F); -+ // CraftBukkit end - ItemStack itemstack2 = ItemUtils.createFilledResult(itemstack, player, itemstack1, false); - - player.setItemInHand(hand, itemstack2); -@@ -106,7 +122,7 @@ - CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer) player, itemstack1); - } - -- entity.discard(); -+ entity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - return Optional.of(InteractionResult.SUCCESS); - } else { - return Optional.empty(); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Cat.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Cat.java.patch deleted file mode 100644 index d829874cb7..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Cat.java.patch +++ /dev/null @@ -1,96 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Cat.java -+++ b/net/minecraft/world/entity/animal/Cat.java -@@ -174,10 +174,10 @@ - @Override - public void readAdditionalSaveData(CompoundTag nbt) { - super.readAdditionalSaveData(nbt); -- Optional optional = Optional.ofNullable(ResourceLocation.tryParse(nbt.getString("variant"))).map((minecraftkey) -> { -+ Optional> optional = Optional.ofNullable(ResourceLocation.tryParse(nbt.getString("variant"))).map((minecraftkey) -> { // CraftBukkit - decompile error - return ResourceKey.create(Registries.CAT_VARIANT, minecraftkey); - }); -- Registry iregistry = BuiltInRegistries.CAT_VARIANT; -+ Registry iregistry = BuiltInRegistries.CAT_VARIANT; // CraftBukkit - decompile error - - Objects.requireNonNull(iregistry); - optional.flatMap(iregistry::get).ifPresent(this::setVariant); -@@ -365,7 +365,7 @@ - BuiltInRegistries.CAT_VARIANT.getRandomElementOf(tagkey, world.getRandom()).ifPresent(this::setVariant); - ServerLevel worldserver = world.getLevel(); - -- if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK).isValid()) { -+ if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK, world).isValid()) { // Paper - Fix swamp hut cat generation deadlock - this.setVariant((Holder) BuiltInRegistries.CAT_VARIANT.getOrThrow(CatVariant.ALL_BLACK)); - this.setPersistenceRequired(); - } -@@ -386,6 +386,13 @@ - DyeColor enumcolor = itemdye.getDyeColor(); - - if (enumcolor != this.getCollarColor()) { -+ // Paper start - Add EntityDyeEvent and CollarColorable interface -+ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) enumcolor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity()); -+ if (!event.callEvent()) { -+ return InteractionResult.FAIL; -+ } -+ enumcolor = DyeColor.byId(event.getColor().getWoolData()); -+ // Paper end - Add EntityDyeEvent and CollarColorable interface - if (!this.level().isClientSide()) { - this.setCollarColor(enumcolor); - itemstack.consume(1, player); -@@ -399,7 +406,7 @@ - this.usePlayerItem(player, hand, itemstack); - FoodProperties foodinfo = (FoodProperties) itemstack.get(DataComponents.FOOD); - -- this.heal(foodinfo != null ? (float) foodinfo.nutrition() : 1.0F); -+ this.heal(foodinfo != null ? (float) foodinfo.nutrition() : 1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // Paper - Add missing regain reason - this.playEatingSound(); - } - -@@ -462,7 +469,7 @@ - } - - private void tryToTame(Player player) { -- if (this.random.nextInt(3) == 0) { -+ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - this.tame(player); - this.setOrderedToSit(true); - this.level().broadcastEntityEvent(this, (byte) 7); -@@ -480,7 +487,7 @@ - private static class CatTemptGoal extends TemptGoal { - - @Nullable -- private Player selectedPlayer; -+ private LivingEntity selectedPlayer; // CraftBukkit - private final Cat cat; - - public CatTemptGoal(Cat cat, double speed, Predicate foodPredicate, boolean canBeScared) { -@@ -614,7 +621,15 @@ - this.cat.randomTeleport((double) (blockposition_mutableblockposition.getX() + randomsource.nextInt(11) - 5), (double) (blockposition_mutableblockposition.getY() + randomsource.nextInt(5) - 2), (double) (blockposition_mutableblockposition.getZ() + randomsource.nextInt(11) - 5), false); - blockposition_mutableblockposition.set(this.cat.blockPosition()); - this.cat.dropFromGiftLootTable(getServerLevel((Entity) this.cat), BuiltInLootTables.CAT_MORNING_GIFT, (worldserver, itemstack) -> { -- worldserver.addFreshEntity(new ItemEntity(worldserver, (double) blockposition_mutableblockposition.getX() - (double) Mth.sin(this.cat.yBodyRot * 0.017453292F), (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + (double) Mth.cos(this.cat.yBodyRot * 0.017453292F), itemstack)); -+ // CraftBukkit start -+ ItemEntity entityitem = new ItemEntity(worldserver, (double) blockposition_mutableblockposition.getX() - (double) Mth.sin(this.cat.yBodyRot * 0.017453292F), (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + (double) Mth.cos(this.cat.yBodyRot * 0.017453292F), itemstack); -+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.cat.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); -+ entityitem.level().getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return; -+ } -+ worldserver.addFreshEntity(entityitem); -+ // CraftBukkit end - }); - } - -@@ -645,10 +660,10 @@ - private final Cat cat; - - public CatAvoidEntityGoal(Cat cat, Class fleeFromType, float distance, double slowSpeed, double fastSpeed) { -- Predicate predicate = EntitySelector.NO_CREATIVE_OR_SPECTATOR; -+ // Predicate predicate = IEntitySelector.NO_CREATIVE_OR_SPECTATOR; // CraftBukkit - decompile error - -- Objects.requireNonNull(predicate); -- super(cat, fleeFromType, distance, slowSpeed, fastSpeed, predicate::test); -+ // Objects.requireNonNull(predicate); // CraftBukkit - decompile error -+ super(cat, fleeFromType, distance, slowSpeed, fastSpeed, EntitySelector.NO_CREATIVE_OR_SPECTATOR::test); // CraftBukkit - decompile error - this.cat = cat; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Chicken.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Chicken.java.patch deleted file mode 100644 index 78c5696f2a..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Chicken.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Chicken.java -+++ b/net/minecraft/world/entity/animal/Chicken.java -@@ -99,10 +99,12 @@ - - if (world instanceof ServerLevel worldserver) { - if (this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggTime <= 0) { -+ this.forceDrops = true; // CraftBukkit - if (this.dropFromGiftLootTable(worldserver, BuiltInLootTables.CHICKEN_LAY, this::spawnAtLocation)) { - this.playSound(SoundEvents.CHICKEN_EGG, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); - this.gameEvent(GameEvent.ENTITY_PLACE); - } -+ this.forceDrops = false; // CraftBukkit - - this.eggTime = this.random.nextInt(6000) + 6000; - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Cow.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Cow.java.patch deleted file mode 100644 index 4e23f7179b..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Cow.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Cow.java -+++ b/net/minecraft/world/entity/animal/Cow.java -@@ -30,6 +30,11 @@ - import net.minecraft.world.item.Items; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.state.BlockState; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.player.PlayerBucketFillEvent; -+// CraftBukkit end - - public class Cow extends Animal { - -@@ -92,8 +97,17 @@ - ItemStack itemstack = player.getItemInHand(hand); - - if (itemstack.is(Items.BUCKET) && !this.isBaby()) { -+ // CraftBukkit start - Got milk? -+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); -+ -+ if (event.isCancelled()) { -+ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end -+ - player.playSound(SoundEvents.COW_MILK, 1.0F, 1.0F); -- ItemStack itemstack1 = ItemUtils.createFilledResult(itemstack, player, Items.MILK_BUCKET.getDefaultInstance()); -+ ItemStack itemstack1 = ItemUtils.createFilledResult(itemstack, player, CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit - - player.setItemInHand(hand, itemstack1); - return InteractionResult.SUCCESS; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Dolphin.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Dolphin.java.patch deleted file mode 100644 index c16913343e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Dolphin.java.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Dolphin.java -+++ b/net/minecraft/world/entity/animal/Dolphin.java -@@ -61,9 +61,20 @@ - import net.minecraft.world.level.ServerLevelAccessor; - import net.minecraft.world.level.pathfinder.PathComputationType; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityPotionEffectEvent; -+import org.bukkit.event.entity.EntityRemoveEvent; -+// CraftBukkit end - - public class Dolphin extends AgeableWaterCreature { - -+ // CraftBukkit start - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() -+ @Override -+ public int getDefaultMaxAirSupply() { -+ return Dolphin.TOTAL_AIR_SUPPLY; -+ } -+ // CraftBukkit end - private static final EntityDataAccessor TREASURE_POS = SynchedEntityData.defineId(Dolphin.class, EntityDataSerializers.BLOCK_POS); - private static final EntityDataAccessor GOT_FISH = SynchedEntityData.defineId(Dolphin.class, EntityDataSerializers.BOOLEAN); - private static final EntityDataAccessor MOISTNESS_LEVEL = SynchedEntityData.defineId(Dolphin.class, EntityDataSerializers.INT); -@@ -200,7 +211,7 @@ - - @Override - public int getMaxAirSupply() { -- return 4800; -+ return this.maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() - } - - @Override -@@ -234,11 +245,17 @@ - ItemStack itemstack = itemEntity.getItem(); - - if (this.canHoldItem(itemstack)) { -+ // CraftBukkit start - call EntityPickupItemEvent -+ if (CraftEventFactory.callEntityPickupItemEvent(this, itemEntity, 0, false).isCancelled()) { -+ return; -+ } -+ itemstack = itemEntity.getItem(); // CraftBukkit- update ItemStack from event -+ // CraftBukkit start - this.onItemPickup(itemEntity); - this.setItemSlot(EquipmentSlot.MAINHAND, itemstack); - this.setGuaranteedDrop(EquipmentSlot.MAINHAND); - this.take(itemEntity, itemstack.getCount()); -- itemEntity.discard(); -+ itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - } - } - -@@ -332,7 +349,7 @@ - - @Nullable - @Override -- protected SoundEvent getDeathSound() { -+ public SoundEvent getDeathSound() { // Paper - decompile error - return SoundEvents.DOLPHIN_DEATH; - } - -@@ -495,7 +512,7 @@ - - @Override - public void start() { -- this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin); -+ this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin, EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit - } - - @Override -@@ -514,7 +531,7 @@ - } - - if (this.player.isSwimming() && this.player.level().random.nextInt(6) == 0) { -- this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin); -+ this.player.addEffect(new MobEffectInstance(MobEffects.DOLPHINS_GRACE, 100), this.dolphin, EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit - } - - } -@@ -587,7 +604,7 @@ - float f2 = 0.02F * Dolphin.this.random.nextFloat(); - - entityitem.setDeltaMovement((double) (0.3F * -Mth.sin(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.cos(f1) * f2), (double) (0.3F * Mth.sin(Dolphin.this.getXRot() * 0.017453292F) * 1.5F), (double) (0.3F * Mth.cos(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.sin(f1) * f2)); -- Dolphin.this.level().addFreshEntity(entityitem); -+ Dolphin.this.spawnAtLocation(getServerLevel(Dolphin.this), entityitem); // Paper - Call EntityDropItemEvent - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Fox.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Fox.java.patch deleted file mode 100644 index 7052ecb52a..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Fox.java.patch +++ /dev/null @@ -1,168 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Fox.java -+++ b/net/minecraft/world/entity/animal/Fox.java -@@ -90,6 +90,9 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.pathfinder.PathType; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.event.entity.EntityRemoveEvent; -+// CraftBukkit end - - public class Fox extends Animal implements VariantHolder { - -@@ -416,7 +419,7 @@ - - this.setSleeping(nbt.getBoolean("Sleeping")); - this.setVariant(Fox.Variant.byName(nbt.getString("Type"))); -- this.setSitting(nbt.getBoolean("Sitting")); -+ this.setSitting(nbt.getBoolean("Sitting"), false); // Paper - Add EntityToggleSitEvent - this.setIsCrouching(nbt.getBoolean("Crouching")); - if (this.level() instanceof ServerLevel) { - this.setTargetGoals(); -@@ -429,6 +432,12 @@ - } - - public void setSitting(boolean sitting) { -+ // Paper start - Add EntityToggleSitEvent -+ this.setSitting(sitting, true); -+ } -+ public void setSitting(boolean sitting, boolean fireEvent) { -+ if (fireEvent && !new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), sitting).callEvent()) return; -+ // Paper end - Add EntityToggleSitEvent - this.setFlag(1, sitting); - } - -@@ -489,21 +498,22 @@ - entityitem.setPickUpDelay(40); - entityitem.setThrower(this); - this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F); -- this.level().addFreshEntity(entityitem); -+ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem); // Paper - Call EntityDropItemEvent - } - } - - private void dropItemStack(ItemStack stack) { - ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), stack); - -- this.level().addFreshEntity(entityitem); -+ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem); // Paper - Call EntityDropItemEvent - } - - @Override - protected void pickUpItem(ServerLevel world, ItemEntity itemEntity) { - ItemStack itemstack = itemEntity.getItem(); - -- if (this.canHoldItem(itemstack)) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, itemEntity, itemstack.getCount() - 1, !this.canHoldItem(itemstack)).isCancelled()) { // CraftBukkit - call EntityPickupItemEvent -+ itemstack = itemEntity.getItem(); // CraftBukkit - update ItemStack from event - int i = itemstack.getCount(); - - if (i > 1) { -@@ -515,7 +525,7 @@ - this.setItemSlot(EquipmentSlot.MAINHAND, itemstack.split(1)); - this.setGuaranteedDrop(EquipmentSlot.MAINHAND); - this.take(itemEntity, itemstack.getCount()); -- itemEntity.discard(); -+ itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - this.ticksSinceEaten = 0; - } - -@@ -685,16 +695,38 @@ - return this.getTrustedUUIDs().contains(uuid); - } - -+ // Paper start - handle the bitten item separately like vanilla - @Override -- protected void dropAllDeathLoot(ServerLevel world, DamageSource damageSource) { -+ protected boolean shouldSkipLoot(EquipmentSlot slot) { -+ return slot == EquipmentSlot.MAINHAND; -+ } -+ // Paper end -+ -+ @Override -+ // Paper start - Cancellable death event -+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(ServerLevel world, DamageSource damageSource) { - ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND); - -- if (!itemstack.isEmpty()) { -+ boolean releaseMouth = false; -+ if (!itemstack.isEmpty() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Fix MC-153010 - this.spawnAtLocation(world, itemstack); -+ releaseMouth = true; -+ } -+ -+ org.bukkit.event.entity.EntityDeathEvent deathEvent = super.dropAllDeathLoot(world, damageSource); -+ -+ // Below is code to drop -+ -+ if (deathEvent == null || deathEvent.isCancelled()) { -+ return deathEvent; -+ } -+ -+ if (releaseMouth) { -+ // Paper end - Cancellable death event - this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); - } - -- super.dropAllDeathLoot(world, damageSource); -+ return deathEvent; // Paper - Cancellable death event - } - - public static boolean isPathClear(Fox fox, LivingEntity chasedEntity) { -@@ -853,6 +885,16 @@ - if (entityplayer1 != null && entityplayer != entityplayer1) { - entityfox.addTrustedUUID(entityplayer1.getUUID()); - } -+ // CraftBukkit start - call EntityBreedEvent -+ entityfox.setAge(-24000); -+ entityfox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F); -+ int experience = this.animal.getRandom().nextInt(7) + 1; -+ org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityfox, this.animal, this.partner, entityplayer, this.animal.breedItem, experience); -+ if (entityBreedEvent.isCancelled()) { -+ return; -+ } -+ experience = entityBreedEvent.getExperience(); -+ // CraftBukkit end - - if (entityplayer2 != null) { - entityplayer2.awardStat(Stats.ANIMALS_BRED); -@@ -863,12 +905,14 @@ - this.partner.setAge(6000); - this.animal.resetLove(); - this.partner.resetLove(); -- entityfox.setAge(-24000); -- entityfox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F); -- worldserver.addFreshEntityWithPassengers(entityfox); -+ worldserver.addFreshEntityWithPassengers(entityfox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason - this.level.broadcastEntityEvent(this.animal, (byte) 18); - if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1)); -+ // CraftBukkit start - use event experience -+ if (experience > 0) { -+ this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityfox)); // Paper -+ } -+ // CraftBukkit end - } - - } -@@ -1264,6 +1308,11 @@ - int i = (Integer) state.getValue(SweetBerryBushBlock.AGE); - - state.setValue(SweetBerryBushBlock.AGE, 1); -+ // CraftBukkit start - call EntityChangeBlockEvent -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(Fox.this, this.blockPos, state.setValue(SweetBerryBushBlock.AGE, 1))) { -+ return; -+ } -+ // CraftBukkit end - int j = 1 + Fox.this.level().random.nextInt(2) + (i == 3 ? 1 : 0); - ItemStack itemstack = Fox.this.getItemBySlot(EquipmentSlot.MAINHAND); - -@@ -1494,7 +1543,7 @@ - } - - public static Fox.Variant byName(String name) { -- return (Fox.Variant) Fox.Variant.CODEC.byName(name, (Enum) Fox.Variant.RED); -+ return (Fox.Variant) Fox.Variant.CODEC.byName(name, Fox.Variant.RED); // CraftBukkit - decompile error - } - - public static Fox.Variant byId(int id) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/IronGolem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/IronGolem.java.patch deleted file mode 100644 index 4562593cc0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/IronGolem.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/net/minecraft/world/entity/animal/IronGolem.java -+++ b/net/minecraft/world/entity/animal/IronGolem.java -@@ -98,7 +98,7 @@ - @Override - protected void doPush(Entity entity) { - if (entity instanceof Enemy && !(entity instanceof Creeper) && this.getRandom().nextInt(20) == 0) { -- this.setTarget((LivingEntity) entity); -+ this.setTarget((LivingEntity) entity, org.bukkit.event.entity.EntityTargetLivingEntityEvent.TargetReason.COLLISION, true); // CraftBukkit - set reason - } - - super.doPush(entity); -@@ -319,7 +319,7 @@ - BlockPos blockposition1 = blockposition.below(); - BlockState iblockdata = world.getBlockState(blockposition1); - -- if (!iblockdata.entityCanStandOn(world, blockposition1, this)) { -+ if (!iblockdata.entityCanStandOn(world, blockposition1, this) && !this.level().paperConfig().entities.spawning.ironGolemsCanSpawnInAir) { // Paper - Add option to allow iron golems to spawn in air - return false; - } else { - for (int i = 1; i < 3; ++i) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/MushroomCow.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/MushroomCow.java.patch deleted file mode 100644 index a7cff6ad18..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/MushroomCow.java.patch +++ /dev/null @@ -1,85 +0,0 @@ ---- a/net/minecraft/world/entity/animal/MushroomCow.java -+++ b/net/minecraft/world/entity/animal/MushroomCow.java -@@ -42,6 +42,13 @@ - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.storage.loot.BuiltInLootTables; -+// CraftBukkit start -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.entity.EntityDropItemEvent; -+import org.bukkit.event.entity.EntityTransformEvent; -+// CraftBukkit end - - public class MushroomCow extends Cow implements Shearable, VariantHolder { - -@@ -120,7 +127,19 @@ - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; - -- this.shear(worldserver, SoundSource.PLAYERS, itemstack); -+ // CraftBukkit start -+ // Paper start - custom shear drops -+ java.util.List drops = this.generateDefaultDrops(worldserver, itemstack); -+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); -+ // Paper end - custom shear drops -+ } -+ // CraftBukkit end -+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops - this.gameEvent(GameEvent.SHEAR, player); - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); - } -@@ -158,16 +177,32 @@ - - @Override - public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) { -+ // Paper start - custom shear drops -+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears)); -+ } -+ -+ @Override -+ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { -+ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); -+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (ignored, stack) -> { -+ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1)); -+ }); -+ return drops; -+ } -+ -+ @Override -+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { -+ // Paper end - custom shear drops - world.playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), (entitycow) -> { - world.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D); -- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (worldserver1, itemstack1) -> { -- for (int i = 0; i < itemstack1.getCount(); ++i) { -- worldserver1.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), itemstack1.copyWithCount(1))); -- } -- -+ // Paper start - custom shear drops; moved drop generation to separate method -+ drops.forEach(drop -> { -+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop); -+ this.spawnAtLocation(world, entityitem); -+ // Paper end - custom shear drops; moved drop generation to separate method - }); -- }); -+ }, EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit - } - - @Override -@@ -263,7 +298,7 @@ - } - - static MushroomCow.Variant byName(String name) { -- return (MushroomCow.Variant) MushroomCow.Variant.CODEC.byName(name, (Enum) MushroomCow.Variant.RED); -+ return (MushroomCow.Variant) MushroomCow.Variant.CODEC.byName(name, MushroomCow.Variant.RED); // CraftBukkit - decompile error - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Ocelot.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Ocelot.java.patch deleted file mode 100644 index e217641cf1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Ocelot.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Ocelot.java -+++ b/net/minecraft/world/entity/animal/Ocelot.java -@@ -132,7 +132,7 @@ - - @Override - public boolean removeWhenFarAway(double distanceSquared) { -- return !this.isTrusting() && this.tickCount > 2400; -+ return !this.isTrusting() && this.tickCount > 2400 && !this.hasCustomName() && !this.isLeashed(); // Paper - honor name and leash - } - - public static AttributeSupplier.Builder createAttributes() { -@@ -167,7 +167,7 @@ - if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemstack) && player.distanceToSqr((Entity) this) < 9.0D) { - this.usePlayerItem(player, hand, itemstack); - if (!this.level().isClientSide) { -- if (this.random.nextInt(3) == 0) { -+ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call and isCancelled check - this.setTrusting(true); - this.spawnTrustingParticles(true); - this.level().broadcastEntityEvent(this, (byte) 41); -@@ -298,10 +298,10 @@ - private final Ocelot ocelot; - - public OcelotAvoidEntityGoal(Ocelot ocelot, Class fleeFromType, float distance, double slowSpeed, double fastSpeed) { -- Predicate predicate = EntitySelector.NO_CREATIVE_OR_SPECTATOR; -+ // Predicate predicate = IEntitySelector.NO_CREATIVE_OR_SPECTATOR; // CraftBukkit - decompile error - -- Objects.requireNonNull(predicate); -- super(ocelot, fleeFromType, distance, slowSpeed, fastSpeed, predicate::test); -+ // Objects.requireNonNull(predicate); // CraftBukkit - decompile error -+ super(ocelot, fleeFromType, distance, slowSpeed, fastSpeed, EntitySelector.NO_CREATIVE_OR_SPECTATOR::test); // CraftBukkit - decompile error - this.ocelot = ocelot; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Panda.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Panda.java.patch deleted file mode 100644 index 911c02e2c0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Panda.java.patch +++ /dev/null @@ -1,122 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Panda.java -+++ b/net/minecraft/world/entity/animal/Panda.java -@@ -68,6 +68,11 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.storage.loot.BuiltInLootTables; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.event.entity.EntityTargetEvent; -+// CraftBukkit end - - public class Panda extends Animal { - -@@ -129,6 +134,7 @@ - } - - public void sit(boolean sitting) { -+ if (!new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), sitting).callEvent()) return; // Paper - Add EntityToggleSitEvent - this.setFlag(8, sitting); - } - -@@ -525,7 +531,9 @@ - Panda entitypanda = (Panda) iterator.next(); - - if (!entitypanda.isBaby() && entitypanda.onGround() && !entitypanda.isInWater() && entitypanda.canPerformAction()) { -+ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper - Entity Jump API - entitypanda.jumpFromGround(); -+ } else { this.setJumping(false); } // Paper - Entity Jump API; setJumping(false) stops a potential loop - } - } - -@@ -533,7 +541,9 @@ - - if (world1 instanceof ServerLevel worldserver) { - if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -+ this.forceDrops = true; // Paper - Add missing forceDrop toggles - this.dropFromGiftLootTable(worldserver, BuiltInLootTables.PANDA_SNEEZE, this::spawnAtLocation); -+ this.forceDrops = false; // Paper - Add missing forceDrop toggles - } - } - -@@ -541,14 +551,14 @@ - - @Override - protected void pickUpItem(ServerLevel world, ItemEntity itemEntity) { -- if (this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty() && Panda.canPickUpAndEat(itemEntity)) { -+ if (!CraftEventFactory.callEntityPickupItemEvent(this, itemEntity, 0, !(this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty() && Panda.canPickUpAndEat(itemEntity))).isCancelled()) { // CraftBukkit - this.onItemPickup(itemEntity); - ItemStack itemstack = itemEntity.getItem(); - - this.setItemSlot(EquipmentSlot.MAINHAND, itemstack); - this.setGuaranteedDrop(EquipmentSlot.MAINHAND); - this.take(itemEntity, itemstack.getCount()); -- itemEntity.discard(); -+ itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - } - - } -@@ -643,8 +653,9 @@ - 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 - Fix EntityBreedEvent copying - this.usePlayerItem(player, hand, itemstack); -- this.setInLove(player); -+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying - } else { - Level world = this.level(); - -@@ -657,7 +668,9 @@ - ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND); - - if (!itemstack1.isEmpty() && !player.hasInfiniteMaterials()) { -+ this.forceDrops = true; // Paper - Add missing forceDrop toggles - this.spawnAtLocation(worldserver, itemstack1); -+ this.forceDrops = false; // Paper - Add missing forceDrop toggles - } - - this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1)); -@@ -772,7 +785,7 @@ - } - - public static Panda.Gene byName(String name) { -- return (Panda.Gene) Panda.Gene.CODEC.byName(name, (Enum) Panda.Gene.NORMAL); -+ return (Panda.Gene) Panda.Gene.CODEC.byName(name, Panda.Gene.NORMAL); // CraftBukkit - decompile error - } - - public static Panda.Gene getRandom(RandomSource random) { -@@ -876,10 +889,10 @@ - private final Panda panda; - - public PandaAvoidGoal(Panda panda, Class fleeFromType, float distance, double slowSpeed, double fastSpeed) { -- Predicate predicate = EntitySelector.NO_SPECTATORS; -+ // Predicate predicate = IEntitySelector.NO_SPECTATORS; - -- Objects.requireNonNull(predicate); -- super(panda, fleeFromType, distance, slowSpeed, fastSpeed, predicate::test); -+ // Objects.requireNonNull(predicate); -+ super(panda, fleeFromType, distance, slowSpeed, fastSpeed, EntitySelector.NO_SPECTATORS::test); - this.panda = panda; - } - -@@ -935,7 +948,9 @@ - ItemStack itemstack = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND); - - if (!itemstack.isEmpty()) { -+ Panda.this.forceDrops = true; // Paper - Add missing forceDrop toggles - Panda.this.spawnAtLocation(getServerLevel(Panda.this.level()), itemstack); -+ Panda.this.forceDrops = false; // Paper - Add missing forceDrop toggles - Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); - int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10; - -@@ -1116,7 +1131,7 @@ - @Override - protected void alertOther(Mob mob, LivingEntity target) { - if (mob instanceof Panda && mob.isAggressive()) { -- mob.setTarget(target); -+ mob.setTarget(target, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - } - - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Pig.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Pig.java.patch deleted file mode 100644 index a5cdaa0866..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Pig.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Pig.java -+++ b/net/minecraft/world/entity/animal/Pig.java -@@ -49,6 +49,10 @@ - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityRemoveEvent; -+// CraftBukkit end - - public class Pig extends Animal implements ItemSteerable, Saddleable { - -@@ -247,7 +251,14 @@ - } - - entitypigzombie1.setPersistenceRequired(); -- }); -+ // CraftBukkit start -+ }, null, null); -+ if (CraftEventFactory.callPigZapEvent(this, lightning, entitypigzombie).isCancelled()) { -+ return; -+ } -+ world.addFreshEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); -+ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause -+ // CraftBukkit end - - if (entitypigzombie == null) { - super.thunderHit(world, lightning); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Rabbit.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Rabbit.java.patch deleted file mode 100644 index 1f8f84be30..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Rabbit.java.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Rabbit.java -+++ b/net/minecraft/world/entity/animal/Rabbit.java -@@ -65,6 +65,9 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.pathfinder.Path; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class Rabbit extends Animal implements VariantHolder { - -@@ -90,7 +93,6 @@ - super(type, world); - this.jumpControl = new Rabbit.RabbitJumpControl(this); - this.moveControl = new Rabbit.RabbitMoveControl(this); -- this.setSpeedModifier(0.0D); - } - - @Override -@@ -577,9 +579,19 @@ - int i = (Integer) iblockdata.getValue(CarrotBlock.AGE); - - if (i == 0) { -+ // CraftBukkit start -+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state -+ return; -+ } -+ // CraftBukkit end - world.setBlock(blockposition, Blocks.AIR.defaultBlockState(), 2); - world.destroyBlock(blockposition, true, this.rabbit); - } else { -+ // CraftBukkit start -+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockposition, iblockdata.setValue(CarrotBlock.AGE, i - 1))) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(blockposition, (BlockState) iblockdata.setValue(CarrotBlock.AGE, i - 1), 2); - world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of((Entity) this.rabbit)); - world.levelEvent(2001, blockposition, Block.getId(iblockdata)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Sheep.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Sheep.java.patch deleted file mode 100644 index ce52e0ef57..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Sheep.java.patch +++ /dev/null @@ -1,90 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Sheep.java -+++ b/net/minecraft/world/entity/animal/Sheep.java -@@ -41,7 +41,6 @@ - import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; - import net.minecraft.world.entity.item.ItemEntity; - import net.minecraft.world.entity.player.Player; --import net.minecraft.world.item.DyeColor; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.Items; - import net.minecraft.world.level.Level; -@@ -49,6 +48,12 @@ - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.storage.loot.BuiltInLootTables; -+import net.minecraft.world.item.DyeColor; -+// CraftBukkit start -+import net.minecraft.world.item.Item; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.SheepRegrowWoolEvent; -+// CraftBukkit end - - public class Sheep extends Animal implements Shearable { - -@@ -160,7 +165,19 @@ - ServerLevel worldserver = (ServerLevel) world; - - if (this.readyForShearing()) { -- this.shear(worldserver, SoundSource.PLAYERS, itemstack); -+ // CraftBukkit start -+ // Paper start - custom shear drops -+ java.util.List drops = this.generateDefaultDrops(worldserver, itemstack); -+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); -+ // Paper end - custom shear drops -+ } -+ // CraftBukkit end -+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops - this.gameEvent(GameEvent.SHEAR, player); - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); - return InteractionResult.SUCCESS_SERVER; -@@ -175,10 +192,29 @@ - - @Override - public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) { -+ // Paper start - custom shear drops -+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears)); -+ } -+ -+ @Override -+ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { -+ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); -+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SHEEP, shears, (ignored, stack) -> { -+ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1)); -+ }); -+ return drops; -+ } -+ -+ @Override -+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { -+ final ServerLevel worldserver1 = world; // Named for lambda consumption -+ // Paper end - custom shear drops - world.playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); -- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SHEEP, shears, (worldserver1, itemstack1) -> { -- for (int i = 0; i < itemstack1.getCount(); ++i) { -- ItemEntity entityitem = this.spawnAtLocation(worldserver1, itemstack1.copyWithCount(1), 1.0F); -+ drops.forEach(itemstack1 -> { // Paper - custom drops - loop in generated default drops -+ if (true) { // Paper - custom drops - loop in generated default drops -+ this.forceDrops = true; // CraftBukkit -+ ItemEntity entityitem = this.spawnAtLocation(worldserver1, itemstack1, 1.0F); // Paper - custom drops - copy already done above -+ this.forceDrops = false; // CraftBukkit - - if (entityitem != null) { - entityitem.setDeltaMovement(entityitem.getDeltaMovement().add((double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F), (double) (this.random.nextFloat() * 0.05F), (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F))); -@@ -276,6 +312,12 @@ - - @Override - public void ate() { -+ // CraftBukkit start -+ SheepRegrowWoolEvent event = new SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) return; -+ // CraftBukkit end - super.ate(); - this.setSheared(false); - if (this.isBaby()) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch deleted file mode 100644 index 40307984a0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/net/minecraft/world/entity/animal/ShoulderRidingEntity.java -+++ b/net/minecraft/world/entity/animal/ShoulderRidingEntity.java -@@ -5,6 +5,9 @@ - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.TamableAnimal; - import net.minecraft.world.level.Level; -+// CraftBukkit start -+import org.bukkit.event.entity.EntityRemoveEvent; -+// CraftBukkit end - - public abstract class ShoulderRidingEntity extends TamableAnimal { - -@@ -21,7 +24,7 @@ - nbttagcompound.putString("id", this.getEncodeId()); - this.saveWithoutId(nbttagcompound); - if (player.setEntityOnShoulder(nbttagcompound)) { -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - return true; - } else { - return false; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/SnowGolem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/SnowGolem.java.patch deleted file mode 100644 index c07f86335e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/SnowGolem.java.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- a/net/minecraft/world/entity/animal/SnowGolem.java -+++ b/net/minecraft/world/entity/animal/SnowGolem.java -@@ -42,6 +42,9 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.storage.loot.BuiltInLootTables; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackMob { - -@@ -100,7 +103,7 @@ - - if (world instanceof ServerLevel worldserver) { - if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) { -- this.hurtServer(worldserver, this.damageSources().onFire(), 1.0F); -+ this.hurtServer(worldserver, this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING - } - - if (!worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -@@ -116,7 +119,11 @@ - BlockPos blockposition = new BlockPos(j, k, l); - - if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) { -- this.level().setBlockAndUpdate(blockposition, iblockdata); -+ // CraftBukkit start -+ if (!CraftEventFactory.handleBlockFormEvent(this.level(), blockposition, iblockdata, this)) { -+ continue; -+ } -+ // CraftBukkit end - this.level().gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(this, iblockdata)); - } - } -@@ -153,7 +160,19 @@ - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; - -- this.shear(worldserver, SoundSource.PLAYERS, itemstack); -+ // CraftBukkit start -+ // Paper start - custom shear drops -+ java.util.List drops = this.generateDefaultDrops(worldserver, itemstack); -+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); -+ // Paper end - custom shear drops -+ } -+ // CraftBukkit end -+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops - this.gameEvent(GameEvent.SHEAR, player); - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); - } -@@ -166,10 +185,29 @@ - - @Override - public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) { -+ // Paper start - custom shear drops -+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears)); -+ } -+ -+ @Override -+ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { -+ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); -+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (ignored, stack) -> { -+ drops.add(stack); -+ }); -+ return drops; -+ } -+ -+ @Override -+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { -+ final ServerLevel worldserver1 = world; // Named for lambda consumption -+ // Paper end - custom shear drops - world.playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - this.setPumpkin(false); -- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (worldserver1, itemstack1) -> { -+ drops.forEach(itemstack1 -> { // Paper - custom shear drops -+ this.forceDrops = true; // CraftBukkit - this.spawnAtLocation(worldserver1, itemstack1, this.getEyeHeight()); -+ this.forceDrops = false; // CraftBukkit - }); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Squid.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Squid.java.patch deleted file mode 100644 index d67bfc9654..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Squid.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Squid.java -+++ b/net/minecraft/world/entity/animal/Squid.java -@@ -46,7 +46,7 @@ - - public Squid(EntityType type, Level world) { - super(type, world); -- this.random.setSeed((long)this.getId()); -+ //this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random - this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Turtle.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Turtle.java.patch deleted file mode 100644 index 49bba2e107..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Turtle.java.patch +++ /dev/null @@ -1,74 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Turtle.java -+++ b/net/minecraft/world/entity/animal/Turtle.java -@@ -310,7 +310,9 @@ - ServerLevel worldserver = (ServerLevel) world; - - if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -+ this.forceDrops = true; // CraftBukkit - this.spawnAtLocation(worldserver, Items.TURTLE_SCUTE, 1); -+ this.forceDrops = false; // CraftBukkit - } - } - } -@@ -339,7 +341,7 @@ - - @Override - public void thunderHit(ServerLevel world, LightningBolt lightning) { -- this.hurtServer(world, this.damageSources().lightningBolt(), Float.MAX_VALUE); -+ this.hurtServer(world, this.damageSources().lightningBolt().customEventDamager(lightning), Float.MAX_VALUE); // CraftBukkit // Paper - fix DamageSource API - } - - @Override -@@ -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)); -+ 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 +498,21 @@ - - if (!this.turtle.isInWater() && this.isReachedTarget()) { - if (this.turtle.layEggCounter < 1) { -- this.turtle.setLayingEgg(true); -+ this.turtle.setLayingEgg(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level(), this.blockPos)).callEvent()); // Paper - Turtle API - } else if (this.turtle.layEggCounter > this.adjustedTickDelay(200)) { - Level world = this.turtle.level(); - -+ // Paper start - Turtle API -+ int eggCount = this.turtle.random.nextInt(4) + 1; -+ com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level(), this.blockPos.above()), eggCount); -+ if (layEggEvent.callEvent() && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()))) { - world.playSound((Player) null, blockposition, SoundEvents.TURTLE_LAY_EGG, SoundSource.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F); - BlockPos blockposition1 = this.blockPos.above(); -- BlockState iblockdata = (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1); -+ BlockState iblockdata = (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()); // Paper - - world.setBlock(blockposition1, iblockdata, 3); - world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition1, GameEvent.Context.of(this.turtle, iblockdata)); -+ } // CraftBukkit - this.turtle.setHasEgg(false); - this.turtle.setLayingEgg(false); - this.turtle.setInLoveTime(600); -@@ -567,7 +578,7 @@ - - @Override - public boolean canUse() { -- return this.turtle.isBaby() ? false : (this.turtle.hasEgg() ? true : (this.turtle.getRandom().nextInt(reducedTickDelay(700)) != 0 ? false : !this.turtle.getHomePos().closerToCenterThan(this.turtle.position(), 64.0D))); -+ return this.turtle.isBaby() ? false : (this.turtle.hasEgg() ? true : (this.turtle.getRandom().nextInt(reducedTickDelay(700)) != 0 ? false : !this.turtle.getHomePos().closerToCenterThan(this.turtle.position(), 64.0D))) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity()).callEvent(); // Paper - Turtle API - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/WaterAnimal.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/WaterAnimal.java.patch deleted file mode 100644 index 5089fd98c0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/WaterAnimal.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/world/entity/animal/WaterAnimal.java -+++ b/net/minecraft/world/entity/animal/WaterAnimal.java -@@ -70,6 +70,10 @@ - ) { - int i = world.getSeaLevel(); - int j = i - 13; -+ // Paper start - Make water animal spawn height configurable -+ i = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(i); -+ j = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(j); -+ // Paper end - Make water animal spawn height configurable - return pos.getY() >= j && pos.getY() <= i && world.getFluidState(pos.below()).is(FluidTags.WATER) && world.getBlockState(pos.above()).is(Blocks.WATER); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Wolf.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Wolf.java.patch deleted file mode 100644 index 50375e02de..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/Wolf.java.patch +++ /dev/null @@ -1,126 +0,0 @@ ---- a/net/minecraft/world/entity/animal/Wolf.java -+++ b/net/minecraft/world/entity/animal/Wolf.java -@@ -85,6 +85,12 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.pathfinder.PathType; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.event.entity.EntityDamageEvent; -+import org.bukkit.event.entity.EntityRegainHealthEvent; -+import org.bukkit.event.entity.EntityTargetEvent; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder> { - -@@ -345,8 +351,14 @@ - if (this.isInvulnerableTo(world, source)) { - return false; - } else { -+ // CraftBukkit start -+ boolean result = super.hurtServer(world, source, amount); -+ if (!result) { -+ return result; -+ } -+ // CraftBukkit end - this.setOrderedToSit(false); -- return super.hurtServer(world, source, amount); -+ return result; // CraftBukkit - } - } - -@@ -356,21 +368,27 @@ - } - - @Override -- protected void actuallyHurt(ServerLevel world, DamageSource source, float amount) { -- if (!this.canArmorAbsorb(source)) { -- super.actuallyHurt(world, source, amount); -+ public boolean actuallyHurt(ServerLevel worldserver, DamageSource damagesource, float f, EntityDamageEvent event) { // CraftBukkit - void -> boolean -+ if (!this.canArmorAbsorb(damagesource)) { -+ return super.actuallyHurt(worldserver, damagesource, f, event); // CraftBukkit - } else { -+ // CraftBukkit start - SPIGOT-7815: if the damage was cancelled, no need to run the wolf armor behaviour -+ if (event.isCancelled()) { -+ return false; -+ } -+ // CraftBukkit end - ItemStack itemstack = this.getBodyArmorItem(); - int i = itemstack.getDamageValue(); - int j = itemstack.getMaxDamage(); - -- itemstack.hurtAndBreak(Mth.ceil(amount), this, EquipmentSlot.BODY); -+ itemstack.hurtAndBreak(Mth.ceil(f), this, EquipmentSlot.BODY); - if (Crackiness.WOLF_ARMOR.byDamage(i, j) != Crackiness.WOLF_ARMOR.byDamage(this.getBodyArmorItem())) { - this.playSound(SoundEvents.WOLF_ARMOR_CRACK); -- world.sendParticles(new ItemParticleOption(ParticleTypes.ITEM, Items.ARMADILLO_SCUTE.getDefaultInstance()), this.getX(), this.getY() + 1.0D, this.getZ(), 20, 0.2D, 0.1D, 0.2D, 0.1D); -+ worldserver.sendParticles(new ItemParticleOption(ParticleTypes.ITEM, Items.ARMADILLO_SCUTE.getDefaultInstance()), this.getX(), this.getY() + 1.0D, this.getZ(), 20, 0.2D, 0.1D, 0.2D, 0.1D); - } - - } -+ return true; // CraftBukkit // Paper - return false ONLY if event was cancelled - } - - private boolean canArmorAbsorb(DamageSource source) { -@@ -381,7 +399,7 @@ - protected void applyTamingSideEffects() { - if (this.isTame()) { - this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(40.0D); -- this.setHealth(40.0F); -+ this.setHealth(this.getMaxHealth()); // CraftBukkit - 40.0 -> getMaxHealth() - } else { - this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(8.0D); - } -@@ -404,7 +422,7 @@ - FoodProperties foodinfo = (FoodProperties) itemstack.get(DataComponents.FOOD); - float f = foodinfo != null ? (float) foodinfo.nutrition() : 1.0F; - -- this.heal(2.0F * f); -+ this.heal(2.0F * f, EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit - return InteractionResult.SUCCESS; - } else { - if (item instanceof DyeItem) { -@@ -414,6 +432,14 @@ - DyeColor enumcolor = itemdye.getDyeColor(); - - if (enumcolor != this.getCollarColor()) { -+ // Paper start - Add EntityDyeEvent and CollarColorable interface -+ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) enumcolor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity()); -+ if (!event.callEvent()) { -+ return InteractionResult.FAIL; -+ } -+ enumcolor = DyeColor.byId(event.getColor().getWoolData()); -+ // Paper end - Add EntityDyeEvent and CollarColorable interface -+ - this.setCollarColor(enumcolor); - itemstack.consume(1, player); - return InteractionResult.SUCCESS; -@@ -440,7 +466,9 @@ - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; - -+ this.forceDrops = true; // CraftBukkit - this.spawnAtLocation(worldserver, itemstack1); -+ this.forceDrops = false; // CraftBukkit - } - - return InteractionResult.SUCCESS; -@@ -459,7 +487,7 @@ - this.setOrderedToSit(!this.isOrderedToSit()); - this.jumping = false; - this.navigation.stop(); -- this.setTarget((LivingEntity) null); -+ this.setTarget((LivingEntity) null, EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason - return InteractionResult.SUCCESS.withoutItem(); - } else { - return enuminteractionresult; -@@ -477,7 +505,8 @@ - } - - private void tryToTame(Player player) { -- if (this.random.nextInt(3) == 0) { -+ // CraftBukkit - added event call and isCancelled check. -+ if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { - this.tame(player); - this.navigation.stop(); - this.setTarget((LivingEntity) null);