Solved Scheduled entity spawning

Discussion in 'Spigot Plugin Development' started by Deividas, Nov 30, 2019.

  1. Hello, so what I'm trying to do is to spawn snowman's at preset random locations. Yet my code doesn't work, so perhaps some one of more experienced devs could throw me an advice or two how to make it work. The idea itself is to spawn snowman's at preset locations randomly, but before spawning check if there isn't one already spawned.

    Code (Java):
    public class Main extends JavaPlugin{



     

        @Override
        public void onEnable() {
            getCommand("espawn").setExecutor(new spawnEntity());
         
            World w = Bukkit.getWorld("world");
            List<Location> locList = new ArrayList<Location>();
            locList.add(new Location(w, 2.501, 65.000, 278.4420));
            locList.add(new Location(w, -0.480, 65.000, 278.4420));
            locList.add(new Location(w, -3.480, 65.000, 278.4420));
            int size = locList.size();
         
         
            Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
                    int random = new Random().nextInt(size);
                    Location rloc = locList.get(random);
                 
                    for(Entity e : getNearbyEntities(rloc, 3)) {
                        if(!(e instanceof Snowman)) {
                            Bukkit.getWorld("world").spawnEntity(rloc, EntityType.SNOWMAN);
                            Bukkit.broadcastMessage("Entity spawned! " + ChatColor.AQUA + rloc.getBlockX() + " " + rloc.getBlockY() + " " + rloc.getBlockZ());
                        }else {
                            Bukkit.broadcastMessage("Entity existing");
                        }
                    }
                }
            }, 100L, 100L);
     
        }
     
     
            public List<Entity> getNearbyEntities(Location loc, int radius) {
                List<Entity> entities = new ArrayList<Entity>();
             
                for(Entity e : loc.getWorld().getEntities())
                    if(loc.distance(e.getLocation()) <= radius)
                        entities.add(e);
             
                return entities;
            }
         
         
     
     

    }
     
    • Like Like x 1
  2. FYI: It's a lot easier to just use world.getNearbyEntities(location, double, double, double);
    What exactly doesn't work? Spawning them or checking if there are other snowmen close?
     
  3. Your method will work but only if the snowman is nearby the preset location so if he walks away, the spawner will spawn another one. If this is what you are going for, then ignore the rest of this post. I'd suggest keeping track of the snowman's UUID ("entity.getUniqueId()") along side the location they spawned at and then listening for entity deaths. If an entity dies that matches the UUID, you can then free up the location it spawned at so the random spawner can work again.
     
  4. The checking isn't working, was trying few variations like
    Code (Text):
    if(!(e.getType() == EntityType.SNOWMAN))
    if(!(e.getType().equals(EntityType.SNOWMAN)))
    But none of them working, they keep spawning on each other.
     
  5. location.distance(location) shouldn't be used to compare large distances (since you're checking all the entities), instead you should use distanceSquared. Try changing your getNearbyEntities method with the one I suggested above.
     
  6. So I wrote differend code to test entities spawning. With built in getNearbyEntities method getting an error on command use.
    Code (Java):
    public class Main extends JavaPlugin{
       
        @Override
        public void onEnable() {
            System.out.println("Started!");
        }
       
        double x = -10.487;
        double y = 63.000;
        double z = 267.491;
        Location spawnLoc = new Location(Bukkit.getWorld("world"), x, y, z);
       

       
       
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
       
               
                if(cmd.getName().equalsIgnoreCase("spawnmob")) {
                    for(Entity e : Bukkit.getWorld("world").getNearbyEntities(spawnLoc, 10, 10, 10)) {
                        if(e.getCustomName().contains("ManSnow")) {
                            sender.sendMessage("Entity already exists at this location!");
                        } else {
                            spawnSnowman(spawnLoc);
                        }
                    }
                }

            return false;
        }
       
        static void spawnSnowman(Location lok) {
            LivingEntity snowman = (LivingEntity) Bukkit.getWorld("world").spawnEntity(lok, EntityType.SNOWMAN);
            snowman.setCustomName("ManSnow");
        }
    }
    Code (Text):
    [15:02:18 WARN]: Unexpected exception while parsing console command "spawnmob"
    org.bukkit.command.CommandException: Unhandled exception executing command 'spawnmob' in plugin TestSpawnPlugin v1.0
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchCommand(CraftServer.java:648) ~[spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchServerCommand(CraftServer.java:634) [spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at net.minecraft.server.v1_12_R1.DedicatedServer.aP(DedicatedServer.java:444) [spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:407) [spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679) [spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577) [spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_211]
    Caused by: java.lang.NullPointerException
            at org.bukkit.craftbukkit.v1_12_R1.CraftWorld.getNearbyEntities(CraftWorld.java:717) ~[spigot.jar:git-Spigot-642f6d2-57ab4cf]
            at lt.minecart.testspawn.Main.onCommand(Main.java:32) ~[?:?]
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-642f6d2-57ab4cf]
            ... 8 more
     
  7. Main.java:32, what's this line?
    Are you sure your world is named world?
     
  8. World is named "world" and line 32 is this one:
    Code (Java):
    for(Entity e : Bukkit.getWorld("world").getNearbyEntities(spawnLoc, 10, 10, 10))
     
  9. Something is null. Do some null checks before looping.
     
  10. If the nearest entities are not found, the loop simply will not be executed, will it? But it's worth a try.
     
    #10 Ristosha, Dec 1, 2019 at 6:16 PM
    Last edited: Dec 1, 2019 at 6:23 PM
  11. If that would have been the case, he wouldn't have gotten an NPE. The null checks are not meant to be there once he fixes the NPE.
     
  12. Did a check on world, appearently the world is null. Any ideas what is wrong with world declaration? Tried two options aswell, but nothing seem to change.
    The world sure is named "world".
    Code (Text):
    World w = Bukkit.getServer().getWorld("world");
    World w = Bukkit.getWorld("world");
     
  13. The world doesn't seem to be named "world" though. Print your world names using Bukkit.getWorlds().toString();
     
  14. It is world, managed to fix this one by declaring worlds inside onCommand() method. Another problem at the moment, that entities not spawning and console showing nothing but executed command.
    Code (Java):
    public class Main extends JavaPlugin{
         
        @Override
        public void onEnable() {
            System.out.println("Started!");
           
            if (Bukkit.getWorld("world") != null) {
                System.out.println("World " + Bukkit.getWorld("world").getName() + " is loaded!");
            } else {
                System.out.println("World is not loaded yet!");
            }
        }
        double x = -10.487;
        double y = 63.000;
        double z = 267.491;

        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
     
             
                if(cmd.getName().equalsIgnoreCase("spawnmob")) {
                    World w = Bukkit.getWorld("world");
                    Location spawnLoc = new Location(w, x, y, z);
                   
                    for(Entity e : w.getNearbyEntities(spawnLoc, 1, 1, 1)) {
                       
                        if(w.getNearbyEntities(spawnLoc, 1, 1, 1).isEmpty()) {
                            spawnSnowman(spawnLoc);
                            sender.sendMessage("Snowman spawned!");
                            break;
                        } else if(e.getEntityId() == 97) {
                            sender.sendMessage("Entity exists!");
                            break;
                          } else {
                              spawnSnowman(spawnLoc);
                              sender.sendMessage("Snowman spawned!");
                              break;
                            }

                    }
                    System.out.println("Loop is not working");
                   
                }
               

            return false;
        }
       
     
        static void spawnSnowman(Location lok) {
            LivingEntity snowman = (LivingEntity) Bukkit.getWorld("world").spawnEntity(lok, EntityType.SNOWMAN);
            snowman.setCustomName("ManSnow");
        }
     
    }
     
  15. Learn Java before trying to make Spigot plugins. Class names should be camel case (ClassName) and you probably shouldn’t name your plugin’s main class “Main” unless it’s the main class of an application (which it isn’t.)

    You don’t need to check the command alias being ran unless multiple commands have that same class as its executor (which you should never do and isn’t the case).

    Otherwise, your for loop doesn’t make sense. Say v is the list of nearby entities. If v is empty, that for loop will never even run.

    It’s best to use Entity#getEntityType instead of comparing entity type ID’s. Which, by the way, you’re comparing the entity’s ID (which is unique to each entity), not its type ID.