Im stuck. I literally have no idea how to register a custom entity in 1.15. All the tutorials out there are so outdated that I cant even get anything out of them. Please help
I doubt that there's no tutorial... But I'll give you my method: Code (Java): @SuppressWarnings("unchecked") public static void register(String name, int id, Class<?> registryClass) { ((Map) ReflectionUtil.getPrivateField("c", EntityTypes.class, null)).put(name, registryClass); ((Map)ReflectionUtil.getPrivateField("d", EntityTypes.class, null)).put(registryClass, name); ((Map) ReflectionUtil.getPrivateField("f", EntityTypes.class, null)).put(registryClass, id); } ReflectionUtil: Code (Java): public final class ReflectionUtil { private ReflectionUtil() {} @Nullable public static Object getPrivateField(String fieldName, @NotNull Class<?> clazz, Object object) { try { Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); return field.get(object); } catch(NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } return null; } } You can then register an Entity like this: Code (Java): PetRegistry.register("some_name_that_is_not_taken", id, clazz); id is the id of the mob (if you want to have a custom chicken, you'll have to insert 93) and clazz is the class of your custom mob.
Quick Q... How do u spawn it. I dont know what to extend the class that im using. Hold the phone this doesnt work rn. Im getting this error Code (Text): java.lang.NoSuchFieldException: c [17:33:00] [Server thread/WARN]: at java.lang.Class.getDeclaredField(Unknown Source) [17:33:00] [Server thread/WARN]: at com.aestheticcraft.www.dungeons.entities.ReflectionUtil.getPrivateField(RegisterEntities.java:32) [17:33:00] [Server thread/WARN]: at com.aestheticcraft.www.dungeons.entities.RegisterEntities.register(RegisterEntities.java:19) [17:33:00] [Server thread/WARN]: at com.aestheticcraft.www.main.Main.registerEntities(Main.java:231) [17:33:00] [Server thread/WARN]: at com.aestheticcraft.www.main.Main.onEnable(Main.java:70) [17:33:00] [Server thread/WARN]: at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263) [17:33:00] [Server thread/WARN]: at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:352) [17:33:00] [Server thread/WARN]: at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:417) [17:33:00] [Server thread/WARN]: at org.bukkit.craftbukkit.v1_15_R1.CraftServer.enablePlugin(CraftServer.java:462) [17:33:00] [Server thread/WARN]: at org.bukkit.craftbukkit.v1_15_R1.CraftServer.enablePlugins(CraftServer.java:376) [17:33:00] [Server thread/WARN]: at net.minecraft.server.v1_15_R1.MinecraftServer.a(MinecraftServer.java:456) [17:33:00] [Server thread/WARN]: at net.minecraft.server.v1_15_R1.DedicatedServer.init(DedicatedServer.java:266) [17:33:00] [Server thread/WARN]: at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:783) [17:33:00] [Server thread/WARN]: at java.lang.Thread.run(Unknown Source) [17:33:00] [Server thread/ERROR]: Error occurred while enabling Enchanter v0.2 (Is it up to date?) java.lang.NullPointerException: null at com.aestheticcraft.www.dungeons.entities.RegisterEntities.register(RegisterEntities.java:19) ~[?:?] at com.aestheticcraft.www.main.Main.registerEntities(Main.java:231) ~[?:?] at com.aestheticcraft.www.main.Main.onEnable(Main.java:70) ~[?:?] at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263) ~[server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:352) [server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:417) [server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.craftbukkit.v1_15_R1.CraftServer.enablePlugin(CraftServer.java:462) [server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.craftbukkit.v1_15_R1.CraftServer.enablePlugins(CraftServer.java:376) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.a(MinecraftServer.java:456) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.DedicatedServer.init(DedicatedServer.java:266) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:783) [server.jar:git-Spigot-3b314f5-e2790ae] at java.lang.Thread.run(Unknown Source) [?:1.8.0_211] Also one more thing... lol how do I spawn him with armor
A quick example of a custom chicken: Code (Text): public class CustomChicken extends EntityChicken { public CustomChicken(org.bukkit.World world) { // I like to use the bukkit world since that makes thing easier super(EntityTypes.CHICKEN, ((CraftWorld) world).getHandle()); } public void spawn(Location loc) { this.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); this.world.addEntity(this, CreatureSpawnEvent.SpawnReason.CUSTOM); } }
ah, right, they changed it... All right, I can maybe provide the answer tomorrow. If you want to find it out yourself; you have to look for the method "a". Try to invoke that with suitable arguments...
This is the method that I use for registering custom entities: Code (Java): public void register() throws IllegalStateException { if (!registered) { throw new IllegalStateException("Unable to register PetType '" + getName() + "', as it is already registered."); } Map<Object, Type<?>> dataTypes = (Map<Object, Type<?>>)DataConverterRegistry.a() .getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion())) .findChoiceType(DataConverterTypes.ENTITY_TREE).types(); dataTypes.put("battlepets:"+name, dataTypes.get(entityType.f())); // a is a class field of type EntityTypes.a<EntityLiving> a = EntityTypes.a.a(maker, EnumCreatureType.CREATURE); IRegistry.a(IRegistry.ENTITY_TYPE, name, a.a(name)); registered = true; } For spawning: Code (Java): public org.bukkit.entity.Entity spawn(Location loc) { Entity entity = getEntityType().spawnCreature(((CraftWorld)loc.getWorld()).getHandle(), null, null, null, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), EnumMobSpawn.EVENT, true, false); return entity == null ? null : entity.getBukkitEntity(); } Parameters in order for EntityType#spawnCreature are the NMS world, the entity's initial nbt (NBTTagCompound), the custom name (IChatComponent), the player who spawned the entity (EntityPlayer), location (BlockPosition), spawn reason (EnumMobSpawn). The last two are a couple of boolean flags; I'm not sure about what the each do, but supposedly the first one corrects the entity's position in some manner.
can u let me see ur variables outside of the method. Im not seeing the default values Also getting this error Code (Text): org.bukkit.command.CommandException: Unhandled exception executing command 'spawn' in plugin Enchanter v0.2 at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.craftbukkit.v1_15_R1.CraftServer.dispatchCommand(CraftServer.java:711) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PlayerConnection.handleCommand(PlayerConnection.java:1657) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PlayerConnection.a(PlayerConnection.java:1497) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PacketPlayInChat.a(PacketPlayInChat.java:47) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.TickTask.run(SourceFile:18) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeTask(SourceFile:144) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeNext(SourceFile:118) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.aZ(MinecraftServer.java:917) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.executeNext(MinecraftServer.java:910) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.awaitTasks(SourceFile:127) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.sleepForTick(MinecraftServer.java:894) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:827) [server.jar:git-Spigot-3b314f5-e2790ae] at java.lang.Thread.run(Unknown Source) [?:1.8.0_211] Caused by: java.lang.IllegalArgumentException: Data fixer not registered for: Fallen_Sailor in entity_tree at com.mojang.datafixers.schemas.Schema.getChoiceType(Schema.java:109) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.DataConverterSchemaNamed.getChoiceType(SourceFile:23) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.EntityTypes$a.a(EntityTypes.java:425) ~[server.jar:git-Spigot-3b314f5-e2790ae] at com.aestheticcraft.www.dungeons.entities.FallenSailor.register(FallenSailor.java:68) ~[?:?] at com.aestheticcraft.www.commands.SpawnEntityCommand.onCommand(SpawnEntityCommand.java:34) ~[?:?] at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[server.jar:git-Spigot-3b314f5-e2790ae] ... 17 more
Whoops, forgot about some other class fields. entityTypes/getEntityType() is ex: EntityTypes.ZOMBIE or whatever it is for the entity it extends from. I can share the rest of the code when I'm back to my laptop. edit:// Constructor Code (Java): private PetType(final String name, final Class<T> petClass, EntityTypes<? super T> type, final EntityTypes.b<T> maker) { this.name = name; this.petClass = petClass; this.maker = maker; // ex: CustomZombie::new this.entityType = type; } petClass is only necessary for resolving T, which is PetType's (only) generic parameter. Example instantiation: Code (Java): new PetType<PetZombie>("pet_zombie", PetZombie.class, EntityTypes.ZOMBIE, PetZombie::new);
Im still getting this error. When i import the code it changes the DataConverterTypes#ENTITY_TREE to DataConverterTypes#ENTITY Code (Text): at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[server.jar:git-Spigot-3b314f5-e2790ae] at org.bukkit.craftbukkit.v1_15_R1.CraftServer.dispatchCommand(CraftServer.java:711) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PlayerConnection.handleCommand(PlayerConnection.java:1657) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PlayerConnection.a(PlayerConnection.java:1497) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PacketPlayInChat.a(PacketPlayInChat.java:47) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.TickTask.run(SourceFile:18) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeTask(SourceFile:144) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeNext(SourceFile:118) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.aZ(MinecraftServer.java:917) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.executeNext(MinecraftServer.java:910) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.awaitTasks(SourceFile:127) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.sleepForTick(MinecraftServer.java:894) [server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:827) [server.jar:git-Spigot-3b314f5-e2790ae] at java.lang.Thread.run(Unknown Source) [?:1.8.0_211] Caused by: java.lang.IllegalArgumentException: Data fixer not registered for: Fallen Sailor in entity_tree at com.mojang.datafixers.schemas.Schema.getChoiceType(Schema.java:109) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.DataConverterSchemaNamed.getChoiceType(SourceFile:23) ~[server.jar:git-Spigot-3b314f5-e2790ae] at net.minecraft.server.v1_15_R1.EntityTypes$a.a(EntityTypes.java:425) ~[server.jar:git-Spigot-3b314f5-e2790ae] at com.aestheticcraft.www.dungeons.entities.EntityRegistry.register(EntityRegistry.java:80) ~[?:?] at com.aestheticcraft.www.commands.SpawnEntityCommand.onCommand(SpawnEntityCommand.java:36) ~[?:?] at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[server.jar:git-Spigot-3b314f5-e2790ae] ... 17 more >
Odd. DataConverterTypes.ENTITY_TREE just isn't a field? Perhaps because I'm using 1.15.2 instead of 1.15.1. Is there a DataConverterTypes.n instead? If so, try that.
I tried it gave a different error. Code (Text): Caused by: java.lang.IllegalArgumentException: Not a choice type at com.mojang.datafixers.schemas.Schema.lambda$findChoiceType$4(Schema.java:115) ~[server.jar:git-Spigot-3b314f5-e2790ae] at java.util.Optional.orElseThrow(Unknown Source) ~[?:1.8.0_211] at com.mojang.datafixers.schemas.Schema.findChoiceType(Schema.java:115) ~[server.jar:git-Spigot-3b314f5-e2790ae] at com.aestheticcraft.www.dungeons.entities.EntityRegistry.register(EntityRegistry.java:76) ~[?:?] at com.aestheticcraft.www.commands.SpawnEntityCommand.onCommand(SpawnEntityCommand.java:36) ~[?:?] at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[server.jar:git-Spigot-3b314f5-e2790ae] ... 17 more
Was playing around with it some yesterday and realized some issues in my code, i.e. using a full namespaced key where only the key was necessary, etc. or the fact that the MinecraftKey returned by EntityTypes#h is in the format of "minecraft:entity/<entity_name>" rather than simply "minecraft:<entity_name>". That also explains why there was no data fixer set for the custom entity type. Here's the fixed class: https://pastebin.com/6jcWBtaX Also, as a heads up in case there's any question, make sure you super the parent EntityTypes in your custom entity's constructor, otherwise you'll be stuck with a pig with all the expected behavior of the parent/custom entity. Not sure why it happens. There's something amusing about a pig strolling around, groaning, and burning in the daylight like a zombie though
Hi Guys, Thank's Escad for the help, I was looking for a good example to create nms custom mob in 1.15 version and it's very hard to find. I would like to just spawn a Custom Zombie and give him as goal to go to a specific Location. Unfortunately, I still not understand how to create my CustomZombie class. The problem is that in all tutorials I saw, the constructor of my CustomZombie extends EntityZombie and only take as constructor's parameter the Bukkit World, like this: Code (Text): public class CustomZombie extends EntityZombie { public CustomZombie(org.bukkit.World world) { super(((CraftWorld)world).getHandle()); } and it doesn't work when I call the CustomEntityType's constructor I got an "Cannot resolve constructor CustomZombie" on the last parameter of Code (Text): new CustomEntityType <CustomZombie> ("CustomZombie", CustomZombie.class, EntityType.ZOMBIE, CustomZombie::new); Could you show me an example of a Custom Mob class that you created. Thank's
The last parameter is of type EntityTypes.a<T> and you're passing in a functional interface that implements a single method. It takes the NMS world and an instance of EntityTypes, which should belong to your custom entity's parent type. You need an additional constructor that also takes these arguments, otherwise the server won't be able to spawn the entity itself. My constructors look something like this: Code (Java): public CustomEntity(World world, EntityTypes<? extends EntityZombie> entityType) { this(world); } public CustomEntity(World world) { super(world, EntityTypes.ZOMBIE); } Honestly not sure if the server manages to pass the parent EntityTypes to the constructor or not (probably not), but I pass the vanilla one explicitly to be safe. Could be easily debugged by printing EntityTypes#h though
The Registration of my Custom mob seems to works well now, but when I do Code (Text): zombie = new CustomEntityType <CustomZombie> ("customzombie", CustomZombie.class, EntityTypes.ZOMBIE, CustomZombie::new); zombie.register(); zombie.spawn(new Location(Bukkit.getWorld("world"), 112 ,58 ,-134)); I have a NullPointerException in the spawn Method on the line : Code (Text): Entity entity = entityType.spawnCreature(((CraftWorld)loc.getWorld()).getHandle(), null, null, null, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), EnumMobSpawn.EVENT, true, false); I checked if all parameters were all right and I don't see any problem, do you have an idea ?
No idea, In my OnLoad method I've this : Code (Text): @Override public void onLoad(){ new CustomEntityType <CustomZombie> ("customzombie", CustomZombie.class, EntityTypes.ZOMBIE, CustomZombie::new).register(); } and there seems to be no problem in the registry of the entity but when I want to spawn my customZombie I do : Code (Text): this.zombie = new CustomEntityType <CustomZombie> ("customzombie", CustomZombie.class, EntityTypes.ZOMBIE, CustomZombie::new); Entity Myzombie = zombie.spawn(new Location(Bukkit.getWorld("world"), 112 ,58 ,-134)); and still have a NullPointerException .
You're instantiating a new CustomEntityType when you spawn your zombie. It isn't registered either, so the EntityTypes for your custom entity (which is set in #register) is null. That's what the spawn method is called from. You'll need to use the same single instance of CustomEntityType.