package com.lenis0012.bukkit.npc; import net.minecraft.server.v1_8_R3.*; import org.bukkit.Location; public class NPCPath { private final NPCEntity entity; private final PathEntity nmsPath; private final double speed; private double progress; private Vec3D currentPoint; protected NPCPath(NPCEntity entity, PathEntity nmsPath, double speed) { this.entity = entity; this.nmsPath = nmsPath; this.speed = speed; this.progress = 0.0; this.currentPoint = nmsPath.a(entity); } public boolean update() { int current = MathHelper.floor(progress); double d = progress - current; double d1 = 1 - d; if(d + speed < 1) { double dx = (currentPoint.a - entity.locX) * speed; double dz = (currentPoint.c - entity.locZ) * speed; entity.move(dx, 0, dz); entity.checkMovement(dx, 0, dz); progress += speed; } else { //First complete old point. double bx = (currentPoint.a - entity.locX) * d1; double bz = (currentPoint.c - entity.locZ) * d1; //Check if new point exists nmsPath.a(); if(!nmsPath.b()) { //Append new movement this.currentPoint = nmsPath.a(entity); double d2 = speed - d1; double dx = bx + ((currentPoint.a - entity.locX) * d2); double dy = currentPoint.b - entity.locY; //Jump if needed to reach next block. double dz = bz + ((currentPoint.c - entity.locZ) * d2); entity.move(dx, dy, dz); entity.checkMovement(dx, dy, dz); progress += speed; } else { //Complete final movement entity.move(bx, 0, bz); entity.checkMovement(bx, 0, bz); return false; } } return true; } public static NPCPath find(NPCEntity entity, Location to, double range, double speed) { if(speed > 1) { throw new IllegalArgumentException("Speed cannot be higher than 1!"); } try { BlockPosition posFrom = new BlockPosition(entity); BlockPosition posTo = new BlockPosition(to.getX(), to.getY(), to.getZ()); int k = (int) (range + 8.0); ChunkCache chunkCache = new ChunkCache(entity.world, posFrom.a(-k, -k, -k), posFrom.a(k, k, k), 0); PathEntity path = entity.getPathfinder().a(chunkCache, entity, posTo, (float) range); if(path != null) { return new NPCPath(entity, path, speed); } else { return null; } } catch(Exception e) { return null; } } }