Войти или зарегистрироваться

Помогите [Решено] Передвижение NPC (extends EntityPlayer)

  • Автор темы Автор темы BeYkeR
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

BeYkeR

Старожил
Девелопер
Пользователь
Баллы
173
У меня есть NPC (EntityPlayer), у них есть маленький AI, у них есть все хелперы для передвижения (Jump, Look, Move). Для навигации использовал данную библиотеку, но случилось так, что боты не могут нормально передвигаться ,то есть "не умеют" с заданной скоростью перемещаться по локации, вместо этого они как флеши перемещаются молниеносно (Или как наркоманы) и вызывают жесткий краш. Вот код моего MoveHelper'a :
Код:
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;
    }
}
Если нужно: Метод update() вызывается почти каждый тик (Он вызывается в методе h() в классе EntityPlayerNPC).
 
Фу, некоментированный код! Не читабельно!!
Какую скорость ты указываешь?
 
а меньше пробовал? 0.02 например
Может там вообще не float а double?
По исходникам там float. При 0.02, передвижение на ближних дистанциях очень низкое, а на дальних всё так же.
[Тема закрыта]
Решение: Снес эту чертову библиотеку и начал использовать ванильный. Результат положительный.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх