1.8 user controlled slime movement

Discussion in 'Spigot Plugin Development' started by Simo389, May 31, 2015.

  1. Hi, so I'm using the following custom class to customise the movement of a slime.
    Code (Text):
    public class CustomEntitySlime extends EntitySlime {
        public CustomEntitySlime(World world) {
            super(world);
        }

        @Override
        public void g(float sideMot, float forMot) {
            if (this.passenger == null || !(this.passenger instanceof EntityHuman)) {
                super.g(sideMot, forMot);
                this.S = 0.5F;    // Make sure the entity can walk over half slabs, instead of jumping
                return;
            }

            this.lastYaw = this.yaw = this.passenger.yaw;
            this.pitch = this.passenger.pitch * 0.5F;

            // Set the entity's pitch, yaw, head rotation etc.
            this.setYawPitch(this.yaw, this.pitch);
            this.aK = this.aI = this.yaw;

            this.S = 1F;    // The custom entity will now automatically climb up 1 high blocks

            sideMot = ((EntityLiving) this.passenger).aZ * 0.5F;
            forMot = ((EntityLiving) this.passenger).ba;

            if (forMot <= 0.0F) {
                forMot *= 0.25F;    // Make backwards slower
            }
            sideMot *= 0.75F;    // Also make sideways slower

            float speed = 0.35F;    // 0.2 is the default entity speed. I made it slightly faster so that riding is better than walking
            this.k(speed);    // Apply the speed
            super.g(sideMot, forMot);    // Apply the motion to the entity
            /*try {
                ReflectionUtilities.FieldAccess jumpField = ReflectionUtilities.getField(EntityLiving.class, "aY");
                if (jumpField != null && this.onGround) {    // Wouldn't want it jumping while in the air would we?
                    if (jumpField.get(Boolean.class, this.passenger)) {
                        double jumpHeight = 0.5D;
                        this.motY = jumpHeight;    // Used all the time in NMS for entity jumping
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }*/
        }
    }

    To enable this I'm using:
    Code (Text):
    @Override
    public void onEnable() {
        //Register custom entities
        CustomEntityType.registerEntities();
    }
    Code (Text):
    public enum CustomEntityType {
        SKELETON("Slime", 55, EntityType.SLIME, EntitySlime.class, CustomEntitySlime.class);
        private String name;
        private int id;
        private EntityType entityType;
        private Class<? extends EntityInsentient> nmsClass;
        private Class<? extends EntityInsentient> customClass;
        private CustomEntityType(String name, int id, EntityType entityType, Class<? extends EntityInsentient> nmsClass, Class<? extends EntityInsentient> customClass){
            this.name = name;
            this.id = id;
            this.entityType = entityType;
            this.nmsClass = nmsClass;
            this.customClass = customClass;
        }
        public String getName(){
            return this.name;
        }
        public int getID(){
            return this.id;
        }
        public EntityType getEntityType(){
            return this.entityType;
        }
        public Class<? extends EntityInsentient> getNMSClass(){
            return this.nmsClass;
        }

        public Class<? extends EntityInsentient> getCustomClass(){
            return this.customClass;
        }

        public static void registerEntities() {
            for (CustomEntityType entity : values()) {
                try{
                    Method a = EntityTypes.class.getDeclaredMethod("a", new Class<?>[]{Class.class, String.class, int.class});
                    a.setAccessible(true);
                    a.invoke(null, entity.getCustomClass(), entity.getName(), entity.getID());
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
       
            for (BiomeBase biomeBase : BiomeBase.getBiomes()) {
                if (biomeBase == null) {
                    break;
                }
         
                for (String field : new String[]{"K", "J", "L", "M"}) {
                    try{
                        Field list = BiomeBase.class.getDeclaredField(field);
                        list.setAccessible(true);
                        @SuppressWarnings("unchecked")
                        List<BiomeMeta> mobList = (List<BiomeMeta>) list.get(biomeBase);
                 
                        for (BiomeMeta meta : mobList){
                            for (CustomEntityType entity : values()){
                                if (entity.getNMSClass().equals(meta.b)){
                                    meta.b = entity.getCustomClass();
                                }
                            }
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    But this custom class doesn't seem to be registering at all. If I create a slime and mount a player on it using:
    Code (Text):
    Slime slime = player.getLocation().getWorld().spawn(loc, Slime.class);
    slime.setPassenger(player);

    None of this user-controlled behaviour works. Any ideas?
     
  2. I'm not sure, but did you tried to spawn your entity using NMS?

    Code (Text):
    World nmsWorld = ((CraftWorld)loc.getWorld()).getHandle();
            CustomEntitySlime slime = new CustomEntitySlime(nmsWorld);
            slime.setPosition(loc.getX(), loc.getY(), loc.getZ());
            nmsWorld.addEntity(slime);