package com.owlmaddie.goals; import com.owlmaddie.controls.LookControls; import net.minecraft.entity.ai.FuzzyTargeting; import net.minecraft.entity.ai.pathing.EntityNavigation; import net.minecraft.entity.mob.*; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.math.Vec3d; import java.util.EnumSet; /** * The {@code FollowPlayerGoal} class instructs a Mob Entity to follow the current target entity. */ public class FollowPlayerGoal extends PlayerBaseGoal { private final MobEntity entity; private final EntityNavigation navigation; private final double speed; public FollowPlayerGoal(ServerPlayerEntity player, MobEntity entity, double speed) { super(player); this.entity = entity; this.speed = speed; this.navigation = entity.getNavigation(); this.setControls(EnumSet.of(Control.MOVE, Control.LOOK)); } @Override public boolean canStart() { // Start only if the target player is more than 8 blocks away return super.canStart() && this.entity.squaredDistanceTo(this.targetEntity) > 64; } @Override public boolean shouldContinue() { // Continue unless the entity gets within 3 blocks of the player return super.canStart() && this.entity.squaredDistanceTo(this.targetEntity) > 9; } @Override public void stop() { // Stop the entity temporarily this.navigation.stop(); } @Override public void tick() { if (this.entity instanceof EndermanEntity || this.entity instanceof EndermiteEntity || this.entity instanceof ShulkerEntity) { // Certain entities should teleport to the player if they get too far if (this.entity.squaredDistanceTo(this.targetEntity) > 256) { Vec3d targetPos = findTeleportPosition(12); if (targetPos != null) { this.entity.teleport(targetPos.x, targetPos.y, targetPos.z); } } } else { // Look at the player and start moving towards them if (this.targetEntity instanceof ServerPlayerEntity) { LookControls.lookAtPlayer((ServerPlayerEntity)this.targetEntity, this.entity); } this.navigation.startMovingTo(this.targetEntity, this.speed); } } private Vec3d findTeleportPosition(int distance) { if (this.entity instanceof PathAwareEntity) { return FuzzyTargeting.findTo((PathAwareEntity) this.entity, distance, distance, this.targetEntity.getPos()); } return null; } }