- Баллы
- 173
У меня есть NPC (EntityPlayer), у них есть маленький AI, у них есть все хелперы для передвижения (Jump, Look, Move). Для навигации использовал данную библиотеку, но случилось так, что боты не могут нормально передвигаться ,то есть "не умеют" с заданной скоростью перемещаться по локации, вместо этого они как флеши перемещаются молниеносно (Или как наркоманы) и вызывают жесткий краш. Вот код моего MoveHelper'a :
Если нужно: Метод update() вызывается почти каждый тик (Он вызывается в методе h() в классе EntityPlayerNPC).
Код:
package ykt.BeYkeRYkt.PlayerAI.AI.utils;
import java.util.ArrayList;
import org.bukkit.Location;
import org.bukkit.Material;
import net.minecraft.server.v1_7_R4.MathHelper;
import ykt.BeYkeRYkt.PlayerAI.AI.pathing.AStar;
import ykt.BeYkeRYkt.PlayerAI.AI.pathing.AStar.InvalidPathException;
import ykt.BeYkeRYkt.PlayerAI.AI.pathing.PathingResult;
import ykt.BeYkeRYkt.PlayerAI.AI.pathing.Tile;
import ykt.BeYkeRYkt.PlayerAI.nms.EntityPlayerNPC;
//From mc-dev
public class NPCMoveHelper {
private final EntityPlayerNPC entity;
private double x;
private double y;
private double z;
private float speed;
private boolean needUpdate;
private AStar path;
private Location end;
private ArrayList<Tile> walkNodes = new ArrayList<Tile>();
public NPCMoveHelper(EntityPlayerNPC entityinsentient) {
this.entity = entityinsentient;
this.x = entityinsentient.locX;
this.y = entityinsentient.locY;
this.z = entityinsentient.locZ;
}
public boolean needUpdate() {
return this.needUpdate;
}
public void move(Location location, float speed) {
this.x = location.getX();
this.y = location.getY();
this.z = location.getZ();
this.speed = speed;
Location start = entity.getBukkitEntity().getLocation();
if (!this.isPathFindComplete()) {
return;
}
while (start.getBlock().getType() == Material.AIR) {
start.subtract(0, 1, 0);
}
while (location.getBlock().getType() == Material.AIR) {
location.subtract(0, 1, 0);
}
try {
path = new AStar(start, location, 500);
walkNodes = path.iterate();
result = path.getPathingResult();
needUpdate = true;
} catch (InvalidPathException e) {
if(e.isEndNotSolid()){
System.out.println("End block is not walkable");
}
if(e.isStartNotSolid()){
System.out.println("Start block is not walkable");
}
}
if(result != PathingResult.SUCCESS || walkNodes == null){
return;
}
this.end = location;
}
private PathingResult result;
public PathingResult getPathingResult() {
return this.result;
}
public double getSpeed() {
return this.speed;
}
public synchronized void update(){
this.entity.be = 0;
if (needUpdate) {
Location start = entity.getBukkitEntity().getLocation();
if (walkNodes == null) {
this.stopPathFind();
} else if (start == null) {
this.stopPathFind();
} else {
if (walkNodes != null && walkNodes.size() > 0) {
Tile t = walkNodes.get(0);
walkNodes.remove(0);
fixBody();
entity.motX = (t.getX(start) - entity.locX) * speed;
//entity.motY = (t.getY(start) - entity.locY) * speed;
entity.motZ = (t.getZ(start) - entity.locZ) * speed;
if((t.getY(start) - entity.locY) > 0.9D){
entity.getNPC().getJumpHelper().jump();
}
entity.e(0.0F, speed);
}else{
this.stopPathFind();
}
}
}
}
public void fixBody(){
//From mc-dev
int i = MathHelper.floor(this.entity.boundingBox.b + 0.5D);
double d0 = x - this.entity.locX;
double d1 = z - this.entity.locZ;
double d2 = y - i;
double d3 = d0 * d0 + d2 * d2 + d1 * d1;
if (d3 >= 2.500000277905201E-7D) {
float f = (float) (Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
this.entity.yaw = this.limitAngle(this.entity.yaw, f, 30.0F); // fix body
}
}
public boolean isPathFindComplete() {
if (this.walkNodes == null || end == null) {
return true;
}
return (this.walkNodes.size() == 0);
}
public void stopPathFind() {
end = null;
walkNodes = null;
needUpdate = false;
}
private float limitAngle(float f, float f1, float f2) {
float f3 = MathHelper.g(f1 - f);
if (f3 > f2) {
f3 = f2;
}
if (f3 < -f2) {
f3 = -f2;
}
return f + f3;
}
}