1.12.2 Block Radius Not Working

Discussion in 'Spigot Plugin Development' started by xUbalubex, Feb 18, 2020.

  1. Hello! I am currently trying to check if the player is in a radius of a location. If so, then it will start a timer for 3 seconds and if they move, this timer is cancelled. I attempted to do this but it is just not working. Help would be greatly appreciated!

    Code (Java):
    @SuppressWarnings("deprecation")
        @EventHandler
        public void checkIfNearEvacZone(PlayerMoveEvent e)
        {
            Title title = new Title();
            if(inGameUsers.containsKey(e.getPlayer()))
            {
                //Bunker
                if(bunkerTime != 0)
                {
                    if(e.getPlayer().getLocation().distance((Location) getConfig().get("BunkerExitPoint")) <= 3 && !UsersBeingEvacced.containsKey(e.getPlayer()))
                    {
                       
                        int taskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BukkitRunnable() {
                            int seconds = 3;
                            @Override
                            public void run() {
                                if(seconds != 0)
                                {
                                    seconds--;
                                    title.sendTitle(e.getPlayer(), ChatColor.AQUA + "Evac Point Reched!", seconds + " Remaining...", 20, 20, 20);
                                }
                                else
                                {
                                    cancelEvacTime(e.getPlayer());
                                }
                            }
                        }, 0L, 20);
                        UsersBeingEvacced.put(e.getPlayer(), taskId);
                       
                    }
                    else
                    {
                        if(UsersBeingEvacced.keySet().contains(e.getPlayer()) && UsersBeingEvacced.get(e.getPlayer()) != null)
                        {
                            UsersBeingEvacced.put(e.getPlayer(), null);
                            cancelEvacTime(e.getPlayer());
                        }
                    }
                }
                else
                {
                    if(roofTopTime != 0)
                    {
                        if(e.getPlayer().getLocation().distance((Location) getConfig().get("BunkerExitPoint")) <= 3 && !UsersBeingEvacced.containsKey(e.getPlayer()))
                        {
                            int taskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BukkitRunnable() {
                                int seconds = 3;
                                @Override
                                public void run() {
                                    if(seconds != 0)
                                    {
                                        seconds--;
                                        title.sendTitle(e.getPlayer(), ChatColor.AQUA + "Evac Point Reched!", seconds + " Remaining...", 20, 20, 20);
                                    }
                                    else
                                    {
                                        cancelEvacTime(e.getPlayer());
                                    }
                                }
                            }, 0L, 20);
                            UsersBeingEvacced.put(e.getPlayer(), taskId);
                        }
                        else
                        {
                            if(UsersBeingEvacced.keySet().contains(e.getPlayer()) && UsersBeingEvacced.get(e.getPlayer()) != null)
                            {
                                UsersBeingEvacced.put(e.getPlayer(), null);
                                cancelEvacTime(e.getPlayer());
                            }
                        }
                    }
                    else
                    {
                        if(DocksTime != 0)
                        {
                            if(e.getPlayer().getLocation().distance((Location) getConfig().get("DockExitPoint")) <= 3 && !UsersBeingEvacced.containsKey(e.getPlayer()))
                            {
                                int taskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BukkitRunnable() {
                                    int seconds = 3;
                                    @Override
                                    public void run() {
                                        if(seconds != 0)
                                        {
                                            seconds--;
                                            title.sendTitle(e.getPlayer(), ChatColor.AQUA + "Evac Point Reched!", seconds + " Remaining...", 20, 20, 20);
                                        }
                                        else
                                        {
                                            cancelEvacTime(e.getPlayer());
                                        }
                                    }
                                }, 0L, 20);
                                UsersBeingEvacced.put(e.getPlayer(), taskId);
                            }
                            else
                            {
                                if(UsersBeingEvacced.keySet().contains(e.getPlayer()) && UsersBeingEvacced.get(e.getPlayer()) != null)
                                {
                                    UsersBeingEvacced.put(e.getPlayer(), null);
                                    cancelEvacTime(e.getPlayer());
                                }
                            }
                        }
                    }
                }
               
            }
        }
     
  2. First, quick tip: the PlayerMoveEvent will fire almost constantly whenever your player moves, sometimes even when just standing still and looking around. To avoid slowing down the server, make the following change to your code:
    Code (Java):
    public void checkIfNearEvacZone(PlayerMoveEvent e)
    {    
        if (evt.getFrom().getBlock().equals(evt.getTo().getBlock()))
        {
            return;
        }
        Title title = new Title();
        ...
    This will ensure the code is only run when entering/exiting a new block. I would also encourage you to change the `inGameUsers` Map to use UUIDs instead of Player objects (accessible from Player#getUUID). This is for performance as well as the fact that player information can change after placement into the Map (username change, inventory, etc.).

    Now, I don't see anything wrong with your code at a glance, so I'd check whether the if statements are returning as expected and whether the config Location is correct. Drop in some console output to get an idea of where the code is stopping at. As a side note, you've also spelled "Reached" wrong.
     
  3. So it turns out im an idiot and I never registered events. But I still have an issue. How do I stop a runnable?

    I currently have this now:
    Code (Java):
    final int taskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BukkitRunnable() {
                            int seconds = 3;
                            @Override
                            public void run() {
                                if(seconds != 0)
                                {
                                    seconds--;
                                    title.sendTitle(e.getPlayer(), ChatColor.AQUA + "Evac Point Reached!", seconds + " Remaining...", 20, 20, 20);
                                }
                                else
                                {
                                    e.getPlayer().sendMessage(ChatColor.GREEN + "WIN!");
                                    cancelEvacTime(e.getPlayer());
                                    playerEvacuate(e.getPlayer());
                                }
                            }
                        }, 0L, 20);
                        UsersBeingEvacced.put(e.getPlayer().getUniqueId(), taskId);
    This code is located where it checks if you are within the evac radius.

    The two methods under the WIN text are:
    Code (Java):
    public void cancelEvacTime(Player p)
        {
            Bukkit.getServer().getScheduler().cancelTask(UsersBeingEvacced.get(p.getUniqueId()));
            UsersBeingEvacced.remove(p.getUniqueId());
        }
       
        public void playerEvacuate(Player p)
        {
            inGameUsers.remove(p);
            p.teleport((Location)getConfig().get("Lobby"));
        }
    Whenever I cancel the task in cancelEvacTime, it cancels the main task that runs my game timer.
     
  4. why are you doing it that way? bukkitrunnables can self cancel.. just call #cancel inside the runnable. no need to track all of this
     
  5. I actually tried this but all it does is it will keep running the code where it stop the runnable and everything.


    Code (Java):
    final int taskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BukkitRunnable() {
                            int seconds = 3;
                            @Override
                            public void run() {
                                if(seconds != 0)
                                {
                                    seconds--;
                                    title.sendTitle(e.getPlayer(), ChatColor.AQUA + "Evac Point Reched!", seconds + " Remaining...", 20, 20, 20);
                                }
                                else
                                {
                                    //The code below runs over and over again infinitely
                                    e.getPlayer().sendMessage(ChatColor.GREEN + "WIN!");
                                    UsersBeingEvacced.remove(e.getPlayer().getUniqueId());
                                    playerEvacuate(e.getPlayer());
                                    this.cancel();
                                }
                            }
                        }, 0L, 20);
                        UsersBeingEvacced.put(e.getPlayer().getUniqueId(), taskId);
     
  6. because you're using the outdated way of creating a bukkitrunnable
    https://hub.spigotmc.org/javadocs/s...rg.bukkit.scheduler.BukkitRunnable-long-long-
    use the suggested method. BukkitRunnable#runTaskTimer

    /e secondly, dont use #distance in a method thats called so often. #distance uses the heavy square root function. use #distanceSquared and manually square your distance (3 would be 9). achieves the same result with significantly better performance
     
  7. Code (Java):
    Bukkit.getServer().getScheduler().runTaskTimer(this, new BukkitRunnable() {
                            int seconds = 3;
                            @Override
                            public void run() {
                                if(seconds != 0)
                                {
                                    seconds--;
                                    title.sendTitle(e.getPlayer(), ChatColor.AQUA + "Evac Point Reached!", seconds + " Remaining...", 20, 20, 20);
                                }
                                else
                                {
                                    e.getPlayer().sendMessage(ChatColor.GREEN + "WIN!");
                                    playerEvacuate(e.getPlayer());
                                    this.cancel();
                                }
                            }
                        }, 0, 20);
    This still does not work, it just loops over and over again.
     
  8. That was what I was following. Im confused on how they use it. Is it used as a variable because it seems like it. Or is that just a method dedicated to that task? The spigot documentation isn't very clear to me.
     
  9. Code (Java):
    new BukkitRunnable() {
        ...
    }.runTaskLater(plugin, delay, interval);
     
  10. It can be used as a variable, in order to save the task ID for cancelling at a later time:
    Code (Java):
    int taskID = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
      ...
    }, delay, interval);
    However, that isn't necessary in your case, as Warren1001 has pointed out.
     
    #11 PikaMug, Feb 19, 2020
    Last edited: Feb 19, 2020
  11. no.. because bukkittask, the proper way of handling bukkitrunnables, stores its own task id that you can cancel. using any sort of integer task id is deprecated.
    this is what you do:
    BukkitTask task = new BukkitRunnable() {
    ....
    }.runTaskWhatever(plugin, ...);
    then you store the task if you'd like and call task#cancel, or use #cancel inside the runnable if you want to self cancel a task
     
  12. This worked perfectly! Thanks!!