Solved NMS Pathfinder Help

Discussion in 'Plugin Development' started by ark9026, Dec 31, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    ark9026

    Hello,

    I need help with Pathfinders using NMS. I have tried following tutorials, but they are either outdated, or simply don't go enough in depth. I am able to spawn my custom mob, which is a Villager, but I am unable to get it to go to a specific location. The following classes are my(failed) attempts at making a Pathfinder:

    PathfinderGoalWalkToLoc.java:
    Code:
    package com.emperiouscraft.archerypvppractice;
    
    import org.bukkit.Location;
    
    import net.minecraft.server.v1_8_R3.EntityInsentient;
    import net.minecraft.server.v1_8_R3.Navigation;
    import net.minecraft.server.v1_8_R3.PathEntity;
    import net.minecraft.server.v1_8_R3.PathfinderGoal;
    
    public class PathfinderGoalWalkToLoc extends PathfinderGoal {
    
        private EntityInsentient entity;
        private Navigation navigation;
        private double speed;
    
        public PathfinderGoalWalkToLoc(EntityInsentient entity, Location loc,
                double speed) {
            this.entity = entity;
            this.navigation = (Navigation) this.entity.getNavigation();
            this.speed = speed;
        }
    
        public boolean a() {
            return true;
        }
    
        public void c() {
            PathEntity pathEntity = this.navigation.a(-4, 7, 14);
            this.navigation.a(pathEntity, speed);
        }
    }
    CustomEntityVillager.java:
    Code:
    package com.emperiouscraft.archerypvppractice;
    
    import java.lang.reflect.Field;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.craftbukkit.v1_8_R3.util.UnsafeList;
    
    import net.minecraft.server.v1_8_R3.EntityVillager;
    import net.minecraft.server.v1_8_R3.PathfinderGoalSelector;
    import net.minecraft.server.v1_8_R3.World;
    
    public class CustomEntityVillager extends EntityVillager {
    
        public CustomEntityVillager(World world) {
            super(world);
    
            try {
                Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
                bField.setAccessible(true);
                Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
                cField.setAccessible(true);
                bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
                bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
                cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
                cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
            } catch (Exception exc) {
                exc.printStackTrace();
            }
            Location l = new Location(Bukkit.getWorld("world"), -4, 7, 14);
            this.goalSelector.a(1, new PathfinderGoalWalkToLoc(this, l, (float) 1));
        }
    }
    Second question solved. Spoiler opens second question. (open)
    Now, on to the next issue. I'm trying to get my Custom NMS Villager to hold a bow. You might think it's easy, but with NMS, there is simply no way that I have found to make a villager hold a bow. With non-NMS mobs, there is a convenient method, but not for custom mobs. I have successfully spawned a bow below the Custom Villager, but when I tried using the "customVillager.canPickUpLoot(true);" message it didn't allow my Custom Villager to pick up the bow. Does anyone know an easy and effective way to do this?


    Thanks everyone!
    ark9026
     
    Last edited: Dec 31, 2015
  2. Offline

    Zombie_Striker

    @ark9026
    Well, since Villagers do not have the ability to store itemstacks anywhere (no armour/ items in hand), I don't think there is any way around this besides also spawning an armour stand that holds the item at the villagers location.
     
    ark9026 likes this.
  3. Offline

    ark9026

    Could I have an example of this please? I'm not asking for code, no spoonfeeding please, but just an example :p
     
  4. Offline

    Zombie_Striker

    @ark9026
    • ArmourStand as = World.spawnEntity(ArmourStand);
    • as.setHands(true); //not sure of the actual method.
    • as.getEquipment().setHand(the item)
    • Using EularAngles, orientate the hands.
    • //Inside runnable
    • as.teleport(villager);
     
  5. Offline

    ark9026

    Thanks! Would the armor stand be invisible? Also, the EntityType enum doesn't contain ArmorStands, where could I access it from?
     
  6. Offline

    Zombie_Striker

    @ark9026
    All you have to do is apply the Invisibility potion effect to make the armour stand invisible. the entity will be invisible, but the item will be visible.
     
  7. Offline

    ark9026

    Thanks again :) How could I access the ArmorStand to spawn it though? It isn't contained in the EntityType enum, not sure why.
     
  8. Offline

    Xerox262

    @ark9026 What version are you building with? You need to use atleast 1.8.
     
  9. Offline

    ark9026

    I'm building against Spigot 1.8.8, but I do have 1.7 Bukkit in my build path. I'll remove it to see if it'll work.

    Removed it, and it works :) Can anyone help me with my first question about the pathfinders?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
  10. Offline

    mcdorli

    That's incorrect. http://minecraft.gamepedia.com/Villager#Picking_up_items
     
    Zombie_Striker likes this.
  11. Offline

    Xerox262

  12. Offline

    mcdorli

    Yeah, but this is nms. It doesn't care about that. Can you put a hoe on your head in survival? No. Can you do it with nms? Yes you can.
     
  13. Offline

    ark9026

    I turned canPickUpItems to true, and dropped a bow in front of my NMS Villager. It didn't pick it up, maybe the method is broken?
     
  14. Offline

    mcdorli

    Try to throw a bread in front of it. It can only pickup that. You'd need to check for items around the villager, and put them in it's inventory, if you want it to pickup a bow too.
     
  15. Offline

    Zombie_Striker

    @ark9026

    Found this under EntityInsentient
    Code:
    
      public ItemStack be() {
      return this.equipment[0];
      }
    This is what the villager holds in his hand.

    So use :
    Code:
    CustomVillager.setEquipment(0, itemstack);;
    to set the item.
     
  16. Offline

    ark9026

    So, seeing that .setEquipment doesn't extend the "new ItemStack(Material.<material>);" we're all used to, I had to do it NMS style. I tried:
    Code:
    net.minecraft.server.v1_8_R3.ItemStack bow = new net.minecraft.server.v1_8_R3.ItemStack(Item.getById(261));
                    customVillager.setEquipment(0, bow);
    , but the villager didn't hold a bow. However, when I killed the villager, it did indeed drop a bow. I guess for now I'm okay with the armor stand code, however if you could find something that allows a villager to hold a bow then that would be great.

    On to the next question: Can any of you please help with the pathfinder?
     
  17. Offline

    mcdorli

    He holds it, the game just doesn't render it.
    What you need to know about pathfinders?
     
  18. Offline

    ark9026

    I need to know how to get a villager to go to a location, wait 3 seconds, and then go back. How could I do that?
     
  19. Offline

    mcdorli

    PathfinderGoalMoveTowardsTarget, then check if he succeded in his job, and if he is, then move the target to the second location after 3 second with a scheduler
     
  20. Offline

    ark9026

    What are the arguments for this? There is none for location.
     
  21. Offline

    mcdorli

    EntityCreature has a location
     
  22. Offline

    ark9026

    So in this spot? What would I fill in the arguments with though?
    Code:
    package com.emperiouscraft.archerypvppractice;
    
    import java.lang.reflect.Field;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.craftbukkit.v1_8_R3.util.UnsafeList;
    
    import net.minecraft.server.v1_8_R3.EntityVillager;
    import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsTarget;
    import net.minecraft.server.v1_8_R3.PathfinderGoalSelector;
    import net.minecraft.server.v1_8_R3.World;
    
    public class CustomEntityVillager extends EntityVillager {
    
        public CustomEntityVillager(World world) {
            super(world);
    
            try {
                Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
                bField.setAccessible(true);
                Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
                cField.setAccessible(true);
                bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
                bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
                cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
                cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
            } catch (Exception exc) {
                exc.printStackTrace();
            }
            this.goalSelector.a(1, new PathfinderGoalMoveTowardsTarget(EntityCreature, double , float));
        }
    }
     
  23. Offline

    mcdorli

    Creat an entityCreature on the location you want it to go, the second and third arguments are I think speed and follow range
    try putting something like 0.9d, 128f
     
  24. Offline

    ark9026

    How would I get it to go back?
     
  25. Offline

    mcdorli

    Save the entitycreature somewhere, and teleport it to the correct location.
     
    ark9026 likes this.
  26. Offline

    ark9026

    Thanks! Solved :)
     
Thread Status:
Not open for further replies.

Share This Page