FollowPlayerGoal.java 2.56 KB
Newer Older
1 2
package com.owlmaddie.goals;

3
import com.owlmaddie.controls.LookControls;
4
import net.minecraft.entity.ai.FuzzyTargeting;
5
import net.minecraft.entity.ai.pathing.EntityNavigation;
6
import net.minecraft.entity.mob.*;
7
import net.minecraft.server.network.ServerPlayerEntity;
8
import net.minecraft.util.math.Vec3d;
9 10 11 12

import java.util.EnumSet;

/**
13
 * The {@code FollowPlayerGoal} class instructs a Mob Entity to follow the current target entity.
14
 */
15
public class FollowPlayerGoal extends PlayerBaseGoal {
16 17 18 19 20
    private final MobEntity entity;
    private final EntityNavigation navigation;
    private final double speed;

    public FollowPlayerGoal(ServerPlayerEntity player, MobEntity entity, double speed) {
21
        super(player);
22 23 24
        this.entity = entity;
        this.speed = speed;
        this.navigation = entity.getNavigation();
25
        this.setControls(EnumSet.of(Control.MOVE, Control.LOOK));
26 27 28 29
    }

    @Override
    public boolean canStart() {
30
        // Start only if the target player is more than 8 blocks away
31
        return super.canStart() && this.entity.squaredDistanceTo(this.targetEntity) > 64;
32 33 34 35
    }

    @Override
    public boolean shouldContinue() {
36
        // Continue unless the entity gets within 3 blocks of the player
37
        return super.canStart() && this.entity.squaredDistanceTo(this.targetEntity) > 9;
38 39 40 41
    }

    @Override
    public void stop() {
42
        // Stop the entity temporarily
43 44 45 46 47
        this.navigation.stop();
    }

    @Override
    public void tick() {
48 49 50 51
        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);
52 53 54 55 56 57
                if (targetPos != null) {
                    this.entity.teleport(targetPos.x, targetPos.y, targetPos.z);
                }
            }
        } else {
            // Look at the player and start moving towards them
58 59 60 61
            if (this.targetEntity instanceof ServerPlayerEntity) {
                LookControls.lookAtPlayer((ServerPlayerEntity)this.targetEntity, this.entity);
            }
            this.navigation.startMovingTo(this.targetEntity, this.speed);
62 63 64 65
        }
    }

    private Vec3d findTeleportPosition(int distance) {
66 67 68 69
        if (this.entity instanceof PathAwareEntity) {
            return FuzzyTargeting.findTo((PathAwareEntity) this.entity, distance, distance, this.targetEntity.getPos());
        }
        return null;
70 71
    }
}