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.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 TEMP_TARGETING = TargetingConditions.forNonCombat().range(10.0).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 items; private final boolean canScare; public TemptGoal(PathfinderMob mob, double speedModifier, Predicate 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 = TEMP_TARGETING.copy().selector(this::shouldFollow); } @Override public boolean canUse() { if (this.calmDown > 0) { this.calmDown--; return false; } else { this.player = this.mob.level().getNearestPlayer(this.targetingConditions, 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; } }