Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем BeYkeR, 29 окт 2014.

Статус темы:
Закрыта.
  1. Автор темы
    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).
     
  2. Хостинг MineCraft
    <
  3. Hilgert

    Hilgert Старожил Пользователь

    Баллы:
    123
    Skype:
    mixa2258
    Имя в Minecraft:
    Hilgert
    Фу, некоментированный код! Не читабельно!!
    Какую скорость ты указываешь?
     
  4. Автор темы
    BeYkeR

    BeYkeR Старожил Девелопер Пользователь

    Баллы:
    173
    Скорость игрока - 0.2F
     
  5. Hilgert

    Hilgert Старожил Пользователь

    Баллы:
    123
    Skype:
    mixa2258
    Имя в Minecraft:
    Hilgert
    а меньше пробовал? 0.02 например
    Может там вообще не float а double?
     
  6. Автор темы
    BeYkeR

    BeYkeR Старожил Девелопер Пользователь

    Баллы:
    173
    По исходникам там float. При 0.02, передвижение на ближних дистанциях очень низкое, а на дальних всё так же.[DOUBLEPOST=1414675074,1414633629][/DOUBLEPOST][Тема закрыта]
    Решение: Снес эту чертову библиотеку и начал использовать ванильный. Результат положительный.
     
Статус темы:
Закрыта.

Поделиться этой страницей