Solved ScheduleSyncRepeatingTask Loop Problem

Discussion in 'Plugin Development' started by Chr0mosom3, Jan 15, 2019.

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

    Chr0mosom3

    Hi humans, need some help,

    I have looked all over the forums and I found nothing useful. I am trying to make a kind of cooldown thing for the player. So the first pick a kit, when they pick a kit (command in other class) the method public static void kit(Player player). In there, I have a ghast tear that when you right click it spawns block below you and when you left click it shoots an arrow, that also works perfectly well, the only problem I'm facing is the cooldown/stamina system.
    I have it so whenever the player rightclicks or leftclicks and the thing goes through (place block or shoot arrow) it takes away 3 levels of XP. The max you can have is 10 and every second you get one XP level, you start out with 6 tho to prevent /kit spam and crap.
    The problem is that in the .scheaduleSyncRepeatingTask thing I looped it to run whenever the player has a kit selected (Main.kitactive btw) and has less than 10 levels of XP it gives them 1 every second but that just freezes the server and lags it out, I need a better alternative, any help?

    Code:
    package kits;
    
    import java.util.ArrayList;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.entity.Arrow;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    import main.Main;
    
    public class Falcon implements Listener {
       
        // Method to wait
        public static void wait(int sec, Player player)
        {
            Main.getPlugin().getServer().getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new Runnable() {
                 public void run() {
                     player.setLevel(player.getLevel() + 1);
                    
                 }
            }, 20, 0);
        }
       
        // Method to create Kit
        public static void createDisplay(Material material, Inventory inv, int Slot, String name, String lore)
        {
            ItemStack item = new ItemStack(material);
            ItemMeta meta = item.getItemMeta();
            meta.setDisplayName(name);
            ArrayList<String> Lore = new ArrayList<String>();
            Lore.add(lore);
            meta.setLore(Lore);
            item.setItemMeta(meta);
            
            inv.setItem(Slot, item);
        }
       
        // The Kit itself
        public static void kit(Player player)
        {
            Inventory InvPlayer = player.getInventory();
                   
            InvPlayer.clear();
            createDisplay(Material.IRON_SWORD, InvPlayer, 0, ChatColor.YELLOW + "" + ChatColor.BOLD + "Lighting Rod", ChatColor.DARK_PURPLE + "Just your plain old Lighting rod");
            createDisplay(Material.GHAST_TEAR, InvPlayer, 1, ChatColor.AQUA + "" + ChatColor.BOLD + "Raindrop", ChatColor.DARK_PURPLE + "Left click to shoot arrow, Right click to place block under your feet");
            createDisplay(Material.GOLDEN_APPLE, InvPlayer, 3, ChatColor.GOLD + "" + ChatColor.BOLD + "Uncooked Flappy Bird", ChatColor.DARK_PURPLE + "Legend says he fell down and died, I think it's true");
           
            player.setLevel(6);
           
            Main.kitactive.add(player);
            while (Main.kitactive.contains(player))
            {
                if (!(player.getLevel() >= 10))
                {
                    wait(1, player);
                }
            }
           
           
        }
       
        // Left Click Ghast Tear
        @EventHandler
        public void onInteractLeft(PlayerInteractEvent event) {
            if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK)
            {
                Player player = event.getPlayer();
                Location loc = player.getLocation();
               
               
                if (player.getItemInHand().getType() == Material.GHAST_TEAR && player.getLevel() > 3)
                {
                   
                    loc.add(0, 1, 0); //Add 1 to the Y, makes the arrow go at chest level instead of feet
                   
                    //Spawns Entity
                    Arrow arrow = player.getWorld().spawnArrow(loc, player.getLocation().getDirection(), 4f, 2f);
                    arrow.setShooter(player);
                    player.setLevel(player.getLevel() - 3); // Stamina
                   
                }
            }
        }
    
        // Right Click Ghast Tear
        @EventHandler
        public void onInteractRight(PlayerInteractEvent event) {
            if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)
            {
                Player player = event.getPlayer();
                Location loc = player.getLocation();
                Location block = loc.add(0, -1, 0);
               
                if (player.getItemInHand().getType() == Material.GHAST_TEAR && loc.getBlock().getType() == Material.AIR && player.getLevel() >= 3)
                {
                    player.setLevel(player.getLevel() - 3); // Stamina
                    block.getBlock().setType(Material.GLOWSTONE);
                        Main.getPlugin().getServer().getScheduler().scheduleSyncDelayedTask(Main.getPlugin(), new Runnable() {
                             public void run() {
                                 block.getBlock().setType(Material.AIR);
                                
                             }
                        }, (2 * 20));
                   
                   
                }
            }
        }
    }
     
  2. @MrDaniel

    What is this for?
    Code:
    while (Main.kitactive.contains(player))
            {
                if (!(player.getLevel() >= 10))
                {
                    wait(1, player);
                }
            }
    It looks like an endless loop that keeps creating tasks that should be fired every second.
     
  3. Offline

    Chr0mosom3

    That is to keep giving the player +1 level every second until he has 10 levels or more or he dies.

    EDIT: I changed it to if(player.getLevel() >=10)) so it isn't an infinite loop but didn't change anything.
     
    Last edited: Jan 16, 2019
  4. Offline

    timtower Administrator Administrator Moderator

    Don't use a while loop, it will lock the server, it will start a runnable, check again but nothing changed, so it repeats. Till you forcefully close the server.

    Why not a single runnable (started in the onEnable) that does the work of this?
     
    Chr0mosom3 likes this.
  5. Offline

    Chr0mosom3

    So what should I change, make a while loop in the onEnable method? I know that that is the problem and I am asking for alternatives, do you know any?
     
  6. Offline

    timtower Administrator Administrator Moderator

    No while loops.
    In the onEnable you make a timer.
    Inside that time you loop over the players.
    If the player is in the list increase the level count.
     
  7. Offline

    Chr0mosom3

    Timer? Do you mean scheduler? If not then how do you do a timer?
     
  8. Offline

    timtower Administrator Administrator Moderator

    BukkitRunnable that runs with runTaskTimer
     
Thread Status:
Not open for further replies.

Share This Page