Tutorial 1.8.8 Entity WASD Control

Discussion in 'Resources' started by lewysryan, Dec 19, 2015.

?

Useful or nar?

  1. OMG THX!

    6 vote(s)
    75.0%
  2. oh nar.

    0 vote(s)
    0.0%
  3. smelly

    2 vote(s)
    25.0%
Thread Status:
Not open for further replies.
  1. Offline

    lewysryan

    1.8.8 WASD Entity Control

    I don't know if there is a tread about this but i'm sorry if there is. I've been working for the past hour / 2 hours getting this bloody entity control down and finally I got it. Ima just leave it here for anyone that wants to be lazy (like I wanted).

    This is a pig. Pigs are cool. This can be done with any entity that extends EntityInsentient.

    Code:
    import java.lang.reflect.Field;
    
    import net.minecraft.server.v1_8_R3.EntityHuman;
    import net.minecraft.server.v1_8_R3.EntityInsentient;
    import net.minecraft.server.v1_8_R3.EntityLiving;
    import net.minecraft.server.v1_8_R3.EntityPig;
    import net.minecraft.server.v1_8_R3.GenericAttributes;
    import net.minecraft.server.v1_8_R3.MathHelper;
    import net.minecraft.server.v1_8_R3.World;
    
    import org.bukkit.Location;
    import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
    import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
    import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPig;
    import org.bukkit.entity.Pig;
    import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
    
    public class RidablePig extends EntityPig{
    
        protected Field FIELD_JUMP = null;
    
        public RidablePig(World world) {
            super(world);
       
            if (FIELD_JUMP == null) {
                try {
                   FIELD_JUMP = EntityLiving.class.getDeclaredField("aY");
                   FIELD_JUMP.setAccessible(true);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        public void g(float f, float f1) {
            if(this.passenger != null && this.passenger instanceof EntityHuman)
            {
                this.lastYaw = this.yaw = this.passenger.yaw;
                this.pitch = this.passenger.pitch * 0.5F;
                this.setYawPitch(this.yaw, this.pitch);
                this.aK = this.aI = this.yaw;
                f = ((EntityLiving)this.passenger).aZ * 0.5F;
                f1 = ((EntityLiving)this.passenger).ba;
    
                if(f1 <= 0.0F)
                {
                    f1 *= 0.25F;
                }
                  try {
                    if (FIELD_JUMP.getBoolean(this.passenger) && this.onGround) {
                        this.motY += 1F;
                        this.ai = true;
                        if (f1 > 0.0F)
                        {
                            float f2 = MathHelper.sin(this.yaw * 3.141593F / 180.0F);
                            float f3 = MathHelper.cos(this.yaw * 3.141593F / 180.0F);
    
                            this.motX += -0.4F * f2 * ((EntityInsentient) this).br();
                            this.motZ += 0.4F * f3 * ((EntityInsentient) this).br();
                        }
                    }
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
    
                this.S = 1.0F; this.aM = this.bI() * 0.1F; if(!this.world.isClientSide)
                {
                    this.k((float)this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
                    super.g(f, f1);
                }
    
                this.aA = this.aB; double d0 = this.locX - this.lastX; double d1 = this.locZ - this.lastZ; float f4 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F;
                if(f4 > 1.0F)
                {
                    f4 = 1.0F;
                }
    
                this.aB += (f4 - this.aB) * 0.4F; this.aC += this.aB;
            } else {
                this.S = 0.5F; this.aM = 0.02F; super.g(f, f1);
            }
        }
    
        public static Pig spawn(Location location)
        {
            World mcWorld = (World) ((CraftWorld) location.getWorld()).getHandle();
    
            RidablePig customEntity = new RidablePig(mcWorld);
            customEntity.setLocation(location.getX(), location.getY(),location.getZ(), location.getYaw(), location.getPitch());
    
            ((CraftLivingEntity) customEntity.getBukkitEntity()).setRemoveWhenFarAway(false);
    
            mcWorld.addEntity(customEntity, SpawnReason.CUSTOM);
    
            customEntity.setCustomName("");
            customEntity.setCustomNameVisible(false);
    
            return (CraftPig) customEntity.getBukkitEntity();
        }
    
    MAKE SURE YOU REGISTER THE ENTITY

    NMS Util (Not mine) :
    Code:
    /**
    * author @BigTeddy98
    * Used for tutorial purposes
    * https://forums.bukkit.org/threads/tutorial-register-your-custom-entities-nms-reflection.258542/
    */
    
    public class NMSUtils {
    
        public static void registerEntity(String name, int id, Class<? extends EntityInsentient> nmsClass, Class<? extends EntityInsentient> customClass) {
            try {
                /*
                * First, we make a list of all HashMap's in the EntityTypes class
                * by looping through all fields. I am using reflection here so we
                * have no problems later when minecraft changes the field's name.
                * By creating a list of these maps we can easily modify them later
                * on.
                */
                List<Map<?, ?>> dataMaps = new ArrayList<Map<?, ?>>();
                for (Field f : EntityTypes.class.getDeclaredFields()) {
                    if (f.getType().getSimpleName().equals(Map.class.getSimpleName())) {
                        f.setAccessible(true);
                        dataMaps.add((Map<?, ?>) f.get(null));
                    }
                }
                /*
                * since minecraft checks if an id has already been registered, we
                * have to remove the old entity class before we can register our
                * custom one
                *
                * map 0 is the map with names and map 2 is the map with ids
                */
                if (dataMaps.get(2).containsKey(id)) {
                    dataMaps.get(0).remove(name);
                    dataMaps.get(2).remove(id);
                }
                /*
                * now we call the method which adds the entity to the lists in the
                * EntityTypes class, now we are actually 'registering' our entity
                */
                Method method = EntityTypes.class.getDeclaredMethod("a", Class.class, String.class, int.class);
                method.setAccessible(true);
                method.invoke(null, customClass, name, id);
                /*
                * after doing the basic registering stuff , we have to register our
                * mob as to be the default for every biome. This can be done by
                * looping through all BiomeBase fields in the BiomeBase class, so
                * we can loop though all available biomes afterwards. Here, again,
                * I am using reflection so we have no problems later when minecraft
                * changes the fields name
                */
                for (Field f : BiomeBase.class.getDeclaredFields()) {
                    if (f.getType().getSimpleName().equals(BiomeBase.class.getSimpleName())) {
                        if (f.get(null) != null) {
                            /*
                            * this peace of code is being called for every biome,
                            * we are going to loop through all fields in the
                            * BiomeBase class so we can detect which of them are
                            * Lists (again, to prevent problems when the field's
                            * name changes), by doing this we can easily get the 4
                            * required lists without using the name (which probably
                            * changes every version)
                            */
                            for (Field list : BiomeBase.class.getDeclaredFields()) {
                                if (list.getType().getSimpleName().equals(List.class.getSimpleName())) {
                                    list.setAccessible(true);
                                    @SuppressWarnings("unchecked")
                                    List<BiomeMeta> metaList = (List<BiomeMeta>) list.get(f.get(null));
                                    /*
                                    * now we are almost done. This peace of code
                                    * we're in now is called for every biome. Loop
                                    * though the list with BiomeMeta, if the
                                    * BiomeMeta's entity is the one you want to
                                    * change (for example if EntitySkeleton matches
                                    * EntitySkeleton) we will change it to our
                                    * custom entity class
                                    */
                                    for (BiomeMeta meta : metaList) {
                                        Field clazz = BiomeMeta.class.getDeclaredFields()[0];
                                        if (clazz.get(meta).equals(nmsClass)) {
                                            clazz.set(meta, customClass);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    HOW TO REGISTER:
    Code:
    NMSUtils.registerEntity(name, id, nmsClass, customClass);
    EXAMPLE:
    Code:
    NMSUtils.registerEntity("Pig", 90, EntityPig.class, RidablePig.class);
    SPAWNING:
    Code:
    Pig pig = RidablePig.spawn(player.getLocation());
    pig.setPassenger(p);
    
    FIND IDS HERE:
    http://pastebin.com/FzJMBa6J

    Credits to things that helped me do it:
    For people that require more spoon-feeding:
    Show Spoiler
    [​IMG]
     
    Last edited: Dec 19, 2015
    bramhaag and Orange Tabby like this.
  2. Offline

    Mrs. bwfctower

  3. Offline

    lewysryan

  4. Offline

    Mrs. bwfctower

    Just put something about it in the OP maybe.
     
  5. Offline

    teej107

    @Mrs. bwfctower He stated 1.8.8. Seeing as I've seen threads for this for other version as well (I don't know if the methods are the same but I'll assume they changed since there is a new thread for the different version), I wouldn't worry about it.
     
    Mrs. bwfctower likes this.
  6. Offline

    lewysryan

    @Mrs. bwfctower @teej107 This was made because I couldn't find a 1.8.8 version as the NMS changes each time (pain in the ass). So I looked into the new horse, looked at old posts, combined, tried, tried, tried, self harmed and finally got it to work for 1.8.8. This is not a library or util its simply showing how to do WASD control.

    This thread is not for those that don't know basic NMS.

    @Mrs. bwfctower
    If you want to make a library for all versions be my guest, but I can update the code for my server when I need to. (YAY 1.9 SOON :D). I'm sure many people will find this EXTREMELY useful. So instead of telling me what to do, leave my thread alone and say something nice for once and stop hating.
     
  7. Offline

    kelbiiz

    Great!!! very helpful.. Thank for sharing...
     
  8. Offline

    Gorbit99

    I wouldn't really call this a "tutorial", because you're not teaching anything, you're just giving people the code they need.
     
Thread Status:
Not open for further replies.

Share This Page