Entity refuses to walk to location using NavigationAbstract

Discussion in 'Plugin Development' started by Assist, Mar 11, 2016.

Thread Status:
Not open for further replies.
  1. Hey there.

    I've created a custom Zombie, and am now attempting to give it new PathfinderGoals. One of these goals should make the zombie follow a specific path, however the zombie refuses to move at all, despite giving it a proper destination using NavigationAbstract:
    Code:
    @Override
    public void c() {
        FastLocation currentTarget = paths.element();
        FastLocation currentLocation = new FastLocation(entity.locX, entity.locY, entity.locZ);
    
        if (currentLocation.distance(currentTarget) <= 1) {
            currentTarget = paths.pop();
        }
    
        PathEntity pathEntity = this.entity.getNavigation().a(currentTarget.x, currentTarget.y, currentTarget.z);
        boolean bool = this.entity.getNavigation().a(pathEntity, speed);
    
        System.out.println(currentLocation.distance(currentTarget) + " " + bool);
    }
    I should mention that I'm in version 1.8(.8). The debug line here says:
    Code:
    19.5 false
    PathEntity here is null, and the navigation method returns false. I've heard that entities don't follow a path longer than 20 blocks, so I've tried making the zombie move only 1 tile forward, that doesn't work either. Default PathfinderGoals such as PathfinderGoalLookAtPlayer seem to work fine.

    I have not tested this in previous versions of Bukkit/Spigot, but I do recall navigation working fine in 1.7. Does anyone have any idea what might be wrong? Thanks in advance.
     
  2. Bump! I tested this in 1.7.10 but the issue still persists.

    Edit: While going through the source of Navigation and NavigationAbstract, I found something odd. Here is a snippet of code from NavigationAbstract class:
    Code:
    public PathEntity a(Entity paramEntity) {
        if (!b()) {
            return null;
        }
    
        float f1 = i();
        this.c.methodProfiler.a("pathfind");
        BlockPosition localBlockPosition = new BlockPosition(this.b).up();
        int k = (int)(f1 + 16.0 F);
    
        ChunkCache localChunkCache = new ChunkCache(this.c, localBlockPosition.a(-k, -k, -k), localBlockPosition.a(k, k, k), 0);
        PathEntity localPathEntity = this.j.a(localChunkCache, this.b, paramEntity, f1);
        this.c.methodProfiler.b();
        return localPathEntity;
    }
    
    My issue is that this method is returning null, which in this case would mean that the method "b" is returning false. This is an abstract method in NavigationAbstract, so here is a snippet from Navigation class:
    Code:
    protected boolean b() {
        return (this.b.onGround) || ((h()) && (o())) || ((this.b.au()) && ((this.b instanceof EntityZombie)) && ((this.b.vehicle instanceof EntityChicken)));
    }
    For some reason, this method requires the entity to be a Zombie jockey (zombie riding a chicken). So, I spawn a chicken in the world, and set my custom zombie as the passenger:
    Code:
    this.entity = entity;
    this.bukkitEntity = entity.getBukkitEntity();
    this.speed = speed;
    this.paths = Lists.newLinkedList();
    definePaths(lane);
    
    this.entity.setBaby(true);
    
    // Raw coordinates because bukkitEntity.getLocation() was not returning the correct location
    Chicken chicken = (Chicken) this.bukkitEntity.getWorld().spawnEntity(new Location(Bukkit.getWorld("world"), 0.5, 5, 7.5), EntityType.CHICKEN);
    chicken.setPassenger(this.bukkitEntity);
    Sure enough, my debug message is now printing "true", however the zombie is not moving anywhere because the movement is handled by the chicken. I may have to create a custom Chicken too for the time being, until this is fixed.

    I'm fairly sure that this is not intentional. Or perhaps I'm doing something wrong, using the wrong method? Thanks in advance.

    Late edit: nevermind about what I said above, it was late and I misread the code.
     
    Last edited: Mar 29, 2016
  3. I had exactly the same problem (found this thread while researching). PathEntity was null, so the return value was always false. After hours of research I fixed it by adding
    Code:
    this.entity.onGround = true; 
    at the beginning of c(). Maybe its a bug, or its because the entity is not spawned exactly onGround, but onGround was (in my case) always equal to false. So b() always return false, what made the PathEntity be null.
    Hope I could help,
    Tobi
     
    Assist likes this.
  4. @Tosel
    Now that you commented on this thread, I noticed that everything I said in my previous post is false (it was late and I misread the code).

    Anyways, I will definitely try that when I can, it looks promising. I should have debugged more but I was convinced that the issue was what I described above.

    Thanks! I'll update this post with the results later.
     
Thread Status:
Not open for further replies.

Share This Page