Solved NMS Entity Despawn

Discussion in 'Spigot Plugin Development' started by LazerShadow, Nov 12, 2015.

  1. Hello,

    I'm have never used anything related to NMS, so forgive me of my lack of knowledge. I have created an entity, although it despawns whenever I leave the server. I need it to not do this. This is my class:

    Code (Text):
    public class CustomVillager extends EntityVillager
    {
        public CustomVillager(CraftWorld world)
        {
            super((world).getHandle());

            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 ex)
            {
                ErrorUtil.EM(ex, ErrorUtil.Errors.ENTITY, "CustomVillager");
            }
        }

        @Override
        public void move(double d0, double d1, double d2)
        {

        }

        @Override
        public void collide(Entity entity)
        {

        }

        @Override
        public boolean damageEntity(DamageSource damagesource, float f)
        {
            return false;
        }

        @Override
        public void g(double d0, double d1, double d2)
        {

        }
    }
     
  2. Have you named the entity? A custom entity is taken as a normal entity in general so it needa a modifier that prevents it fromd espawning like a name ;)
     
  3. You don't need to name it actually... set the field "persistent" of the NMS Entity.class to true. This will prevent the entity from despawning when there are no players near it and I think it might be the cause of your problem.
    Code (Text):
    public CustomVillager(CraftWorld world)
        {
            super((world).getHandle());
            this.persistent = true;
            // your code ...
        }

     
     
  4. Tried this, and naming the Villager and he still despawns when I unload the chunk or reconnect.
     
  5. @LazerShadow check your console. You need to register your entity in the EntityTypes class for an entity to despawn and respawn.
     
  6. I don't believe I am registering my entities correctly. I am calling the spawnEntity method but that's it.


    Code (Java):
    public enum EntityTypes
    {
        VILLAGER("Villager", 120, CustomVillager.class),
        ARMOR_STAND("Armor Stand", 416, CustomArmorStand.class);

        EntityTypes(String name, int id, Class<? extends Entity> custom)
        {
            addToMaps(custom, name, id);
        }

        public static void spawnEntity(Entity entity, Location loc, String name)
        {
            entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
            entity.setCustomName(name);
            entity.setCustomNameVisible(true);
            //((CraftLivingEntity) entity.getBukkitEntity()).set maybe metadata
            ((CraftWorld)loc.getWorld()).getHandle().addEntity(entity);
        }

        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 ex)
            {
                ErrorUtil.EM(ex, ErrorUtil.Errors.ENTITY, "EntityTypes");
            }
            catch(IllegalAccessException ex)
            {
                ErrorUtil.EM(ex, ErrorUtil.Errors.ENTITY, "EntityTypes");
            }

            return o;
        }

        public static void addToMaps(Class clazz, String name, int id)
        {
            ((Map)getPrivateField("c", net.minecraft.server.v1_8_R3.EntityTypes.class, null)).put(name, clazz);
            ((Map)getPrivateField("d", net.minecraft.server.v1_8_R3.EntityTypes.class, null)).put(clazz, name);
            ((Map)getPrivateField("f", net.minecraft.server.v1_8_R3.EntityTypes.class, null)).put(clazz, Integer.valueOf(id));
        }


    }
     
  7. The ArmorStand id is 30 actually.
     
  8. Thanks, I'm not sure what I did but it worked!
     
  9. I'm glad you solved it.
     
    • Friendly Friendly x 1