diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch new file mode 100644 index 0000000000..512a8a9953 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java ++++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +@@ -70,6 +_,7 @@ + return false; + } else { + mutableLong.setValue(time + 20L + level.getRandom().nextInt(20)); ++ if (mob.getNavigation().isStuck()) mutableLong.add(200); // Paper - Perf: Wait an additional 10s to check again if they're stuck + PoiManager poiManager = level.getPoiManager(); + map.long2ObjectEntrySet().removeIf(entry -> !entry.getValue().isStillValid(time)); + Predicate predicate1 = pos -> { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java.patch new file mode 100644 index 0000000000..60e6ed37af --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java ++++ b/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java +@@ -38,7 +_,14 @@ + .findFirst() + ) + .ifPresent(profession -> { +- villager.setVillagerData(villager.getVillagerData().setProfession(profession)); ++ // CraftBukkit start - Fire VillagerCareerChangeEvent where Villager gets employed ++ org.bukkit.event.entity.VillagerCareerChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callVillagerCareerChangeEvent(villager, org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.minecraftToBukkit(profession), org.bukkit.event.entity.VillagerCareerChangeEvent.ChangeReason.EMPLOYED); ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ villager.setVillagerData(villager.getVillagerData().setProfession(org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession()))); ++ // CraftBukkit end + villager.refreshBrain(level); + }); + return true; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch new file mode 100644 index 0000000000..0695aae31f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java ++++ b/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java +@@ -24,8 +_,19 @@ + if (!mob.isBaby()) { + return false; + } else { +- AgeableMob ageableMob = instance.get(nearestVisibleAdult); ++ LivingEntity ageableMob = instance.get(nearestVisibleAdult); // CraftBukkit - type + if (mob.closerThan(ageableMob, followRange.getMaxValue() + 1) && !mob.closerThan(ageableMob, followRange.getMinValue())) { ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(mob, ageableMob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER); ++ if (event.isCancelled()) { ++ return false; ++ } ++ if (event.getTarget() == null) { ++ nearestVisibleAdult.erase(); ++ return true; ++ } ++ ageableMob = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); ++ // CraftBukkit end + WalkTarget walkTarget1 = new WalkTarget( + new EntityTracker(ageableMob, false), speedModifier.apply(mob), followRange.getMinValue() - 1 + ); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/Behavior.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/Behavior.java.patch similarity index 53% rename from paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/Behavior.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/Behavior.java.patch index dab10a1e20..d205203f19 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/Behavior.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/Behavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/behavior/Behavior.java +++ b/net/minecraft/world/entity/ai/behavior/Behavior.java -@@ -14,6 +14,9 @@ +@@ -14,6 +_,9 @@ private long endTimestamp; private final int minDuration; private final int maxDuration; @@ -8,12 +8,12 @@ + private final String configKey; + // Paper end - configurable behavior tick rate and timings - public Behavior(Map, MemoryStatus> requiredMemoryState) { - this(requiredMemoryState, 60); -@@ -27,6 +30,14 @@ - this.minDuration = minRunTime; - this.maxDuration = maxRunTime; - this.entryCondition = requiredMemoryState; + public Behavior(Map, MemoryStatus> entryCondition) { + this(entryCondition, 60); +@@ -27,6 +_,14 @@ + this.minDuration = minDuration; + this.maxDuration = maxDuration; + this.entryCondition = entryCondition; + // Paper start - configurable behavior tick rate and timings + String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName(); + int lastSeparator = key.lastIndexOf('.'); @@ -25,16 +25,16 @@ } @Override -@@ -36,6 +47,12 @@ +@@ -36,6 +_,12 @@ @Override - public final boolean tryStart(ServerLevel world, E entity, long time) { -+ // Paper start - configurable behavior tick rate and timings -+ int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1); -+ if (tickRate > -1 && time < this.endTimestamp + tickRate) { -+ return false; -+ } -+ // Paper end - configurable behavior tick rate and timings - if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) { + public final boolean tryStart(ServerLevel level, E owner, long gameTime) { ++ // Paper start - configurable behavior tick rate and timings ++ int tickRate = java.util.Objects.requireNonNullElse(level.paperConfig().tickRates.behavior.get(owner.getType(), this.configKey), -1); ++ if (tickRate > -1 && gameTime < this.endTimestamp + tickRate) { ++ return false; ++ } ++ // Paper end - configurable behavior tick rate and timings + if (this.hasRequiredMemories(owner) && this.checkExtraStartConditions(level, owner)) { this.status = Behavior.Status.RUNNING; - int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration); + int i = this.minDuration + level.getRandom().nextInt(this.maxDuration + 1 - this.minDuration); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java.patch new file mode 100644 index 0000000000..77f8530cc4 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java ++++ b/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java +@@ -80,6 +_,7 @@ + } + + public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 offset, Vec3 speedMultiplier, float yOffset) { ++ if (stack.isEmpty()) return; // CraftBukkit - SPIGOT-4940: no empty loot + double d = entity.getEyeY() - yOffset; + ItemEntity itemEntity = new ItemEntity(entity.level(), entity.getX(), d, entity.getZ(), stack); + itemEntity.setThrower(entity); +@@ -87,6 +_,13 @@ + vec3 = vec3.normalize().multiply(speedMultiplier.x, speedMultiplier.y, speedMultiplier.z); + itemEntity.setDeltaMovement(vec3); + itemEntity.setDefaultPickUpDelay(); ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(entity.getBukkitEntity(), (org.bukkit.entity.Item) itemEntity.getBukkitEntity()); ++ itemEntity.level().getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + entity.level().addFreshEntity(itemEntity); + } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/GateBehavior.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/GateBehavior.java.patch similarity index 97% rename from paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/GateBehavior.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/GateBehavior.java.patch index fdb4490626..d7a1d368e0 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/GateBehavior.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/GateBehavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/behavior/GateBehavior.java +++ b/net/minecraft/world/entity/ai/behavior/GateBehavior.java -@@ -18,7 +18,7 @@ +@@ -18,7 +_,7 @@ private final Set> exitErasedMemories; private final GateBehavior.OrderPolicy orderPolicy; private final GateBehavior.RunningPolicy runningPolicy; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java.patch new file mode 100644 index 0000000000..ca1948e8a9 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java ++++ b/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java +@@ -35,6 +_,21 @@ + && itemEntity.closerThan(entity, maxDistToWalk) + && entity.level().getWorldBorder().isWithinBounds(itemEntity.blockPosition()) + && entity.canPickUpLoot()) { ++ // CraftBukkit start ++ if (entity instanceof net.minecraft.world.entity.animal.allay.Allay) { ++ org.bukkit.event.entity.EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetEvent(entity, itemEntity, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ if (!(event.getTarget() instanceof org.bukkit.craftbukkit.entity.CraftItem)) { // Paper - only erase allay memory on non-item targets ++ nearestVisibleWantedItem.erase(); ++ return false; // Paper - only erase allay memory on non-item targets ++ } ++ ++ itemEntity = (ItemEntity) ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); ++ } ++ // CraftBukkit end + WalkTarget walkTarget1 = new WalkTarget(new EntityTracker(itemEntity, false), speedModifier, 0); + lookTarget.set(new EntityTracker(itemEntity, true)); + walkTarget.set(walkTarget1); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch new file mode 100644 index 0000000000..32e15ef453 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java ++++ b/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java +@@ -110,7 +_,9 @@ + Block block = blockState.getBlock(); + Block block1 = level.getBlockState(this.aboveFarmlandPos.below()).getBlock(); + if (block instanceof CropBlock && ((CropBlock)block).isMaxAge(blockState)) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(owner, this.aboveFarmlandPos, blockState.getFluidState().createLegacyBlock())) { // CraftBukkit // Paper - fix wrong block state + level.destroyBlock(this.aboveFarmlandPos, true, owner); ++ } // CraftBukkit + } + + if (blockState.isAir() && block1 instanceof FarmBlock && owner.hasFarmSeeds()) { +@@ -121,9 +_,11 @@ + boolean flag = false; + if (!item.isEmpty() && item.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) && item.getItem() instanceof BlockItem blockItem) { + BlockState blockState1 = blockItem.getBlock().defaultBlockState(); ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(owner, this.aboveFarmlandPos, blockState1)) { // CraftBukkit + level.setBlockAndUpdate(this.aboveFarmlandPos, blockState1); + level.gameEvent(GameEvent.BLOCK_PLACE, this.aboveFarmlandPos, GameEvent.Context.of(owner, blockState1)); + flag = true; ++ } // CraftBukkit + } + + if (flag) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch new file mode 100644 index 0000000000..a5139c9b02 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java ++++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java +@@ -58,6 +_,13 @@ + if (blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) { + DoorBlock doorBlock = (DoorBlock)blockState.getBlock(); + if (!doorBlock.isOpen(blockState)) { ++ // CraftBukkit start - entities opening doors ++ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entity.level(), blockPos)); ++ entity.level().getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return false; ++ } ++ // CraftBukkit end + doorBlock.setOpen(entity, level, blockState, blockPos, true); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java.patch new file mode 100644 index 0000000000..239d6f934e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java.patch @@ -0,0 +1,27 @@ +--- a/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java ++++ b/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java +@@ -10,6 +_,7 @@ + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; + import net.minecraft.sounds.SoundEvent; + import net.minecraft.sounds.SoundSource; + import net.minecraft.util.Mth; +@@ -75,6 +_,16 @@ + .flatMap( + nearestVisibleLivingEntities -> nearestVisibleLivingEntities.findClosest(livingEntity -> this.ramTargeting.test(level, entity, livingEntity)) + ) ++ // CraftBukkit start ++ .map((entityliving) -> { ++ org.bukkit.event.entity.EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(entity, entityliving, (entityliving instanceof ServerPlayer) ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY); ++ if (event.isCancelled() || event.getTarget() == null) { ++ return null; ++ } ++ entityliving = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); ++ return entityliving; ++ }) ++ // CraftBukkit end + .ifPresent(entity1 -> this.chooseRamPosition(entity, entity1)); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch new file mode 100644 index 0000000000..0f29b936ec --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/ai/behavior/RamTarget.java ++++ b/net/minecraft/world/entity/ai/behavior/RamTarget.java +@@ -89,7 +_,7 @@ + float f = 0.25F * (i - i1); + float f1 = Mth.clamp(owner.getSpeed() * 1.65F, 0.2F, 3.0F) + f; + float f2 = livingEntity.isDamageSourceBlocked(level.damageSources().mobAttack(owner)) ? 0.5F : 1.0F; +- livingEntity.knockback(f2 * f1 * this.getKnockbackForce.applyAsDouble(owner), this.ramDirection.x(), this.ramDirection.z()); ++ livingEntity.knockback(f2 * f1 * this.getKnockbackForce.applyAsDouble(owner), this.ramDirection.x(), this.ramDirection.z(), owner, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent + this.finishRam(level, owner); + level.playSound(null, owner, this.getImpactSound.apply(owner), SoundSource.NEUTRAL, 1.0F, 1.0F); + } else if (this.hasRammedHornBreakingBlock(level, owner)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/ResetProfession.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/ResetProfession.java.patch new file mode 100644 index 0000000000..580871ed59 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/ResetProfession.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/entity/ai/behavior/ResetProfession.java ++++ b/net/minecraft/world/entity/ai/behavior/ResetProfession.java +@@ -18,7 +_,14 @@ + && villagerData.getProfession() != VillagerProfession.NITWIT + && villager.getVillagerXp() == 0 + && villagerData.getLevel() <= 1) { +- villager.setVillagerData(villager.getVillagerData().setProfession(VillagerProfession.NONE)); ++ // CraftBukkit start ++ org.bukkit.event.entity.VillagerCareerChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callVillagerCareerChangeEvent(villager, org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.minecraftToBukkit(VillagerProfession.NONE), org.bukkit.event.entity.VillagerCareerChangeEvent.ChangeReason.LOSING_JOB); ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ villager.setVillagerData(villager.getVillagerData().setProfession(org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession()))); ++ // CraftBukkit end + villager.refreshBrain(level); + return true; + } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/ShufflingList.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/ShufflingList.java.patch similarity index 92% rename from paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/ShufflingList.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/ShufflingList.java.patch index 3f1d97092e..ddad0d3698 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/ShufflingList.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/ShufflingList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/behavior/ShufflingList.java +++ b/net/minecraft/world/entity/ai/behavior/ShufflingList.java -@@ -16,12 +16,25 @@ +@@ -16,12 +_,25 @@ public class ShufflingList implements Iterable { protected final List> entries; private final RandomSource random = RandomSource.create(); @@ -16,17 +16,17 @@ this.entries = Lists.newArrayList(); } - private ShufflingList(List> list) { + private ShufflingList(List> entries) { + // Paper start - Fix Concurrency issue in ShufflingList during worldgen -+ this(list, true); ++ this(entries, true); + } -+ private ShufflingList(List> list, boolean isUnsafe) { ++ private ShufflingList(List> entries, boolean isUnsafe) { + this.isUnsafe = isUnsafe; + // Paper end - Fix Concurrency issue in ShufflingList during worldgen - this.entries = Lists.newArrayList(list); + this.entries = Lists.newArrayList(entries); } -@@ -35,9 +48,12 @@ +@@ -35,9 +_,12 @@ } public ShufflingList shuffle() { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch similarity index 58% rename from paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch index d905f5c1d7..cfe4ec0579 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/entity/ai/behavior/SleepInBed.java +++ b/net/minecraft/world/entity/ai/behavior/SleepInBed.java -@@ -42,7 +42,8 @@ +@@ -42,7 +_,8 @@ } } -- BlockState blockState = world.getBlockState(globalPos.pos()); -+ BlockState blockState = world.getBlockStateIfLoaded(globalPos.pos()); // Paper - Prevent sync chunk loads when villagers try to find beds +- BlockState blockState = level.getBlockState(globalPos.pos()); ++ BlockState blockState = level.getBlockStateIfLoaded(globalPos.pos()); // Paper - Prevent sync chunk loads when villagers try to find beds + if (blockState == null) { return false; } // Paper - Prevent sync chunk loads when villagers try to find beds - return globalPos.pos().closerToCenterThan(entity.position(), 2.0) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED); + return globalPos.pos().closerToCenterThan(owner.position(), 2.0) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED); } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch new file mode 100644 index 0000000000..4915d1fd6b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/entity/ai/behavior/StartAttacking.java ++++ b/net/minecraft/world/entity/ai/behavior/StartAttacking.java +@@ -27,6 +_,17 @@ + if (!entity.canAttack(livingEntity)) { + return false; + } else { ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(entity, livingEntity, (livingEntity instanceof net.minecraft.server.level.ServerPlayer) ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY); ++ if (event.isCancelled()) { ++ return false; ++ } ++ if (event.getTarget() == null) { ++ memoryAccessor.erase(); ++ return true; ++ } ++ livingEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); ++ // CraftBukkit end + memoryAccessor.set(livingEntity); + memoryAccessor1.erase(); + return true; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java.patch new file mode 100644 index 0000000000..24a503eca0 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java ++++ b/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java +@@ -40,6 +_,30 @@ + && !canStopAttacking.test(level, livingEntity)) { + return true; + } else { ++ // Paper start - better track target change reason ++ final org.bukkit.event.entity.EntityTargetEvent.TargetReason reason; ++ if (!entity.canAttack(livingEntity)) { ++ reason = org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_INVALID; ++ } else if (canGrowTiredOfTryingToReachTarget && StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entity, instance.tryGet(memoryAccessor1))) { ++ reason = org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET; ++ } else if (!livingEntity.isAlive()) { ++ reason = org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_DIED; ++ } else if (livingEntity.level() != entity.level()) { ++ reason = org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_OTHER_LEVEL; ++ } else { ++ reason = org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_INVALID; ++ } ++ // Paper end ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(entity, null, reason); // Paper ++ if (event.isCancelled()) { ++ return false; ++ } ++ if (event.getTarget() != null) { ++ entity.getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle()); ++ return true; ++ } ++ // CraftBukkit end + onStopAttacking.accept(level, entity, livingEntity); + memoryAccessor.erase(); + return true; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java.patch new file mode 100644 index 0000000000..da9c516844 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java ++++ b/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java +@@ -33,6 +_,12 @@ + BlockPos blockPos2 = blockPos1.above(); + if (level.getBlockState(blockPos2).isAir()) { + BlockState blockState = spawnBlock.defaultBlockState(); ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, blockPos2, blockState)) { ++ isPregnant.erase(); ++ return true; ++ } ++ // CraftBukkit end + level.setBlock(blockPos2, blockState, 3); + level.gameEvent(GameEvent.BLOCK_PLACE, blockPos2, GameEvent.Context.of(entity, blockState)); + level.playSound(null, entity, SoundEvents.FROG_LAY_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java.patch similarity index 72% rename from paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java.patch index c8260c2305..cac3171662 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java +++ b/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java -@@ -42,7 +42,7 @@ +@@ -42,7 +_,7 @@ Pair.of(1, new MoveToTargetSink()), Pair.of(2, PoiCompetitorScan.create()), - Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), -- Pair.of(5, GoToWantedItem.create(speed, false, 4)), -+ Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speed, false, 4)), // Paper - Fix MC-157464 + Pair.of(3, new LookAndFollowTradingPlayerSink(speedModifier)), +- Pair.of(5, GoToWantedItem.create(speedModifier, false, 4)), ++ Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speedModifier, false, 4)), // Paper - Fix MC-157464 Pair.of( 6, AcquirePoi.create( diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch new file mode 100644 index 0000000000..303c80235c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java ++++ b/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java +@@ -111,11 +_,17 @@ + if (breedOffspring == null) { + return Optional.empty(); + } else { +- parent.setAge(6000); +- partner.setAge(6000); + breedOffspring.setAge(-24000); + breedOffspring.moveTo(parent.getX(), parent.getY(), parent.getZ(), 0.0F, 0.0F); +- level.addFreshEntityWithPassengers(breedOffspring); ++ // CraftBukkit start - call EntityBreedEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(breedOffspring, parent, partner, null, null, 0).isCancelled()) { ++ return Optional.empty(); ++ } ++ // Move age setting down ++ parent.setAge(6000); ++ partner.setAge(6000); ++ level.addFreshEntityWithPassengers(breedOffspring, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); ++ // CraftBukkit end + level.broadcastEntityEvent(breedOffspring, (byte)12); + return Optional.of(breedOffspring); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch similarity index 54% rename from paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch index 3d8d9ce4bd..3556764a3b 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java +++ b/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java -@@ -86,7 +86,9 @@ - simpleContainer.removeItemType(Items.WHEAT, m); - ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l)); +@@ -86,7 +_,9 @@ + inventory.removeItemType(Items.WHEAT, i3); + ItemStack itemStack = inventory.addItem(new ItemStack(Items.BREAD, min)); if (!itemStack.isEmpty()) { -+ villager.forceDrops = true; // Paper - Add missing forceDrop toggles - villager.spawnAtLocation(world, itemStack, 0.5F); -+ villager.forceDrops = false; // Paper - Add missing forceDrop toggles ++ villager.forceDrops = true; // Paper - Add missing forceDrop toggle + villager.spawnAtLocation(level, itemStack, 0.5F); ++ villager.forceDrops = false; // Paper - Add missing forceDrop toggle } } } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch deleted file mode 100644 index 64bab57963..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -@@ -70,6 +70,7 @@ - return false; - } else { - mutableLong.setValue(time + 20L + (long)world.getRandom().nextInt(20)); -+ if (entity.getNavigation().isStuck()) mutableLong.add(200); // Paper - Perf: Wait an additional 10s to check again if they're stuck - PoiManager poiManager = world.getPoiManager(); - long2ObjectMap.long2ObjectEntrySet().removeIf(entry -> !entry.getValue().isStillValid(time)); - Predicate predicate2 = pos -> { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java.patch deleted file mode 100644 index a3aec14777..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java -+++ b/net/minecraft/world/entity/ai/behavior/AssignProfessionFromJobSite.java -@@ -9,6 +9,12 @@ - import net.minecraft.world.entity.npc.Villager; - import net.minecraft.world.entity.npc.VillagerProfession; - -+// CraftBukkit start -+import org.bukkit.craftbukkit.entity.CraftVillager; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.VillagerCareerChangeEvent; -+// CraftBukkit end -+ - public class AssignProfessionFromJobSite { - - public AssignProfessionFromJobSite() {} -@@ -37,7 +43,14 @@ - return villagerprofession.heldJobSite().test(holder); - }).findFirst(); - }).ifPresent((villagerprofession) -> { -- entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(villagerprofession)); -+ // CraftBukkit start - Fire VillagerCareerChangeEvent where Villager gets employed -+ VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityvillager, CraftVillager.CraftProfession.minecraftToBukkit(villagerprofession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED); -+ if (event.isCancelled()) { -+ return; -+ } -+ -+ entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession()))); -+ // CraftBukkit end - entityvillager.refreshBrain(worldserver); - }); - return true; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch deleted file mode 100644 index fe0de69d00..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java -+++ b/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java -@@ -7,6 +7,12 @@ - import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder; - import net.minecraft.world.entity.ai.memory.MemoryModuleType; - import net.minecraft.world.entity.ai.memory.WalkTarget; -+// CraftBukkit start -+import org.bukkit.craftbukkit.entity.CraftLivingEntity; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityTargetEvent; -+import org.bukkit.event.entity.EntityTargetLivingEntityEvent; -+// CraftBukkit end - - public class BabyFollowAdult { - -@@ -25,9 +31,20 @@ - if (!entityageable.isBaby()) { - return false; - } else { -- AgeableMob entityageable1 = (AgeableMob) behaviorbuilder_b.get(memoryaccessor); -+ LivingEntity entityageable1 = (AgeableMob) behaviorbuilder_b.get(memoryaccessor); // CraftBukkit - type - - if (entityageable.closerThan(entityageable1, (double) (executionRange.getMaxValue() + 1)) && !entityageable.closerThan(entityageable1, (double) executionRange.getMinValue())) { -+ // CraftBukkit start -+ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityageable, entityageable1, EntityTargetEvent.TargetReason.FOLLOW_LEADER); -+ if (event.isCancelled()) { -+ return false; -+ } -+ if (event.getTarget() == null) { -+ memoryaccessor.erase(); -+ return true; -+ } -+ entityageable1 = ((CraftLivingEntity) event.getTarget()).getHandle(); -+ // CraftBukkit end - WalkTarget memorytarget = new WalkTarget(new EntityTracker(entityageable1, false), (Float) speed.apply(entityageable), executionRange.getMinValue() - 1); - - memoryaccessor1.set(new EntityTracker(entityageable1, true)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java.patch deleted file mode 100644 index 35afe8f0a4..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java -+++ b/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java -@@ -60,7 +60,7 @@ - } - - public static void lookAtEntity(LivingEntity entity, LivingEntity target) { -- entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new EntityTracker(target, true))); -+ entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new EntityTracker(target, true))); // CraftBukkit - decompile error - } - - private static void setWalkAndLookTargetMemoriesToEachOther(LivingEntity first, LivingEntity second, float speed, int completionRange) { -@@ -79,8 +79,8 @@ - public static void setWalkAndLookTargetMemories(LivingEntity entity, PositionTracker target, float speed, int completionRange) { - WalkTarget memorytarget = new WalkTarget(target, speed, completionRange); - -- entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) target); -- entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) memorytarget); -+ entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, target); // CraftBukkit - decompile error -+ entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, memorytarget); // CraftBukkit - decompile error - } - - public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 targetLocation) { -@@ -90,6 +90,7 @@ - } - - public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 targetLocation, Vec3 velocityFactor, float yOffset) { -+ if (stack.isEmpty()) return; // CraftBukkit - SPIGOT-4940: no empty loot - double d0 = entity.getEyeY() - (double) yOffset; - ItemEntity entityitem = new ItemEntity(entity.level(), entity.getX(), d0, entity.getZ(), stack); - -@@ -99,12 +100,19 @@ - vec3d2 = vec3d2.normalize().multiply(velocityFactor.x, velocityFactor.y, velocityFactor.z); - entityitem.setDeltaMovement(vec3d2); - entityitem.setDefaultPickUpDelay(); -+ // CraftBukkit start -+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(entity.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); -+ entityitem.level().getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - entity.level().addFreshEntity(entityitem); - } - - public static SectionPos findSectionClosestToVillage(ServerLevel world, SectionPos center, int radius) { - int j = world.sectionsToVillage(center); -- Stream stream = SectionPos.cube(center, radius).filter((sectionposition1) -> { -+ Stream stream = SectionPos.cube(center, radius).filter((sectionposition1) -> { // CraftBukkit - decompile error - return world.sectionsToVillage(sectionposition1) < j; - }); - -@@ -161,10 +169,10 @@ - - return optional.map((uuid) -> { - return ((ServerLevel) entity.level()).getEntity(uuid); -- }).map((entity) -> { -+ }).map((entity1) -> { // Paper - remap fix - LivingEntity entityliving1; - -- if (entity instanceof LivingEntity entityliving2) { -+ if (entity1 instanceof LivingEntity entityliving2) { // Paper - remap fix - entityliving1 = entityliving2; - } else { - entityliving1 = null; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java.patch deleted file mode 100644 index d9692605cb..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java -+++ b/net/minecraft/world/entity/ai/behavior/GoToWantedItem.java -@@ -28,6 +28,21 @@ - ItemEntity entityitem = (ItemEntity) behaviorbuilder_b.get(memoryaccessor2); - - if (behaviorbuilder_b.tryGet(memoryaccessor3).isEmpty() && startCondition.test(entityliving) && entityitem.closerThan(entityliving, (double) radius) && entityliving.level().getWorldBorder().isWithinBounds(entityitem.blockPosition()) && entityliving.canPickUpLoot()) { -+ // CraftBukkit start -+ if (entityliving instanceof net.minecraft.world.entity.animal.allay.Allay) { -+ org.bukkit.event.entity.EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetEvent(entityliving, entityitem, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY); -+ -+ if (event.isCancelled()) { -+ return false; -+ } -+ if (!(event.getTarget() instanceof org.bukkit.craftbukkit.entity.CraftItem)) { // Paper - only erase allay memory on non-item targets -+ memoryaccessor2.erase(); -+ return false; // Paper - only erase allay memory on non-item targets -+ } -+ -+ entityitem = (ItemEntity) ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); -+ } -+ // CraftBukkit end - WalkTarget memorytarget = new WalkTarget(new EntityTracker(entityitem, false), speed, 0); - - memoryaccessor.set(new EntityTracker(entityitem, true)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch deleted file mode 100644 index 066bfd1863..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch +++ /dev/null @@ -1,63 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java -+++ b/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java -@@ -22,10 +22,15 @@ - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.level.GameRules; - import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.gameevent.GameEvent; -+ -+// CraftBukkit start -+import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.CropBlock; - import net.minecraft.world.level.block.FarmBlock; - import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.gameevent.GameEvent; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class HarvestFarmland extends Behavior { - -@@ -82,8 +87,8 @@ - - protected void start(ServerLevel worldserver, Villager entityvillager, long i) { - if (i > this.nextOkStartTime && this.aboveFarmlandPos != null) { -- entityvillager.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new BlockPosTracker(this.aboveFarmlandPos))); -- entityvillager.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new WalkTarget(new BlockPosTracker(this.aboveFarmlandPos), 0.5F, 1))); -+ entityvillager.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new BlockPosTracker(this.aboveFarmlandPos))); // CraftBukkit - decompile error -+ entityvillager.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new WalkTarget(new BlockPosTracker(this.aboveFarmlandPos), 0.5F, 1))); // CraftBukkit - decompile error - } - - } -@@ -103,7 +108,9 @@ - Block block1 = world.getBlockState(this.aboveFarmlandPos.below()).getBlock(); - - if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata)) { -+ if (CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, iblockdata.getFluidState().createLegacyBlock())) { // CraftBukkit // Paper - fix wrong block state - world.destroyBlock(this.aboveFarmlandPos, true, entity); -+ } // CraftBukkit - } - - if (iblockdata.isAir() && block1 instanceof FarmBlock && entity.hasFarmSeeds()) { -@@ -120,9 +127,11 @@ - BlockItem itemblock = (BlockItem) item; - BlockState iblockdata1 = itemblock.getBlock().defaultBlockState(); - -+ if (CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, iblockdata1)) { // CraftBukkit - world.setBlockAndUpdate(this.aboveFarmlandPos, iblockdata1); - world.gameEvent((Holder) GameEvent.BLOCK_PLACE, this.aboveFarmlandPos, GameEvent.Context.of(entity, iblockdata1)); - flag = true; -+ } // CraftBukkit - } - } - -@@ -142,8 +151,8 @@ - this.aboveFarmlandPos = this.getValidFarmland(world); - if (this.aboveFarmlandPos != null) { - this.nextOkStartTime = time + 20L; -- entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new WalkTarget(new BlockPosTracker(this.aboveFarmlandPos), 0.5F, 1))); -- entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new BlockPosTracker(this.aboveFarmlandPos))); -+ entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new WalkTarget(new BlockPosTracker(this.aboveFarmlandPos), 0.5F, 1))); // CraftBukkit - decompile error -+ entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new BlockPosTracker(this.aboveFarmlandPos))); // CraftBukkit - decompile error - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch deleted file mode 100644 index 7348471be5..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java -+++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java -@@ -61,6 +61,13 @@ - DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock(); - - if (!blockdoor.isOpen(iblockdata)) { -+ // CraftBukkit start - entities opening doors -+ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.level(), blockposition)); -+ entityliving.level().getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return false; -+ } -+ // CraftBukkit end - blockdoor.setOpen(entityliving, worldserver, iblockdata, blockposition, true); - } - -@@ -76,6 +83,13 @@ - DoorBlock blockdoor1 = (DoorBlock) iblockdata1.getBlock(); - - if (!blockdoor1.isOpen(iblockdata1)) { -+ // CraftBukkit start - entities opening doors -+ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.level(), blockposition1)); -+ entityliving.level().getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return false; -+ } -+ // CraftBukkit end - blockdoor1.setOpen(entityliving, worldserver, iblockdata1, blockposition1, true); - optional = InteractWithDoor.rememberDoorToClose(memoryaccessor1, optional, worldserver, blockposition1); - } -@@ -129,7 +143,7 @@ - } - - private static boolean areOtherMobsComingThroughDoor(LivingEntity entity, BlockPos pos, Optional> otherMobs) { -- return otherMobs.isEmpty() ? false : ((List) otherMobs.get()).stream().filter((entityliving1) -> { -+ return otherMobs.isEmpty() ? false : (otherMobs.get()).stream().filter((entityliving1) -> { // CraftBukkit - decompile error - return entityliving1.getType() == entity.getType(); - }).filter((entityliving1) -> { - return pos.closerToCenterThan(entityliving1.position(), 2.0D); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java.patch deleted file mode 100644 index 18aef70f25..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java -+++ b/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java -@@ -13,6 +13,7 @@ - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.sounds.SoundEvent; - import net.minecraft.sounds.SoundSource; - import net.minecraft.util.Mth; -@@ -30,6 +31,10 @@ - import net.minecraft.world.level.pathfinder.Path; - import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; - import net.minecraft.world.phys.Vec3; -+import org.bukkit.craftbukkit.entity.CraftLivingEntity; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityTargetEvent; -+// CraftBukkit end - - public class PrepareRamNearestTarget extends Behavior { - -@@ -63,6 +68,13 @@ - return this.ramTargeting.test(worldserver, entitycreature, entityliving); - }); - }).ifPresent((entityliving) -> { -+ // CraftBukkit start -+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entitycreature, entityliving, (entityliving instanceof ServerPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY); -+ if (event.isCancelled() || event.getTarget() == null) { -+ return; -+ } -+ entityliving = ((CraftLivingEntity) event.getTarget()).getHandle(); -+ // CraftBukkit end - this.chooseRamPosition(entitycreature, entityliving); - }); - } -@@ -72,7 +84,7 @@ - - if (!behaviorcontroller.hasMemoryValue(MemoryModuleType.RAM_TARGET)) { - world.broadcastEntityEvent(entity, (byte) 59); -- behaviorcontroller.setMemory(MemoryModuleType.RAM_COOLDOWN_TICKS, (Object) this.getCooldownOnFail.applyAsInt(entity)); -+ behaviorcontroller.setMemory(MemoryModuleType.RAM_COOLDOWN_TICKS, this.getCooldownOnFail.applyAsInt(entity)); // CraftBukkit - decompile error - } - - } -@@ -83,8 +95,8 @@ - - protected void tick(ServerLevel worldserver, E e0, long i) { - if (!this.ramCandidate.isEmpty()) { -- e0.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new WalkTarget(((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getStartPosition(), this.walkSpeed, 0))); -- e0.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new EntityTracker(((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getTarget(), true))); -+ e0.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new WalkTarget(((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getStartPosition(), this.walkSpeed, 0))); // CraftBukkit - decompile error -+ e0.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new EntityTracker(((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getTarget(), true))); // CraftBukkit - decompile error - boolean flag = !((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getTarget().blockPosition().equals(((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getTargetPosition()); - - if (flag) { -@@ -101,7 +113,7 @@ - } - - if (i - (Long) this.reachedRamPositionTimestamp.get() >= (long) this.ramPrepareTime) { -- e0.getBrain().setMemory(MemoryModuleType.RAM_TARGET, (Object) this.getEdgeOfBlock(blockposition, ((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getTargetPosition())); -+ e0.getBrain().setMemory(MemoryModuleType.RAM_TARGET, this.getEdgeOfBlock(blockposition, ((PrepareRamNearestTarget.RamCandidate) this.ramCandidate.get()).getTargetPosition())); // CraftBukkit - decompile error - worldserver.playSound((Player) null, (Entity) e0, (SoundEvent) this.getPrepareRamSound.apply(e0), SoundSource.NEUTRAL, 1.0F, e0.getVoicePitch()); - this.ramCandidate = Optional.empty(); - } -@@ -153,7 +165,7 @@ - } - - PathNavigation navigationabstract = entity.getNavigation(); -- Stream stream = list.stream(); -+ Stream stream = list.stream(); // CraftBukkit - decompile error - BlockPos blockposition1 = entity.blockPosition(); - - Objects.requireNonNull(blockposition1); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch deleted file mode 100644 index 3c23484d4f..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/RamTarget.java -+++ b/net/minecraft/world/entity/ai/behavior/RamTarget.java -@@ -89,7 +89,7 @@ - float f = 0.25F * (float)(i - j); - float g = Mth.clamp(entity.getSpeed() * 1.65F, 0.2F, 3.0F) + f; - float h = livingEntity.isDamageSourceBlocked(world.damageSources().mobAttack(entity)) ? 0.5F : 1.0F; -- livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z()); -+ livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent - this.finishRam(world, entity); - world.playSound(null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F); - } else if (this.hasRammedHornBreakingBlock(world, entity)) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/ResetProfession.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/ResetProfession.java.patch deleted file mode 100644 index f5dc7ba366..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/ResetProfession.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/ResetProfession.java -+++ b/net/minecraft/world/entity/ai/behavior/ResetProfession.java -@@ -6,6 +6,12 @@ - import net.minecraft.world.entity.npc.VillagerData; - import net.minecraft.world.entity.npc.VillagerProfession; - -+// CraftBukkit start -+import org.bukkit.craftbukkit.entity.CraftVillager; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.VillagerCareerChangeEvent; -+// CraftBukkit end -+ - public class ResetProfession { - - public ResetProfession() {} -@@ -17,7 +23,14 @@ - VillagerData villagerdata = entityvillager.getVillagerData(); - - if (villagerdata.getProfession() != VillagerProfession.NONE && villagerdata.getProfession() != VillagerProfession.NITWIT && entityvillager.getVillagerXp() == 0 && villagerdata.getLevel() <= 1) { -- entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(VillagerProfession.NONE)); -+ // CraftBukkit start -+ VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityvillager, CraftVillager.CraftProfession.minecraftToBukkit(VillagerProfession.NONE), VillagerCareerChangeEvent.ChangeReason.LOSING_JOB); -+ if (event.isCancelled()) { -+ return false; -+ } -+ -+ entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession()))); -+ // CraftBukkit end - entityvillager.refreshBrain(worldserver); - return true; - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch deleted file mode 100644 index 0a02e4eb2c..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/StartAttacking.java -+++ b/net/minecraft/world/entity/ai/behavior/StartAttacking.java -@@ -2,10 +2,15 @@ - - import java.util.Optional; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.entity.LivingEntity; - import net.minecraft.world.entity.Mob; - import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder; - import net.minecraft.world.entity.ai.memory.MemoryModuleType; -+import org.bukkit.craftbukkit.entity.CraftLivingEntity; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityTargetEvent; -+// CraftBukkit end - - public class StartAttacking { - -@@ -34,6 +39,17 @@ - if (!entityinsentient.canAttack(entityliving)) { - return false; - } else { -+ // CraftBukkit start -+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityinsentient, entityliving, (entityliving instanceof ServerPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY); -+ if (event.isCancelled()) { -+ return false; -+ } -+ if (event.getTarget() == null) { -+ memoryaccessor.erase(); -+ return true; -+ } -+ entityliving = ((CraftLivingEntity) event.getTarget()).getHandle(); -+ // CraftBukkit end - memoryaccessor.set(entityliving); - memoryaccessor1.erase(); - return true; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java.patch deleted file mode 100644 index c156a35921..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java -+++ b/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java -@@ -7,6 +7,12 @@ - import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder; - import net.minecraft.world.entity.ai.memory.MemoryModuleType; - -+// CraftBukkit start -+import org.bukkit.craftbukkit.entity.CraftLivingEntity; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityTargetEvent; -+// CraftBukkit end -+ - public class StopAttackingIfTargetInvalid { - - private static final int TIMEOUT_TO_GET_WITHIN_ATTACK_RANGE = 200; -@@ -40,6 +46,30 @@ - if (entityinsentient.canAttack(entityliving) && (!shouldForgetIfTargetUnreachable || !StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) && entityliving.isAlive() && entityliving.level() == entityinsentient.level() && !condition.test(worldserver, entityliving)) { - return true; - } else { -+ // Paper start - better track target change reason -+ final EntityTargetEvent.TargetReason reason; -+ if (!entityinsentient.canAttack(entityliving)) { -+ reason = EntityTargetEvent.TargetReason.TARGET_INVALID; -+ } else if (shouldForgetIfTargetUnreachable && StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) { -+ reason = EntityTargetEvent.TargetReason.FORGOT_TARGET; -+ } else if (!entityliving.isAlive()) { -+ reason = EntityTargetEvent.TargetReason.TARGET_DIED; -+ } else if (entityliving.level() != entityinsentient.level()) { -+ reason = EntityTargetEvent.TargetReason.TARGET_OTHER_LEVEL; -+ } else { -+ reason = EntityTargetEvent.TargetReason.TARGET_INVALID; -+ } -+ // Paper end -+ // CraftBukkit start -+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityinsentient, null, reason); // Paper -+ if (event.isCancelled()) { -+ return false; -+ } -+ if (event.getTarget() != null) { -+ entityinsentient.getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, ((CraftLivingEntity) event.getTarget()).getHandle()); -+ return true; -+ } -+ // CraftBukkit end - callback.accept(worldserver, entityinsentient, entityliving); - memoryaccessor.erase(); - return true; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java.patch deleted file mode 100644 index e0fa77caef..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java -+++ b/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java -@@ -39,6 +39,12 @@ - if (worldserver.getBlockState(blockposition2).isAir()) { - BlockState iblockdata = frogSpawn.defaultBlockState(); - -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityliving, blockposition2, iblockdata)) { -+ memoryaccessor2.erase(); -+ return true; -+ } -+ // CraftBukkit end - worldserver.setBlock(blockposition2, iblockdata, 3); - worldserver.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition2, GameEvent.Context.of(entityliving, iblockdata)); - worldserver.playSound((Player) null, (Entity) entityliving, SoundEvents.FROG_LAY_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch deleted file mode 100644 index 9875c853b9..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java -+++ b/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java -@@ -17,6 +17,10 @@ - import net.minecraft.world.entity.ai.village.poi.PoiTypes; - import net.minecraft.world.entity.npc.Villager; - import net.minecraft.world.level.pathfinder.Path; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.CreatureSpawnEvent; -+// CraftBukkit end - - public class VillagerMakeLove extends Behavior { - -@@ -114,11 +118,17 @@ - if (entityvillager2 == null) { - return Optional.empty(); - } else { -- parent.setAge(6000); -- partner.setAge(6000); - entityvillager2.setAge(-24000); - entityvillager2.moveTo(parent.getX(), parent.getY(), parent.getZ(), 0.0F, 0.0F); -- world.addFreshEntityWithPassengers(entityvillager2); -+ // CraftBukkit start - call EntityBreedEvent -+ if (CraftEventFactory.callEntityBreedEvent(entityvillager2, parent, partner, null, null, 0).isCancelled()) { -+ return Optional.empty(); -+ } -+ // Move age setting down -+ parent.setAge(6000); -+ partner.setAge(6000); -+ world.addFreshEntityWithPassengers(entityvillager2, CreatureSpawnEvent.SpawnReason.BREEDING); -+ // CraftBukkit end - world.broadcastEntityEvent(entityvillager2, (byte) 12); - return Optional.of(entityvillager2); - } -@@ -127,6 +137,6 @@ - private void giveBedToChild(ServerLevel world, Villager child, BlockPos pos) { - GlobalPos globalpos = GlobalPos.of(world.dimension(), pos); - -- child.getBrain().setMemory(MemoryModuleType.HOME, (Object) globalpos); -+ child.getBrain().setMemory(MemoryModuleType.HOME, globalpos); // CraftBukkit - decompile error - } - }