NMS How to override default Minecraft mobs

Discussion in 'Resources' started by TeeePeee, Jan 6, 2014.

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

    GreySwordz

    Thanks. I also realized you need to copy/paste the n() method from EntityMonster for it to apply damage.

    TeeePeee one problem left :p

    I'm trying to get the custom amount damage/health of my custom mob in its constructor, then set it in my aC():
    Code:
        @Override
        protected void aC() {
            super.aC();
            this.getAttributeInstance(GenericAttributes.a).setValue(20);
            this.getAttributeInstance(GenericAttributes.b).setValue(TARGET_RANGE);
            this.getAttributeInstance(GenericAttributes.d).setValue(chicken_speed);
            this.bb().b(GenericAttributes.e);
            this.getAttributeInstance(GenericAttributes.e).setValue(chicken_attack);
        }
    When I print the values from a debug method however, they all come up as 0. Do you have any clue what I may be doing wrong?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jan 25, 2016
  2. Offline

    ToastHelmi

    could you go more in detail in how to obtain the nms world to add the entity
     
  3. Offline

    TeeePeee

    ToastHelmi
    An NMS world can be obtained as simply as:
    Code:java
    1. net.minecraft.server.xxx.World world = ((CraftWorld)someWorld).getHandle();

    GreySwordz
    Your aC() method will run at the call to super(world). Your variables need to be either static or already initialized in another class as assigning them in the constructor won't have any effect.
     
  4. Offline

    GreySwordz

    TeeePeee Thanks for the help, I ended up getting my variables in my aC() instead of trying to initialize them elsewhere
     
  5. Offline

    ToastHelmi

    does anybodys clien crash after reloading the server too
     
  6. Offline

    TwoPointDuck

    Anyone on this thread figure out yet how to give them armor pieces?

    Having issues creating the dang ItemStack....
     
  7. Offline

    TeeePeee

    ToastHelmi
    If there are still custom entities in the world after reloads/restarts in some instances, it crashes. If you despawn all of your custom mobs before disabling your plugin, it should work. And remember to #unregisterEntities();

    TwoPointDuck
    Just use yourCustomMob#getBukkitEntity().getEquipment()... To give it equipment like you would a normal mob.
     
    TwoPointDuck likes this.
  8. Offline

    TwoPointDuck

    TeeePeee

    You always know the answer :) Thx again man.
     
  9. Offline

    ToastHelmi

    TeeePeee
    Strange i have following classes which should act same but the Pigzombie class acts like the default mob
    Code:java
    1. public class Swat extends EntityPigZombie{
    2.  
    3. public static org.bukkit.inventory.ItemStack[] equip = Settings.getSwatEquip();
    4.  
    5. public Swat(World world){
    6. super(world);
    7. try {
    8. Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
    9. bField.setAccessible(true);
    10. Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
    11. cField.setAccessible(true);
    12. bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
    13. bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
    14. cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
    15. cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
    16.  
    17. this.setCustomName("SWAT");
    18.  
    19. } catch (Exception exc) {
    20. exc.printStackTrace();
    21. // This means that the name of one of the fields changed names or
    22. // declaration and will have to be re-examined.
    23. }
    24. this.goalSelector.a(0, new PathfinderGoalFloat(this));
    25. this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this));
    26. this.goalSelector.a(3, new PathfinderGoalMoveIndoors(this));
    27. this.goalSelector.a(5,new PathfinderGoalOpenDoor(this, true));
    28. this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this,EntityHuman.class, 8.0F));
    29. this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D));
    30.  
    31. this.goalSelector.a(7, new PathfinderGoalMeleeAttack(this,EntityHuman.class, 1.0D, false));
    32. this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
    33. this.targetSelector.a(2, new PathfinderGoalNearestAttackableGangster(this, EntityHuman.class, 0, true,1));
    34.  
    35. EntityEquipment e = ((PigZombie)this.getBukkitEntity()).getEquipment();
    36. e.setHelmet(equip[0]);
    37. e.setChestplate(equip[1]);
    38. e.setLeggings(equip[2]);
    39. e.setBoots(equip[3]);
    40. e.setItemInHand(equip[4]);
    41.  
    42. }
    43.  
    44.  
    45. @Override
    46. protected void aD() {
    47. super.aD();
    48. this.getAttributeInstance(GenericAttributes.e).setValue(6.0D);
    49. this.getAttributeInstance(GenericAttributes.a).setValue(50.0D);
    50. }
    51. }

    and
    Code:java
    1. public class PoliceOfficer extends EntityZombie{
    2.  
    3. public static org.bukkit.inventory.ItemStack[] equip = Settings.getOfficerEquip();
    4.  
    5. public PoliceOfficer(World world) {
    6. super(world);
    7. try {
    8. Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
    9. bField.setAccessible(true);
    10. Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
    11. cField.setAccessible(true);
    12. bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
    13. bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
    14. cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
    15. cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
    16.  
    17. this.setCustomName("Police Officer");
    18.  
    19. } catch (Exception exc) {
    20. exc.printStackTrace();
    21. // This means that the name of one of the fields changed names or
    22. // declaration and will have to be re-examined.
    23. }
    24. this.goalSelector.a(0, new PathfinderGoalFloat(this));
    25. this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this));
    26. this.goalSelector.a(3, new PathfinderGoalMoveIndoors(this));
    27. this.goalSelector.a(5,new PathfinderGoalOpenDoor(this, true));
    28. this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this,EntityHuman.class, 8.0F));
    29. this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D));
    30.  
    31. this.goalSelector.a(7, new PathfinderGoalMeleeAttack(this,EntityHuman.class, 1.0D, false));
    32. this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
    33. this.targetSelector.a(2, new PathfinderGoalNearestAttackableGangster(this, EntityHuman.class, 0, true,1));
    34.  
    35. EntityEquipment e = ((Zombie)this.getBukkitEntity()).getEquipment();
    36. e.setHelmet(equip[0]);
    37. e.setChestplate(equip[1]);
    38. e.setLeggings(equip[2]);
    39. e.setBoots(equip[3]);
    40. e.setItemInHand(equip[4]);
    41.  
    42. }
    43.  
    44.  
    45. @Override
    46. protected void aD() {
    47. super.aD();
    48. this.getAttributeInstance(GenericAttributes.e).setValue(3.0D);
    49. }

    i would guase its because PigZombie is instance of Zombie ore something
    am i right?
    andhow to fix this?
     
  10. Offline

    TeeePeee

    ToastHelmi
    You should be able to override both PigZombies and normal Zombies. Make sure you made the entry in CustomEntityTypes.

    Also, there's a method that equips entities. It's 1.7.2 it's bA() and bC() in 1.7.5. You should put your equipment stuff in that method and it is called automatically when the entity is created.
     
  11. Offline

    ToastHelmi

    I think i have done it correct
    Code:java
    1. ZOMBIE("Zombie", 54, EntityType.ZOMBIE, EntityZombie.class,PoliceOfficer.class),
    2. SKELETON("Skeleton",51,EntityType.SKELETON,EntitySkeleton.class,Sniper.class),
    3. SWAT("PigZombie",57,EntityType.PIG_ZOMBIE,EntityPigZombie.class,Swat.class);
     
  12. Offline

    TeeePeee

    ToastHelmi
    Make a debug message to see if the custom pigman is spawning or not. Just System.out.println in the constructor.
     
  13. Offline

    ToastHelmi

    they spawn but dosent have the right beavior
     
  14. Offline

    TeeePeee

    ToastHelmi
    What do you mean, they don't have the right behavior? Are they not getting the proper equipment? Or the right pathfinders? Or...?

    I need more information on the problem if you want me to help remedy it.
     
  15. Offline

    97WaterPolo

    TeeePeee
    To start thank you so much for this tutorial, it has helped me greatly!

    Couple questions for this if you have a chance.

    1. I am using "this.setCustomName("" + ChatColor.RED + ChatColor.BOLD + "Bandit");" which works, only problem is it only shows the name when a player has their crossheirs on the mob, is there a way to get it to show all the time like another player?

    2. I am trying to set the armor and item of the mob, no errors or anything it just does nothing. I know its running as their health, name, and such is the same as the modified class.
    Code:
    Code:java
    1. public CustomEntityZombie(World world) {
    2. super(world);
    3. ItemStack sword = CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(Material.STONE_SWORD, 1));
    4. ItemStack helm = CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_HELMET, 1));
    5. ItemStack chest = CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_CHESTPLATE, 1));
    6. ItemStack leg = CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_LEGGINGS, 1));
    7. ItemStack boot = CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_BOOTS, 1));
    8. this.setCustomName("" + ChatColor.RED + ChatColor.BOLD + "Bandit");
    9. this.setCustomNameVisible(true);
    10. this.setEquipment(0, sword);
    11. this.setEquipment(4, helm);
    12. this.setEquipment(3, chest);
    13. this.setEquipment(2, leg);
    14. this.setEquipment(1, boot);
    15. this.setHealth(30);
    16. try {
    17. Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
    18. bField.setAccessible(true);
    19. Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
    20. cField.setAccessible(true);
    21. bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
    22. bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
    23. cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
    24. cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
    25. } catch (Exception exc) {
    26. exc.printStackTrace();
    27. // This means that the name of one of the fields changed names or declaration and will have to be re-examined.
    28. }
    29.  
    30. //The rest of the class.
     
  16. Offline

    ToastHelmi

    TeeePeee
    it seams like the entityselector in PathfinderGoalNearestAttackableGangster
    or
    PathfinderGoalNearestAttackableGangster itselfe dosent work witg PigZombie
     
  17. Offline

    TeeePeee

    97WaterPolo
    Glad the tutorial helped!
    1) I'm not positive. Sorry!
    2) Move the code to set the equipment to a protected void bA(). This is the method that Minecraft uses to equip mobs so if you equip it beforehand, it will just override it.

    ToastHelmi
    Post your PathfinderNearestAttackableGangster.
     
  18. Offline

    97WaterPolo

    TeeePeee
    Thanks so much, will try it soon! The way I get the item stack is all right? Wasn't sure as it doesn't look normal, Lol. Thanks again!
     
  19. Offline

    ToastHelmi

    TeeePeee
    This classes work with a normal Zombie
    PathfinderNearestAttackableGangster
    Code:java
    1. public class PathfinderGoalNearestAttackableGangster extends PathfinderGoalTarget {
    2.  
    3. private final Class a;
    4. private final int b;
    5. private final DistanceComparator e;
    6. private final IEntitySelector f;
    7. private EntityLiving g;
    8.  
    9. public PathfinderGoalNearestAttackableGangster(EntityCreature entitycreature, Class oclass, int i, boolean flag, int minLevel) {
    10. this(entitycreature, oclass, i, flag, false, minLevel);
    11. }
    12.  
    13. public PathfinderGoalNearestAttackableGangster(EntityCreature entitycreature, Class oclass, int i, boolean flag, boolean flag1, int minLevel) {
    14. this(entitycreature, oclass, i, flag, flag1, (IEntitySelector) null, minLevel);
    15. }
    16.  
    17. public PathfinderGoalNearestAttackableGangster(EntityCreature entitycreature, Class oclass, int i, boolean flag, boolean flag1, IEntitySelector ientityselector, int minLevel) {
    18. super(entitycreature,flag, flag1);
    19. this.a = oclass;
    20. this.b = i;
    21. this.e = new DistanceComparator(entitycreature);
    22. this.a(1);
    23. this.f = new EntitySelectorNearestAttackableGangster(this, ientityselector,minLevel);
    24. }
    25.  
    26. public boolean a() {
    27. if (this.b > 0 && this.c.aH().nextInt(this.b) != 0) {
    28. return false;
    29. } else {
    30. double d0 = this.f();
    31. List list = this.c.world.a(this.a, this.c.boundingBox.grow(d0, 4.0D, d0), this.f);
    32.  
    33. Collections.sort(list, this.e);
    34. if (list.isEmpty()) {
    35. return false;
    36. } else {
    37. this.g = (EntityLiving) list.get(0);
    38. return true;
    39. }
    40. }
    41. }
    42.  
    43. public void c() {
    44. this.c.setGoalTarget(this.g);
    45. super.c();
    46. }
    47. public boolean a(EntityLiving e, boolean flag){
    48. return super.a(e, flag);
    49. }
    50. }


    EntitySelectorNearestAttackableGangster
    Code:java
    1. public class EntitySelectorNearestAttackableGangster implements IEntitySelector{
    2. final IEntitySelector c;
    3. final PathfinderGoalNearestAttackableGangster d;
    4. final int minLevel;
    5.  
    6. EntitySelectorNearestAttackableGangster(PathfinderGoalNearestAttackableGangster pathfindergoalnearestattackablegengster,IEntitySelector ientityselector, int minLevel) {
    7. this.d = pathfindergoalnearestattackablegengster;
    8. this.c = ientityselector;
    9. this.minLevel = minLevel;
    10. }
    11.  
    12. public boolean a(Entity entity) {
    13. return !(entity instanceof EntityPlayer) ? false : (this.c != null && !this.c.a(entity) ? false : (!checkWantedlevel((EntityPlayer)entity) ? false : this.d.a((EntityLiving) entity,false)));
    14. }
    15. public boolean checkWantedlevel(EntityPlayer e){
    16. return CrimeManager.getInstance().getWantedLevel((Player)e.getBukkitEntity())>= minLevel;
    17.  
    18. }
    19. }
    20. [//syntax]
     
  20. Offline

    zDylann


    1. When you set the custom name, use <Entity>.setCustomNameVisible(true).
     
  21. Offline

    97WaterPolo

    zDylann
    I did, the name that is custom shows up, but it seems to only show up when you are near the mob.
     
  22. Offline

    zDylann

    That has to be something else then. As long as the mob is loaded on the client I see the tag while its true. Which is why I turned it off since its kind of annoying to see mobs underground. Try testing without any other plugins. Unless you are using spigot/libigot?
     
  23. Offline

    97WaterPolo

    zDylann
    Never heard of libigot? :confused: sounds weird.
    I was generally loading it by using a plugin reloader which probably caused some errors, I restarted it and it works well now!
     
  24. Offline

    ZeusAllMighty11

    97WaterPolo

    'setCustomNameVisible(true)' will show the mob's name at all times.
     
    97WaterPolo likes this.
  25. Offline

    NeonGuilmon

    Nice tutorial :) I never knew you could do so much!
    One question: is it possible to use this method just to add an entity that extends another entity?
    Basically, I want to create a Railcart entity that extends EntityMinecartAbstract. Then two other entities will extend the Railcart entity. However, I don't want to completely replace Minecarts, just create another entity based off them.
    Do I need a special enum like in your tutorial?
     
  26. Offline

    TeeePeee

    NeonGuilmon
    Much of the register method is to ensure the entities spawn naturally in place of other mobs. The others still exist but Minecraft essentially has lost the proper references to them.

    In the CustomEntityTypes#a() method, remove everything but the fields containing "d" and "f" and it should not spawn naturally. Then, you can simply spawn the custom Railcarts in by creating them:

    Code:java
    1. Railcart cart = new Railcart(someworld);
    2. cart.setLocation(somelocation);
    3. someworld.addEntity(cart);
     
  27. Offline

    paully104

    Hey guys having a similiar issue to the one posted earlier in this thread however for whatever reason i can't seem to figure it out after reading up to page 6 in this thread so far ^^!.

    Code:
    package com.paulreitz.entitytest;
     
    import java.lang.reflect.Field;
     
    import net.minecraft.server.v1_7_R1.EntityHuman;
    import net.minecraft.server.v1_7_R1.EntitySkeleton;
    import net.minecraft.server.v1_7_R1.EntityZombie;
    import net.minecraft.server.v1_7_R1.GenericAttributes;
    import net.minecraft.server.v1_7_R1.PathfinderGoalFloat;
    import net.minecraft.server.v1_7_R1.PathfinderGoalHurtByTarget;
    import net.minecraft.server.v1_7_R1.PathfinderGoalLookAtPlayer;
    import net.minecraft.server.v1_7_R1.PathfinderGoalMeleeAttack;
    import net.minecraft.server.v1_7_R1.PathfinderGoalMoveThroughVillage;
    import net.minecraft.server.v1_7_R1.PathfinderGoalMoveTowardsRestriction;
    import net.minecraft.server.v1_7_R1.PathfinderGoalNearestAttackableTarget;
    import net.minecraft.server.v1_7_R1.PathfinderGoalRandomLookaround;
    import net.minecraft.server.v1_7_R1.PathfinderGoalRandomStroll;
    import net.minecraft.server.v1_7_R1.PathfinderGoalSelector;
    import net.minecraft.server.v1_7_R1.World;
    import org.bukkit.craftbukkit.v1_7_R1.util.UnsafeList;
     
     
     
    public class CustomEntityZombie extends EntityZombie {
     
    public CustomEntityZombie(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 means that the name of one of the fields changed names or declaration and will have to be re-examined.
    }
     
    this.goalSelector.a(0, new PathfinderGoalFloat(this));
    this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.0D, false));
    this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntitySkeleton.class, 1.0D, true));
    this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D));
    this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, false));
    this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D));
    this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
    this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
    this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
    this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 0, true));
    this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntitySkeleton.class, 0, false));
    }
     
    //@Override
    //protected void aD() {
    //super.aD();
    //this.getAttributeInstance(GenericAttributes.e).setValue(300.0D); // Original 3.0D sets mob damage to 300!
    //
     
     
     
     
     
    @Override
    protected void aD() {
     
        //this.bc().b(GenericAttributes.b);
        super.aD();
      this.getAttributeInstance(GenericAttributes.b).setValue(70.0D);//mob range
        super.aD();
     
     
    }
     
     
     
    }
    Basically im having the null point error from the protected void aD() , i'm just simply trying to extend the range from the default of 40 to 70. Here's the EntityZombie 1.7.2 i'm looking at also: https://github.com/SpigotMC/mc-dev/...3e8e69/net/minecraft/server/EntityZombie.java


    Edit: Solved, no idea why this took me so long to figure out lol
    Code:
    @Override
    protected void aD() {
       
       
        super.aD();
        //this.bc().b(GenericAttributes.b);
      this.getAttributeInstance(GenericAttributes.b).setValue(100.0D);//mob range
     
       
     
    }
     
  28. Offline

    NeonGuilmon

    Thanks, will try it out once I get my dev server sorted. Again, +1 for the tutorial!
     
  29. Offline

    97WaterPolo

    TeeePeee
    For some reason I am getting "The return type is incompatible with EntityLiving.aD()" on
    Code:java
    1. @Override
    2. protected void aD() {
    3. super.aD();
    4. this.getAttributeInstance(GenericAttributes.e).setValue(3.5D); // Original 3.0D
    5. this.getAttributeInstance(GenericAttributes.d).setValue(0.699999988079074D);//Original 0.699999988079071D
    6.  
    7. }


    Any idea why and how to fix it?


    EDIT: Fixed it, guess the method changed for me, changed it to aC like I saw in source, and it works!
     
  30. Offline

    TwoPointDuck

    Hey, im back again. :)
    Whats the way to remove current Pathfinders from an already living mob?
     
Thread Status:
Not open for further replies.

Share This Page