minecraft-src/net/minecraft/world/entity/ai/goal/TemptGoal.java
2025-07-04 02:00:41 +03:00

114 lines
3.2 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.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 org.jetbrains.annotations.Nullable;
public class TemptGoal extends Goal {
private static final TargetingConditions TEMPT_TARGETING = TargetingConditions.forNonCombat().ignoreLineOfSight();
private final TargetingConditions targetingConditions;
protected final PathfinderMob mob;
private 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;
public TemptGoal(PathfinderMob mob, double speedModifier, Predicate<ItemStack> items, boolean canScare) {
this.mob = mob;
this.speedModifier = speedModifier;
this.items = items;
this.canScare = canScare;
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.mob.getNavigation().stop();
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) < 6.25) {
this.mob.getNavigation().stop();
} else {
this.mob.getNavigation().moveTo(this.player, this.speedModifier);
}
}
/**
* @see #isRunning
*/
public boolean isRunning() {
return this.isRunning;
}
}