net.minecraft.world.entity.ai.goal

This commit is contained in:
Jake Potrebic 2024-12-14 18:55:46 -08:00
parent 1b5b2d8d45
commit aaf151c03d
No known key found for this signature in database
GPG Key ID: ECE0B3C133C016C5
14 changed files with 137 additions and 188 deletions

View File

@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
+++ b/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
@@ -72,9 +72,16 @@
@@ -73,9 +_,16 @@
}
if (this.breakTime == this.getDoorBreakTime() && this.isValidDifficulty(this.mob.level().getDifficulty())) {
@ -16,5 +16,5 @@
- this.mob.level().levelEvent(2001, this.doorPos, Block.getId(this.mob.level().getBlockState(this.doorPos)));
+ this.mob.level().levelEvent(2001, this.doorPos, Block.getId(oldState)); // Paper - fix MC-263999
}
}

View File

@ -0,0 +1,35 @@
--- a/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
@@ -26,6 +_,11 @@
@Override
public boolean canUse() {
+ // Paper start - Fix MC-210802
+ if (!((net.minecraft.server.level.ServerLevel) this.level).chunkSource.chunkMap.anyPlayerCloseEnoughForSpawning(this.mob.chunkPosition())) {
+ return false;
+ }
+ // Paper end
if (this.mob.getRandom().nextInt(this.mob.isBaby() ? 50 : 1000) != 0) {
return false;
} else {
@@ -60,8 +_,9 @@
this.eatAnimationTick = Math.max(0, this.eatAnimationTick - 1);
if (this.eatAnimationTick == this.adjustedTickDelay(4)) {
BlockPos blockPos = this.mob.blockPosition();
- if (IS_TALL_GRASS.test(this.level.getBlockState(blockPos))) {
- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ final BlockState blockState = this.level.getBlockState(blockPos); // Paper - fix wrong block state
+ if (IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockPos, blockState.getFluidState().createLegacyBlock(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state
this.level.destroyBlock(blockPos, false);
}
@@ -69,7 +_,7 @@
} else {
BlockPos blockPos1 = blockPos.below();
if (this.level.getBlockState(blockPos1).is(Blocks.GRASS_BLOCK)) {
- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockPos1, Blocks.DIRT.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state
this.level.levelEvent(2001, blockPos1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
this.level.setBlock(blockPos1, Blocks.DIRT.defaultBlockState(), 2);
}

View File

@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/goal/FloatGoal.java
+++ b/net/minecraft/world/entity/ai/goal/FloatGoal.java
@@ -9,6 +9,7 @@
@@ -9,6 +_,7 @@
public FloatGoal(Mob mob) {
this.mob = mob;

View File

@ -1,11 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
+++ b/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
@@ -72,7 +72,7 @@
@@ -72,7 +_,7 @@
public void tick() {
boolean bl = this.tamable.shouldTryTeleportToOwner();
if (!bl) {
- this.tamable.getLookControl().setLookAt(this.owner, 10.0F, (float)this.tamable.getMaxHeadXRot());
+ if (this.tamable.distanceToSqr(this.owner) <= 16 * 16) this.tamable.getLookControl().setLookAt(this.owner, 10.0F, (float)this.tamable.getMaxHeadXRot()); // Paper - Limit pet look distance
boolean shouldTryTeleportToOwner = this.tamable.shouldTryTeleportToOwner();
if (!shouldTryTeleportToOwner) {
- this.tamable.getLookControl().setLookAt(this.owner, 10.0F, this.tamable.getMaxHeadXRot());
+ if (this.tamable.distanceToSqr(this.owner) <= 16 * 16) this.tamable.getLookControl().setLookAt(this.owner, 10.0F, this.tamable.getMaxHeadXRot()); // Paper - Limit pet look distance
}
if (--this.timeToRecalcPath <= 0) {

View File

@ -1,9 +1,10 @@
--- a/net/minecraft/world/entity/ai/goal/Goal.java
+++ b/net/minecraft/world/entity/ai/goal/Goal.java
@@ -46,6 +46,16 @@
@@ -46,6 +_,17 @@
return this.flags;
}
+
+ // Paper start - Mob Goal API
+ public boolean hasFlag(final Goal.Flag flag) {
+ return this.flags.contains(flag);
@ -12,13 +13,13 @@
+ public void addFlag(final Goal.Flag flag) {
+ this.flags.add(flag);
+ }
+ // Paper end - Mob Goal API
+
protected int adjustedTickDelay(int ticks) {
return this.requiresUpdateEveryTick() ? ticks : reducedTickDelay(ticks);
+ // Paper end - Mob Goal API
protected int adjustedTickDelay(int adjustment) {
return this.requiresUpdateEveryTick() ? adjustment : reducedTickDelay(adjustment);
}
@@ -62,7 +72,19 @@
return (ServerLevel)world;
@@ -62,7 +_,19 @@
return (ServerLevel)level;
}
+ // Paper start - Mob goal api

View File

@ -0,0 +1,42 @@
--- a/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
@@ -104,6 +_,11 @@
}
if (this.ticksSinceReachedGoal > 60) {
+ // CraftBukkit start - Step on eggs
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityInteractEvent(this.removerMob, org.bukkit.craftbukkit.block.CraftBlock.at(level, posWithBlock))) {
+ return;
+ }
+ // CraftBukkit end
level.removeBlock(posWithBlock, false);
if (!level.isClientSide) {
for (int i = 0; i < 20; i++) {
@@ -124,13 +_,16 @@
@Nullable
private BlockPos getPosWithBlock(BlockPos pos, BlockGetter level) {
- if (level.getBlockState(pos).is(this.blockToRemove)) {
+ net.minecraft.world.level.block.state.BlockState block = level.getBlockStateIfLoaded(pos); // Paper - Prevent AI rules from loading chunks
+ if (block == null) return null; // Paper - Prevent AI rules from loading chunks
+ if (block.is(this.blockToRemove)) { // Paper - Prevent AI rules from loading chunks
return pos;
} else {
BlockPos[] blockPoss = new BlockPos[]{pos.below(), pos.west(), pos.east(), pos.north(), pos.south(), pos.below().below()};
for (BlockPos blockPos : blockPoss) {
- if (level.getBlockState(blockPos).is(this.blockToRemove)) {
+ net.minecraft.world.level.block.state.BlockState block2 = level.getBlockStateIfLoaded(blockPos); // Paper - Prevent AI rules from loading chunks
+ if (block2 != null && block2.is(this.blockToRemove)) { // Paper - Prevent AI rules from loading chunks
return blockPos;
}
}
@@ -141,7 +_,7 @@
@Override
protected boolean isValidTarget(LevelReader level, BlockPos pos) {
- ChunkAccess chunk = level.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()), ChunkStatus.FULL, false);
+ ChunkAccess chunk = level.getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4); // Paper - Prevent AI rules from loading chunks
return chunk != null
&& chunk.getBlockState(pos).is(this.blockToRemove)
&& chunk.getBlockState(pos.above()).isAir()

View File

@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
+++ b/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
@@ -58,7 +_,7 @@
if (firstPassenger instanceof Player player) {
int temper = this.horse.getTemper();
int maxTemper = this.horse.getMaxTemper();
- if (maxTemper > 0 && this.horse.getRandom().nextInt(maxTemper) < temper) {
+ if (maxTemper > 0 && this.horse.getRandom().nextInt(maxTemper) < temper && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.horse, ((org.bukkit.craftbukkit.entity.CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { // CraftBukkit - fire EntityTameEvent
this.horse.tameWithName(player);
return;
}

View File

@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/goal/SitWhenOrderedToGoal.java
+++ b/net/minecraft/world/entity/ai/goal/SitWhenOrderedToGoal.java
@@ -22,7 +22,7 @@
@@ -20,7 +_,7 @@
@Override
public boolean canUse() {
if (!this.mob.isTame()) {

View File

@ -1,17 +1,17 @@
--- a/net/minecraft/world/entity/ai/goal/SwellGoal.java
+++ b/net/minecraft/world/entity/ai/goal/SwellGoal.java
@@ -21,7 +21,14 @@
return this.creeper.getSwellDir() > 0 || livingEntity != null && this.creeper.distanceToSqr(livingEntity) < 9.0;
@@ -21,6 +_,14 @@
return this.creeper.getSwellDir() > 0 || target != null && this.creeper.distanceToSqr(target) < 9.0;
}
+ // Paper start - Fix MC-179072
@Override
+ @Override
+ public boolean canContinueToUse() {
+ return !net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(this.creeper.getTarget()) && canUse();
+ return !net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(this.creeper.getTarget()) && this.canUse();
+ }
+ // Paper end
+
+ @Override
+
@Override
public void start() {
this.creeper.getNavigation().stop();
this.target = this.creeper.getTarget();

View File

@ -0,0 +1,27 @@
--- a/net/minecraft/world/entity/ai/goal/TemptGoal.java
+++ b/net/minecraft/world/entity/ai/goal/TemptGoal.java
@@ -21,7 +_,7 @@
private double pRotX;
private double pRotY;
@Nullable
- protected Player player;
+ protected LivingEntity player; // CraftBukkit
private int calmDown;
private boolean isRunning;
private final Predicate<ItemStack> items;
@@ -44,6 +_,15 @@
} else {
this.player = getServerLevel(this.mob)
.getNearestPlayer(this.targetingConditions.range(this.mob.getAttributeValue(Attributes.TEMPT_RANGE)), this.mob);
+ // CraftBukkit start
+ if (this.player != null) {
+ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(this.mob, this.player, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TEMPT);
+ if (event.isCancelled()) {
+ return false;
+ }
+ this.player = (event.getTarget() == null) ? null : ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle();
+ }
+ // CraftBukkit end
return this.player != null;
}
}

View File

@ -1,46 +0,0 @@
--- a/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
@@ -11,6 +11,10 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.predicate.BlockStatePredicate;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class EatBlockGoal extends Goal {
private static final int EAT_ANIMATION_TICKS = 40;
@@ -27,6 +31,11 @@
@Override
public boolean canUse() {
+ // Paper start - Fix MC-210802
+ if (!((net.minecraft.server.level.ServerLevel) this.level).chunkSource.chunkMap.anyPlayerCloseEnoughForSpawning(this.mob.chunkPosition())) {
+ return false;
+ }
+ // Paper end
if (this.mob.getRandom().nextInt(this.mob.isBaby() ? 50 : 1000) != 0) {
return false;
} else {
@@ -63,8 +72,9 @@
if (this.eatAnimationTick == this.adjustedTickDelay(4)) {
BlockPos blockposition = this.mob.blockPosition();
- if (EatBlockGoal.IS_TALL_GRASS.test(this.level.getBlockState(blockposition))) {
- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ final BlockState blockState = this.level.getBlockState(blockposition); // Paper - fix wrong block state
+ if (EatBlockGoal.IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state
this.level.destroyBlock(blockposition, false);
}
@@ -73,7 +83,7 @@
BlockPos blockposition1 = blockposition.below();
if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) {
- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state
this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2);
}

View File

@ -1,55 +0,0 @@
--- a/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
@@ -21,6 +21,10 @@
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import org.bukkit.craftbukkit.block.CraftBlock;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
public class RemoveBlockGoal extends MoveToBlockGoal {
@@ -97,6 +101,11 @@
}
if (this.ticksSinceReachedGoal > 60) {
+ // CraftBukkit start - Step on eggs
+ if (!CraftEventFactory.callEntityInteractEvent(this.removerMob, CraftBlock.at(world, blockposition1))) {
+ return;
+ }
+ // CraftBukkit end
world.removeBlock(blockposition1, false);
if (!world.isClientSide) {
for (int i = 0; i < 20; ++i) {
@@ -118,7 +127,9 @@
@Nullable
private BlockPos getPosWithBlock(BlockPos pos, BlockGetter world) {
- if (world.getBlockState(pos).is(this.blockToRemove)) {
+ net.minecraft.world.level.block.state.BlockState block = world.getBlockStateIfLoaded(pos); // Paper - Prevent AI rules from loading chunks
+ if (block == null) return null; // Paper - Prevent AI rules from loading chunks
+ if (block.is(this.blockToRemove)) { // Paper - Prevent AI rules from loading chunks
return pos;
} else {
BlockPos[] ablockposition = new BlockPos[]{pos.below(), pos.west(), pos.east(), pos.north(), pos.south(), pos.below().below()};
@@ -128,7 +139,8 @@
for (int j = 0; j < i; ++j) {
BlockPos blockposition1 = ablockposition1[j];
- if (world.getBlockState(blockposition1).is(this.blockToRemove)) {
+ net.minecraft.world.level.block.state.BlockState block2 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent AI rules from loading chunks
+ if (block2 != null && block2.is(this.blockToRemove)) { // Paper - Prevent AI rules from loading chunks
return blockposition1;
}
}
@@ -139,7 +151,7 @@
@Override
protected boolean isValidTarget(LevelReader world, BlockPos pos) {
- ChunkAccess ichunkaccess = world.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()), ChunkStatus.FULL, false);
+ ChunkAccess ichunkaccess = world.getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4); // Paper - Prevent AI rules from loading chunks
return ichunkaccess == null ? false : ichunkaccess.getBlockState(pos).is(this.blockToRemove) && ichunkaccess.getBlockState(pos.above()).isAir() && ichunkaccess.getBlockState(pos.above(2)).isAir();
}

View File

@ -1,22 +0,0 @@
--- a/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
+++ b/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
@@ -6,6 +6,10 @@
import net.minecraft.world.entity.animal.horse.AbstractHorse;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
public class RunAroundLikeCrazyGoal extends Goal {
@@ -63,7 +67,7 @@
int i = this.horse.getTemper();
int j = this.horse.getMaxTemper();
- if (j > 0 && this.horse.getRandom().nextInt(j) < i) {
+ if (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { // CraftBukkit - fire EntityTameEvent
this.horse.tameWithName(entityhuman);
return;
}

View File

@ -1,44 +0,0 @@
--- a/net/minecraft/world/entity/ai/goal/TemptGoal.java
+++ b/net/minecraft/world/entity/ai/goal/TemptGoal.java
@@ -8,9 +8,15 @@
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;
-import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
+// 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 TemptGoal extends Goal {
private static final TargetingConditions TEMPT_TARGETING = TargetingConditions.forNonCombat().ignoreLineOfSight();
@@ -23,7 +29,7 @@
private double pRotX;
private double pRotY;
@Nullable
- protected Player player;
+ protected LivingEntity player; // CraftBukkit
private int calmDown;
private boolean isRunning;
private final Predicate<ItemStack> items;
@@ -47,6 +53,15 @@
return false;
} else {
this.player = getServerLevel((Entity) this.mob).getNearestPlayer(this.targetingConditions.range(this.mob.getAttributeValue(Attributes.TEMPT_RANGE)), this.mob);
+ // CraftBukkit start
+ if (this.player != null) {
+ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this.mob, this.player, EntityTargetEvent.TargetReason.TEMPT);
+ if (event.isCancelled()) {
+ return false;
+ }
+ this.player = (event.getTarget() == null) ? null : ((CraftLivingEntity) event.getTarget()).getHandle();
+ }
+ // CraftBukkit end
return this.player != null;
}
}