Enderpearl cooldown with xp bar

Discussion in 'Programming' started by HK_Sushi, Jan 29, 2018.

  1. Code (Text):
    package me.samsoon;

    import java.util.ArrayList;

    import org.bukkit.GameMode;
    import org.bukkit.Material;
    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.ItemStack;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.scheduler.BukkitRunnable;

    public class cooldown implements Listener{

        ArrayList<Player> cooldown = new ArrayList<Player>();
       
        @EventHandler
        public void EnderPearl(PlayerInteractEvent e) {
            final Player p = e.getPlayer();
            ItemStack pearl = new ItemStack(Material.ENDER_PEARL);
            if(p.getGameMode() == GameMode.SURVIVAL) {
                if(p.getInventory().getItemInHand() == pearl) {
                    if(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
                        cooldown.add(p);
                         if(p instanceof Player) {
                             int time = 16;
                             new BukkitRunnable() {

                                @Override
                                public void run() {
                                    int countdown = time;
                                    if(countdown <= 0) {
                                        p.setExp(0f);
                                        cooldown.remove(p);
                                        this.cancel();
                                        return;
                                    }
                                    p.setExp(1f * (countdown/time));
                                    countdown --;              
                                }
                               
                             }.runTaskTimer((Plugin) this, 0L, 1L);
                         }
                            }
                        }
                    }
                }
    }
     
  2. If I want to add a level count down.
    Should I do
    Code (Text):
    If(countdown <= 0){
    p.setLevel(0);

     
    And then above countdown --; add
    Code (Text):
    p.setLevel(countdown);
     
  3. It should be okay (and yeah, you got it right for adding a level countdown)
    However, a few things you could improve:

    "if(p.getInventory().getItemInHand() == pearl)" This won't work (at least for customized enderpearls) because it is checking for the same instance of enderpearl as the new one you're defining above, you should do something like this instead:
    "if (e.getItem() != null && e.getItem().getType() == Material.ENDER_PEARL)" (Checking if item isn't null, and if it's an enderpearl)

    "if(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)"
    I tend to merge these two into a single condition check, but I don't know if this is a better way or not. Still makes something more "readable" at least :p
    "if (e.getAction().name().contains("RIGHT_CLICK"))"
     
  4. I will still use the p.getaction first cuz I want the plugin work first
     
  5. Ok I followed your suggestions and now I'm testing :)
     
  6. ".runTaskTimer((Plugin) this, 0L, 1L);"

    Why would you cast your Listener class as your main class when it isn't?
     
  7. So what how can I change this ?
    @Arektor
     
  8. I make it to
    Code (Text):
    .runTaskTimer(new main(), 0L , 1L);
    Is that right
    @Arektor
     
  9. 1. Why do you let players execute commands? Why don't you use a method like:
    Code (Text):
    public void putCooldown(Player target, int cooldown) {
    // Put 'target' in cooldown ArrayList.
    // Send optional message?
    }
    2. You're using action string to compare the actions. Just don't... don't do that. Use this to compare instead:
    Code (Text):
    if (event.getAction == Action.RIGHT_CLICK_BLOCK) {
    // Action 'right-click block' triggered.
    }
    3. Checking for game mode survival is kinda useless since creative players can't use ender pearls. But that's your option.
    4. I see you've added an 'instance of' check, why would you do that to check a player? Doesn't something bother you about the event?
    Code (Text):
    PlayerInteractEvent
    It clearly says PlayerInteractEvent, which is being triggered when a player interacts with something.
    5. You're not checking if the ArrayList contains the player, this will result in no cooldown and just a lot of player clones in the ArrayList. Use this:
    Code (Text):
    if (!arraylist.contains(player)) {
    // Put the player in the cooldown ArrayList.
    } else {
    // Send cooldown message and cancel the event.
    }
    6. To have a working runnable task, you need a working main class instance. Use this:
    Code (Text):
    public static JavaPlugin instance;

    public void onEnable() {
    instance = this;
    }


    There are a lot of things wrong with your code, since you're a beginner I recommend you to learn good Java coding practices first, since that is very important to have a good working plugin. If I've done something wrong, please tell me it. I'll edit it then.
     
    • Winner Winner x 1
  10. Your code is still bad and won't work.
     
  11. MiniDigger

    Supporter

  12. @MiniDigger it's bEcUz I want to make my server enderpearl cokcoold like some big network
     
  13. @Marido how about this
    Code (Text):
    package me.samsoon.xp;

    import java.util.HashMap;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Projectile;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.ProjectileLaunchEvent;

    public class Cooldown implements Listener{

        public HashMap<String , Long> cooldown = new HashMap<String , Long>();

        int second = 16;
        int cd = second;

        @SuppressWarnings("deprecation")
        @EventHandler
        public void Throw(ProjectileLaunchEvent e) {
            Projectile pro = e.getEntity();
            if(pro.getShooter() instanceof Player) {
                if(pro.getType() == EntityType.ENDER_PEARL) {
                    Player p = (Player) pro.getShooter();
                    if(cooldown.containsKey(p.getName())) {
                        long timer = (cooldown.get(p.getName()) / 1000 + second) - System.currentTimeMillis() / 1000;
                        if(!(timer < 0)) {
                            e.setCancelled(true);
                            p.sendMessage(ChatColor.RED + "You cannot use this yet!");
                            p.setLevel(cd);
                            p.setExp(1f * (cd /second));
                        }else {
                            e.setCancelled(false);
                            cooldown.remove(p.getName());
                            p.sendMessage(ChatColor.GREEN + "You can throw ender pearl now!");
                            p.setExp(0f);
                            p.setLevel(0);
                        }
                    }else {
                        cooldown.put(p.getName(), System.currentTimeMillis());

                    }

                }

            }Bukkit.getScheduler().scheduleSyncRepeatingTask(new Main(), new Runnable() {
                public void run() {
                    cd --;
                }
            }, 0L, 20);
        }


    }
     
     
  14. Didn't took time to really read this but this only is going to update the exp bar when the player will try to use the enderpearl while its on cooldown.
     
  15. Then how can I make to make it to counting down once they use it @Arektor
     
  16. DavidDevelops

    Supporter

    Use a runnable until the cooldown count reaches the end?
     
  17. I don't think I should becuz there is a HashMap
    And if the Stine is euqps to zero or small than zero
    Player will be removed