NMS Custom Entities HELP :(

Discussion in 'Spigot Plugin Development' started by GamingMeatheadHD, May 13, 2015.

  1. Hi there! As the title suggests, I'm trying to make custom entities using NMS. I've looked up every tutorial I can. The custom entity correctly spawns and has no behavior, as desired. However, whenever I try to set it's pathfinder so it'll move, it does absolutely nothing. It won't walk to that location.

    Here's my custom entity:

    Code (Text):
    @SuppressWarnings( "rawtypes" )
        public CustomZombie(org.bukkit.World world){
            super(((CraftWorld)world).getHandle());
         
            List goalB = (List)nmsUtils.getPrivateField("b", PathfinderGoalSelector.class, goalSelector); goalB.clear();
            List goalC = (List)nmsUtils.getPrivateField("c", PathfinderGoalSelector.class, goalSelector); goalC.clear();
            List targetB = (List)nmsUtils.getPrivateField("b", PathfinderGoalSelector.class, goalSelector); targetB.clear();
            List targetC = (List)nmsUtils.getPrivateField("c", PathfinderGoalSelector.class, goalSelector); targetC.clear();
         
             
        }
     
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public void walk(Location l, double speed){
            /*try{
                Field gsa = PathfinderGoalSelector.class.getDeclaredField("a");
                gsa.setAccessible(true);
               
               
                gsa.set(this.goalSelector, new UnsafeList());
                gsa.set(this.targetSelector, new UnsafeList());
            } catch (SecurityException e) {
            e.printStackTrace();
            } catch (NoSuchFieldException e) {
            e.printStackTrace();
            } catch (IllegalArgumentException e) {
            e.printStackTrace();
            } catch (IllegalAccessException e) {
            e.printStackTrace();
            }
    */
         
            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(1, new PathfinderGoalBreakDoor(this));
            this.goalSelector.a(1, new PathfinderGoalWalkToLoc(this, l, (float) speed));
            //this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, this.bI, false));
            //this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, EntityVillager.class, this.bI, true));
            //this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bI));
            //this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bI, false));
            //this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bI));
            this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
            this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
            this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, false));
        }
    Here's the my custom Pathfinder goal class:

    Code (Text):
    public class PathfinderGoalWalkToLoc extends PathfinderGoal{
       
        private double speed;
       
        private EntityInsentient entity;
       
        private Location loc;
       
        private Navigation navigation;
       
        public PathfinderGoalWalkToLoc(EntityInsentient e, Location l, double speed){
            entity = e;
            loc = l;
            this.speed = speed;
            this.navigation = (Navigation) this.entity.getNavigation();
            this.speed = speed;
        }
       
        public void c(){
            PathEntity pathEntity = this.navigation.a(loc.getX(), loc.getY(), loc.getZ());
            navigation.a(pathEntity, speed);
        }
       
        public boolean a(){
            return true; //should start? add a range check here
        }
       
       

    }
    And here's my nmsUtils class, where the reflection takes place:
    Code (Text):
    @SuppressWarnings("rawtypes")
        public static Object getPrivateField(String fieldName, Class clazz, Object object){
            Field field;
            Object o = null;
           
            try{
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                o = field.get(object);
            }catch(NoSuchFieldException e){
                e.printStackTrace();
            }catch(IllegalAccessException e){
                e.printStackTrace();
            }
            return o;
        }
    And lastly, here's my EntityTypes enum thingy:
    Code (Text):
    public enum EntityTypes {
       
        //NAME("Entity name", Entity ID, yourcustomclass.class);
        CUSTOM_ZOMBIE("Zombie", 54, CustomZombie.class);
       
        private EntityTypes(String name, int id, Class<? extends Entity> custom){
            addToMaps(custom, name, id);
        }
       
        public static void spawnEntity(Entity entity, Location loc){
            entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
            ((CraftWorld)loc.getWorld()).getHandle().addEntity(entity);
        }
       
        @SuppressWarnings({ "unchecked", "rawtypes" })
        private static void addToMaps(Class clazz, String name, int id){
            ((Map)nmsUtils.getPrivateField("d", net.minecraft.server.v1_8_R2.EntityTypes.class, null)).put(clazz, name);
            ((Map)nmsUtils.getPrivateField("f", net.minecraft.server.v1_8_R2.EntityTypes.class, null)).put(clazz, Integer.valueOf(id));
        }

    }
    Any help is greatly appreciated!