minecraft-src/net/minecraft/world/entity/ai/goal/TemptGoal.java
2025-09-18 12:27:44 +00:00

152 lines
4.5 KiB
Java

package net.minecraft.world.entity.ai.goal;
import java.util.EnumSet;
import java.util.function.Predicate;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
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;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
public class TemptGoal extends Goal {
private static final TargetingConditions TEMPT_TARGETING = TargetingConditions.forNonCombat().ignoreLineOfSight();
private static final double DEFAULT_STOP_DISTANCE = 2.5;
private final TargetingConditions targetingConditions;
protected final Mob mob;
protected final double speedModifier;
private double px;
private double py;
private double pz;
private double pRotX;
private double pRotY;
@Nullable
protected Player player;
private int calmDown;
private boolean isRunning;
private final Predicate<ItemStack> items;
private final boolean canScare;
private final double stopDistance;
public TemptGoal(PathfinderMob mob, double speedModifier, Predicate<ItemStack> items, boolean canScare) {
this((Mob)mob, speedModifier, items, canScare, 2.5);
}
public TemptGoal(PathfinderMob mob, double speedModifier, Predicate<ItemStack> items, boolean canScare, double stopDistance) {
this((Mob)mob, speedModifier, items, canScare, stopDistance);
}
TemptGoal(Mob mob, double speedModifier, Predicate<ItemStack> items, boolean canScare, double stopDistance) {
this.mob = mob;
this.speedModifier = speedModifier;
this.items = items;
this.canScare = canScare;
this.stopDistance = stopDistance;
this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
this.targetingConditions = TEMPT_TARGETING.copy().selector((livingEntity, serverLevel) -> this.shouldFollow(livingEntity));
}
@Override
public boolean canUse() {
if (this.calmDown > 0) {
this.calmDown--;
return false;
} else {
this.player = getServerLevel(this.mob).getNearestPlayer(this.targetingConditions.range(this.mob.getAttributeValue(Attributes.TEMPT_RANGE)), this.mob);
return this.player != null;
}
}
private boolean shouldFollow(LivingEntity entity) {
return this.items.test(entity.getMainHandItem()) || this.items.test(entity.getOffhandItem());
}
@Override
public boolean canContinueToUse() {
if (this.canScare()) {
if (this.mob.distanceToSqr(this.player) < 36.0) {
if (this.player.distanceToSqr(this.px, this.py, this.pz) > 0.010000000000000002) {
return false;
}
if (Math.abs(this.player.getXRot() - this.pRotX) > 5.0 || Math.abs(this.player.getYRot() - this.pRotY) > 5.0) {
return false;
}
} else {
this.px = this.player.getX();
this.py = this.player.getY();
this.pz = this.player.getZ();
}
this.pRotX = this.player.getXRot();
this.pRotY = this.player.getYRot();
}
return this.canUse();
}
protected boolean canScare() {
return this.canScare;
}
@Override
public void start() {
this.px = this.player.getX();
this.py = this.player.getY();
this.pz = this.player.getZ();
this.isRunning = true;
}
@Override
public void stop() {
this.player = null;
this.stopNavigation();
this.calmDown = reducedTickDelay(100);
this.isRunning = false;
}
@Override
public void tick() {
this.mob.getLookControl().setLookAt(this.player, this.mob.getMaxHeadYRot() + 20, this.mob.getMaxHeadXRot());
if (this.mob.distanceToSqr(this.player) < this.stopDistance * this.stopDistance) {
this.stopNavigation();
} else {
this.navigateTowards(this.player);
}
}
protected void stopNavigation() {
this.mob.getNavigation().stop();
}
protected void navigateTowards(Player player) {
this.mob.getNavigation().moveTo(player, this.speedModifier);
}
/**
* @see #isRunning
*/
public boolean isRunning() {
return this.isRunning;
}
public static class ForNonPathfinders extends TemptGoal {
public ForNonPathfinders(Mob mob, double d, Predicate<ItemStack> predicate, boolean bl, double e) {
super(mob, d, predicate, bl, e);
}
@Override
protected void stopNavigation() {
this.mob.getMoveControl().setWait();
}
@Override
protected void navigateTowards(Player player) {
Vec3 vec3 = player.getEyePosition().subtract(this.mob.position()).scale(this.mob.getRandom().nextDouble()).add(this.mob.position());
this.mob.getMoveControl().setWantedPosition(vec3.x, vec3.y, vec3.z, this.speedModifier);
}
}
}