Creating custom mobs (NMS) (Single Instance)

Discussion in 'Plugin Development' started by ThePixelPony, Sep 2, 2014.

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

    ThePixelPony

    So I'd like to spawn a single instance of a custom mob.
    I've got no idea on how to do this, but I have tried the following two threads:
    https://forums.bukkit.org/threads/spawning-single-custom-mobs.203390/
    http://forums.bukkit.org/threads/tutorial-how-to-customize-the-behaviour-of-a-mob-or-entity.54547/

    I do not want to override every single mob in the game.

    This is my CustomEntity.java:
    Code:java
    1. package com.thepixelpony.game.mob.entity;
    2.  
    3. import java.lang.reflect.InvocationTargetException;
    4. import java.lang.reflect.Method;
    5. import net.minecraft.server.v1_7_R4.EntityCow;
    6. import net.minecraft.server.v1_7_R4.EntityInsentient;
    7. import net.minecraft.server.v1_7_R4.EntityTypes;
    8. import net.minecraft.server.v1_7_R4.EntityZombie;
    9. import org.bukkit.entity.EntityType;
    10.  
    11. public enum CustomEntity {
    12.  
    13. COW("Cow", 92, EntityType.COW, EntityCow.class, CustomCow.class),
    14. ZOMBIE("Zombie", 54, EntityType.ZOMBIE, EntityZombie.class, CustomZombie.class);
    15.  
    16. private String name;
    17. private int id;
    18. private EntityType entityType;
    19. private Class<? extends EntityInsentient> nmsClass;
    20. private Class<? extends EntityInsentient> customClass;
    21.  
    22. private CustomEntity(String name, int id, EntityType entityType, Class<? extends EntityInsentient> nmsClass, Class<? extends EntityInsentient> customClass){
    23. this.name = name;
    24. this.id = id;
    25. this.entityType = entityType;
    26. this.nmsClass = nmsClass;
    27. this.customClass = customClass;
    28. }
    29.  
    30. public String getName(){
    31. return this.name;
    32. }
    33.  
    34. public int getID(){
    35. return this.id;
    36. }
    37.  
    38. public EntityType getEntityType(){
    39. return this.entityType;
    40. }
    41.  
    42. public Class<? extends EntityInsentient> getNMSClass(){
    43. return this.nmsClass;
    44. }
    45.  
    46. public Class<? extends EntityInsentient> getCustomClass(){
    47. return this.customClass;
    48. }
    49.  
    50. public static void registerEntities(){
    51. for (CustomEntity entity : values()){
    52. try{
    53. Method a = EntityTypes.class.getDeclaredMethod("a", new Class<?>[]{Class.class, String.class, int.class});
    54. a.setAccessible(true);
    55. a.invoke(null, entity.getCustomClass(), entity.getName(), entity.getID());
    56. }
    57. }
    58. }
    59.  
    60. }


    This is my CustomCow.java (and the CustomZombie.java is almost identical):
    Code:java
    1. package com.thepixelpony.game.mob.entity;
    2.  
    3. import net.minecraft.server.v1_7_R4.EntityCow;
    4. import net.minecraft.server.v1_7_R4.World;
    5.  
    6. public class CustomCow extends EntityCow {
    7.  
    8. public CustomCow(World world) {
    9. super(world);
    10. }
    11. }


    This is my spawning method:
    Code:java
    1. public static void spawnCustomEntity(CustomEntity entity, String name, Location loc, World world) {
    2.  
    3. try {
    4. EntityInsentient e = (EntityInsentient) (CustomZombie.class.getDeclaredConstructor(World.class).newInstance(world));
    5. e.setPosition(loc.getX(), loc.getY(), loc.getZ());
    6.  
    7. e.setCustomName(name);
    8. e.setCustomNameVisible(true);
    9.  
    10. world.addEntity(e);
    11. Bukkit.getServer().broadcastMessage(ex.toString());
    12. ex.printStackTrace();
    13. }
    14. //EntityInsentient e = (EntityInsentient) entity.getCustomClass().newInstance();s
    15. }


    I tried to spawn a custom cow like this:
    Code:java
    1. ClassName.spawnCustomEntity(CustomEntity.COW, "Name", ((Player) sender).getLocation(), ((CraftWorld) ((Player) sender).getLocation().getWorld()).getHandle());


    I know that people have got it to work before but I keep getting an InstantiationException.

    Thank you in advance for any help given :)
     
  2. ThePixelPony always post the exception. Show it to me/us and i/we may can help you faster/better.
     
  3. Offline

    ThePixelPony

    Shmobi There's no stack trace. I tried ex.printStackTrace() and Logger.getLogger(Mob.class.getName()).log(Level.SEVERE, null, ex); but it doesn't print one :confused:

    I know that it's the following line in the entity spawning method that requires the multicatch clause:
    Code:java
    1. EntityInsentient e = (EntityInsentient) (CustomZombie.class.getDeclaredConstructor(World.class).newInstance(world));
     
  4. ThePixelPony do single catch clauses instead of multicatch and try/catch this:
    Code:java
    1. Class customZombieClass = CustomZombie.class;
    2. Class worldClass = World.class;
    3. Constructor<CustomZombie> customZombieConstructor = customZombieClass.getConstructor(worldClass);
    4. System.out.println("Got the constructor: "+customZombieConstructor.hashCode()+" Object: "+customZombieConstructor);
    5. CustomZombie customZombie = customZombieConstructor.newInstance(world);
    6. System.out.println("Created CustomZombie: "+customZombie.hashCode()+" Object: "+customZombie);
    7. EntityInsentient e = (EntityInsentient) customZombie;
    8. System.out.println("Casted CustomZombie: "+e.hashCode()+" Object: "+e);

    Why do you know that you get an instantinationexception if no exception is thrown? there must be one, try to run this. if the code exit somewhere, you will se it in your console because i'm printing every important step into it.
     
  5. Offline

    ThePixelPony

    Shmobi Well, once it worked and I made it message me the name of the exception.

    Ooh, thanks a lot for suggesting that! The result was the following:
    Code:
    07:09:15  [Server thread/INFO]: Got the constructor: 1596475514 Object: public com.thepixelpony.game.mob.entity.CustomZombie(net.minecraft.server.v1_7_R4.World)
    07:09:15  [Server thread/INFO]: Created CustomZombie: 1810175 Object: CustomZombie['unknown'/1810175, l='world', x=0.00, y=0.00, z=0.00]
    07:09:15  [Server thread/INFO]: Casted CustomZombie: 1810175 Object: CustomZombie['unknown'/1810175, l='world', x=0.00, y=0.00, z=0.00]
    That basically means that the entities are apparently spawning, but not at the right position.

    I tried setting the position after adding the entity to the world and then printing it's coordinates. According to Bukkit, it was at my location, but I couldn't see it.
     
  6. ThePixelPony well i have 0.0% knowledge about costumentities xD all i told you was just guessing and normal java programming. i believe you made a mistake in your spawning method. are you sure that world.add() does really spawn it? i think you should try something like spawnEntity(YourCoustumEntity.class, ....); i don't think add does what you want, but i am not quiet sure, look in the docs
     
  7. Offline

    ThePixelPony

    Shmobi I used world.addEntity(e, CreatureSpawnEvent.SpawnReason.CUSTOM); and it worked as I was cancelling any generic spawns. Then I was slain by unknown and my client crashed. Progress! :p

    When I finish it, I'll post the code :)
     
  8. ThePixelPony xD after finishing your code you should, before you add the mob, check if your mob is instance of unknown and then add it :D just to make it really safe
     
  9. Offline

    ThePixelPony

    Shmobi Instanceof unknown? That's not a class :p

    So now using the code below:
    Code:java
    1. public static void spawnCustomEntity(CustomEntity entity, String name, Location l, World world) {
    2. CustomCow zomb = new CustomCow(world);
    3. zomb.setCustomName("Test");
    4. zomb.setCustomNameVisible(true);
    5. zomb.setPositionRotation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
    6. }

    This crashed the client. However, when I replace CustomCow with EntityCow, it does work, but the cow is invisible to the player until they reconnect or move away from the chunk and come back to it, lol
     
  10. ThePixelPony you knew exactly what i meant with instance!! xD so shhhhhhhh shhhhhhh shhhhut up :D Well, like i said, i don't know much about spawning custom entities. if i would be you, i would go to goole and would search for something like "how to spawn custom entities bukkit". i think you could find something interesting. also i can show you this tutorial which is about creating and spawning custom entities. i wanted to take a look at it for a long time now, but i still couldn't find time or i was to lazy :D here is the link: https://forums.bukkit.org/threads/tutorial-custom-entities-meteor.93899/

    hope i could help you :)
     
  11. Offline

    PluginMaker

    ThePixelPony
    As I said in another thread, there is something wrong at the moment with custom entities. You have done your checks right- when you spawn normal cow, everything is fine, but when you spawn custom cow it will crash the client.
    Unfortunately, I have no idea how it can be fixed.
     
  12. Offline

    jpjunho

    ThePixelPony
    In that method you also need to do world.addEntity(zomb);
    And have you registered your entity?
     
  13. Offline

    ThePixelPony

    PluginMaker Oh okay, I see. Maybe it's a Bukkit bug :confused:
    jpjunho Nope. How does one register an entity? Oh and I did have that (I don't know why I missed it out, lol)
     
  14. Offline

    jpjunho

  15. Offline

    ThePixelPony

    jpjunho Ooh thank you! One question, is it possible to register custom entity names, such as "CustomEnderDragon" etc?
     
Thread Status:
Not open for further replies.

Share This Page