net/minecraft/world/entity/ai/behavior/

This commit is contained in:
Owen1212055 2024-12-14 17:25:17 -05:00
parent 4707f46b25
commit d096e6baaf
No known key found for this signature in database
GPG key ID: 2133292072886A30
34 changed files with 324 additions and 560 deletions

View file

@ -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<BlockPos> predicate1 = pos -> {

View file

@ -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;

View file

@ -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
);

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/behavior/Behavior.java --- a/net/minecraft/world/entity/ai/behavior/Behavior.java
+++ b/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 long endTimestamp;
private final int minDuration; private final int minDuration;
private final int maxDuration; private final int maxDuration;
@ -8,12 +8,12 @@
+ private final String configKey; + private final String configKey;
+ // Paper end - configurable behavior tick rate and timings + // Paper end - configurable behavior tick rate and timings
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState) { public Behavior(Map<MemoryModuleType<?>, MemoryStatus> entryCondition) {
this(requiredMemoryState, 60); this(entryCondition, 60);
@@ -27,6 +30,14 @@ @@ -27,6 +_,14 @@
this.minDuration = minRunTime; this.minDuration = minDuration;
this.maxDuration = maxRunTime; this.maxDuration = maxDuration;
this.entryCondition = requiredMemoryState; this.entryCondition = entryCondition;
+ // Paper start - configurable behavior tick rate and timings + // 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(); + 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('.'); + int lastSeparator = key.lastIndexOf('.');
@ -25,16 +25,16 @@
} }
@Override @Override
@@ -36,6 +47,12 @@ @@ -36,6 +_,12 @@
@Override @Override
public final boolean tryStart(ServerLevel world, E entity, long time) { public final boolean tryStart(ServerLevel level, E owner, long gameTime) {
+ // Paper start - configurable behavior tick rate and timings + // Paper start - configurable behavior tick rate and timings
+ int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1); + int tickRate = java.util.Objects.requireNonNullElse(level.paperConfig().tickRates.behavior.get(owner.getType(), this.configKey), -1);
+ if (tickRate > -1 && time < this.endTimestamp + tickRate) { + if (tickRate > -1 && gameTime < this.endTimestamp + tickRate) {
+ return false; + return false;
+ } + }
+ // Paper end - configurable behavior tick rate and timings + // Paper end - configurable behavior tick rate and timings
if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) { if (this.hasRequiredMemories(owner) && this.checkExtraStartConditions(level, owner)) {
this.status = Behavior.Status.RUNNING; 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);

View file

@ -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);
}

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/behavior/GateBehavior.java --- a/net/minecraft/world/entity/ai/behavior/GateBehavior.java
+++ b/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<MemoryModuleType<?>> exitErasedMemories; private final Set<MemoryModuleType<?>> exitErasedMemories;
private final GateBehavior.OrderPolicy orderPolicy; private final GateBehavior.OrderPolicy orderPolicy;
private final GateBehavior.RunningPolicy runningPolicy; private final GateBehavior.RunningPolicy runningPolicy;

View file

@ -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);

View file

@ -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) {

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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)) {

View file

@ -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 {

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/behavior/ShufflingList.java --- a/net/minecraft/world/entity/ai/behavior/ShufflingList.java
+++ b/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<U> implements Iterable<U> { public class ShufflingList<U> implements Iterable<U> {
protected final List<ShufflingList.WeightedEntry<U>> entries; protected final List<ShufflingList.WeightedEntry<U>> entries;
private final RandomSource random = RandomSource.create(); private final RandomSource random = RandomSource.create();
@ -16,17 +16,17 @@
this.entries = Lists.newArrayList(); this.entries = Lists.newArrayList();
} }
private ShufflingList(List<ShufflingList.WeightedEntry<U>> list) { private ShufflingList(List<ShufflingList.WeightedEntry<U>> entries) {
+ // Paper start - Fix Concurrency issue in ShufflingList during worldgen + // Paper start - Fix Concurrency issue in ShufflingList during worldgen
+ this(list, true); + this(entries, true);
+ } + }
+ private ShufflingList(List<ShufflingList.WeightedEntry<U>> list, boolean isUnsafe) { + private ShufflingList(List<ShufflingList.WeightedEntry<U>> entries, boolean isUnsafe) {
+ this.isUnsafe = isUnsafe; + this.isUnsafe = isUnsafe;
+ // Paper end - Fix Concurrency issue in ShufflingList during worldgen + // 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<U> shuffle() { public ShufflingList<U> shuffle() {

View file

@ -1,12 +1,12 @@
--- a/net/minecraft/world/entity/ai/behavior/SleepInBed.java --- a/net/minecraft/world/entity/ai/behavior/SleepInBed.java
+++ b/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 = level.getBlockState(globalPos.pos());
+ BlockState blockState = world.getBlockStateIfLoaded(globalPos.pos()); // Paper - Prevent sync chunk loads when villagers try to find beds + 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 + 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);
} }
} }

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -1,11 +1,11 @@
--- a/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java --- a/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
+++ b/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(1, new MoveToTargetSink()),
Pair.of(2, PoiCompetitorScan.create()), Pair.of(2, PoiCompetitorScan.create()),
Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), Pair.of(3, new LookAndFollowTradingPlayerSink(speedModifier)),
- Pair.of(5, GoToWantedItem.create(speed, false, 4)), - Pair.of(5, GoToWantedItem.create(speedModifier, false, 4)),
+ Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speed, false, 4)), // Paper - Fix MC-157464 + Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speedModifier, false, 4)), // Paper - Fix MC-157464
Pair.of( Pair.of(
6, 6,
AcquirePoi.create( AcquirePoi.create(

View file

@ -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);
}

View file

@ -1,12 +1,12 @@
--- a/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java --- a/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
+++ b/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java +++ b/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
@@ -86,7 +86,9 @@ @@ -86,7 +_,9 @@
simpleContainer.removeItemType(Items.WHEAT, m); inventory.removeItemType(Items.WHEAT, i3);
ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l)); ItemStack itemStack = inventory.addItem(new ItemStack(Items.BREAD, min));
if (!itemStack.isEmpty()) { if (!itemStack.isEmpty()) {
+ villager.forceDrops = true; // Paper - Add missing forceDrop toggles + villager.forceDrops = true; // Paper - Add missing forceDrop toggle
villager.spawnAtLocation(world, itemStack, 0.5F); villager.spawnAtLocation(level, itemStack, 0.5F);
+ villager.forceDrops = false; // Paper - Add missing forceDrop toggles + villager.forceDrops = false; // Paper - Add missing forceDrop toggle
} }
} }
} }

View file

@ -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<BlockPos> predicate2 = pos -> {

View file

@ -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;

View file

@ -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));

View file

@ -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<SectionPos> 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;

View file

@ -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));

View file

@ -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<Villager> {
@@ -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
}
}
}

View file

@ -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<List<LivingEntity>> 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);

View file

@ -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<E extends PathfinderMob> extends Behavior<E> {
@@ -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<BlockPos> stream = list.stream(); // CraftBukkit - decompile error
BlockPos blockposition1 = entity.blockPosition();
Objects.requireNonNull(blockposition1);

View file

@ -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)) {

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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<Villager> {
@@ -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
}
}