Filled [PLEASE, NEED HELP] XP Bar become Loading Bar

Discussion in 'Archived: Plugin Requests' started by electrobricks, May 30, 2013.

  1. Offline

    electrobricks

    So I need your guys help. Please make a plugin or code where:
    • the XP Bar is used for a loading bar instead,
    • the XP Bar is used on multiple things so it needs to send the time per XP increase has to be sent to the class/method, (Ex. Loading bar takes 10 seconds to fill up in order to use the egg grenade again.)
    • Do not allow multiple requests at a time,
    • Acts like a cooldown,
    • most efficient possible way for the above,
    Also, I have looked if this was ever asked before and I couldn't find anything. Anyways, do mind spending a little time helping me??

    Thanks,
    Electrobricks
     
  2. Offline

    timtower Administrator Administrator Moderator

    electrobricks If you want then then you also need plugins that hook into this one to use it as an cooldown bar
     
  3. Offline

    electrobricks

    timtower Not exactly. I was just going to use it in a plugin. But it could be a separate one... (Separate Plugin)
     
  4. Offline

    bigteddy98

    You could simply disable enchanting and earning xpe, and use player.setLevel(your number); to let it look like a loading bar.
     
  5. Offline

    electrobricks

    bigteddy98 It would be actually player.setXP(NUMBER) in a repeating task, which I have already made:
    Code:
        public void cooldownRequest(Plugin thisPlugin, final Player sender, long cooldownTimePerXP){
            boolean finished;
         
            new BukkitRunnable(){
                @Override
                public void run(){
                    float exp = sender.getExp();
                    float maxExp = 1.0F;
                    float expToAdd = 0.01F;
                 
                    if(exp + expToAdd <= maxExp){
                        sender.setExp(exp + expToAdd);
                    }
                }
            } .runTaskTimer(thisPlugin, 1L, cooldownTimePerXP);
        }
    ....but isn't doing points 3 and 4, which I don't know how to do. Also prior to this being called I set their xp to zero....
     
  6. Offline

    timtower Administrator Administrator Moderator

    So you know java, you can make plugins and you don't post this in plugin development?
     
  7. Offline

    electrobricks

    CaptainWalrus I don't see how that is relevant. Anyways, I took a full year java class using the book called Java for programmers by Deitel...

    timtower I did and was advised to ask here...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  8. Offline

    timtower Administrator Administrator Moderator

    Weird...
     
  9. Offline

    electrobricks

    timtower I know... Anyways, could you make me a class (or method) to do points 3 and 4??
     
  10. Offline

    bigteddy98

    player.setLevel(player.getLevel() + number you want to add); is this where you are looking for? setXpe would be a possibility too, but then you have to calculate the xp for each level.
     
  11. Offline

    timtower Administrator Administrator Moderator

    If you can give me an step by step explanation of the class, then I might be able to write the complete thing
     
  12. Offline

    electrobricks

    Nope. And from level 1 - 17 its 18 xp per level I think...

    I will write one up. Look out for it.


    timtower Here it is:

    1. Method cooldownRequest takes player, cooldownInSeconds(IN SECONDS) then
    • acts like a cooldown meaning the xp bar has to be fill to use it again
    • Add a player to like say an array or hash set
    • make sure seconds entered is actually how many seconds the bar takes to fill (18 xp per level until 17 then it increases)
    2. Method already in cooldown
    • Returns true if the player is in the hash set
    • Returns false if the player isn't
    Thats it I think...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  13. Offline

    electrobricks

    timtower Did you receive my last post?
     
  14. Offline

    FunnyGopher

    Instead of a hash set for storing what player is in a cooldown, I use metadata. Give the player a cooldown metadata, run a separate task that's delayed for the amount of cooldown time, then the task removes the metadata. During that time if cooldown is initiated again, it just checks if the player has the metadata or not and runs accordingly.

    Oh, and player.getExp() actually returns a decimal from 0 - 1, 0 being the exp bar is empty and 1 being the exp bar is full. So it basically returns a percentage. So instead of worrying about how much exp it takes per level to fill the bar, just player.setExp() and give it a percentage based on time passed.

    Example:
    Starting off with an empty exp bar, if your cooldown is 10 seconds, then every second you want to increase the exp bar by 10%, or (1/10).
    Code:
    player.setExp(player.getExp() + (1F/10))
    But that would look gross because it wouldn't be one fluid motion, it would just increase every second and look really choppy. Since each second is 20 ticks, and your cooldown is 10 seconds, you actually need to split the exp bar into 200 pieces to fill it up equally for 200 ticks. So your code looks like this:
    Code:
    player.setExp(player.getExp() + (1F/(10 * 20)))
    The 10 in the code can be replaced by a config call. You would want to run this in a repeating task that repeats every tick with no delay. Or, to make the exp bar empty itself, you initially player.setExp(1) and then instead of adding you would subtract.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  15. And you should also learn that this is the REQUEST section not the Lrn2DuJava section. Next time you should read what a requesting section is compared to a learn it yourself section.
     
  16. Offline

    FunnyGopher

    Code:
    public class Cooldown implements Runnable {
     
        private int cooldownTime;
        private Player player;
     
        public Cooldown(int time, Player player) {
            cooldownTime = time;
            this.player = player;
        }
     
        @Override
        public void run() {
            if(player.getExp() < 1) { //To make sure bar stops once its full, otherwise it keeps going.
                player.setExp(player.getExp() + (1F/(cooldownTime*20))); //Sets the exp bar
                int currLvl = (int) (player.getExp()/(1F/(cooldownTime))); //Determines past seconds
                if(player.getLevel() !=(cooldownTime - currLvl)) {
                    player.setLevel(cooldownTime - currLvl); //Sets level to seconds left before cooldown is over
                }
            }
        }
    }
    
    Here, I know I just explained it, but this will do the exp bar animation. You pass in a cooldown time in seconds and a player. It will fill the exp bar up and count down. If you don't want it to countdown, remove the int currLevel and the last if statement.
     
  17. Offline

    timtower Administrator Administrator Moderator

    electrobricks I assume that you will be able to use the code FunnyGopher provided, if not, then I will create something for you
     
  18. Offline

    electrobricks

    FunnyGopher

    It isn't working...
     
  19. Offline

    FunnyGopher

    electrobricks Haha, nice one. It is working, I'm using the exact same code in my plugin. Show the code where you're running it and I can help you a lot more than if you just tell me, "It isn't working".
     
  20. Offline

    electrobricks

    FunnyGopher Here is my main class:

    Code:
    public class mainclass extends JavaPlugin implements Listener {
      ....
        @EventHandler
        public void onPlayerToggleSneakEvent(PlayerToggleSneakEvent event) {
            final Player player = event.getPlayer();
            if (player.isSneaking()) {
                if(!(player.getExp() == 0F) || (!(player.getExp() == 1F))) {
                    event.setCancelled(true);
                    player.setSneaking(false);
                    this.newCooldown.newStandardCooldown(sender, plugin, 7);
                }
            }
            
        }
    and my cooldown class:

    Code:
    package com.gmail.amclose97;
     
    import java.util.HashSet;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.scheduler.BukkitRunnable;
     
    public class Cooldown {
       
        public void newStandardCooldown(Player player, Plugin plugin, long cooldownDelay) {
            runStandardCooldown(player, plugin, cooldownDelay);
        }
       
       
       
        private void runStandardCooldown(final Player player, Plugin plugin, long cooldownDelay) {
                new BukkitRunnable() {
                    @Override
                    public void run() {
                        if((player.getExp() == 0F) || (!(player.getExp() == 1F))) {
                            player.setExp(player.getExp() + (1F/(10*20)));
                        } else {
                            player.setExp(0F);
                            cancel();
                        }
                    }
                } .runTaskTimer(plugin, cooldownDelay, 10L);
            }
    }
     
  21. Offline

    Beatlynx

    Why not just install a plugin that uses this feature? It would be much easier.
     
  22. Offline

    electrobricks

  23. Offline

    timtower Administrator Administrator Moderator

    I assume that the cooldown list is an static object so you can change it from anywhere?
     
  24. Offline

    FunnyGopher

    Okay, so... there are a couple problems with your class. You were definitely close.
    1) First problem, your first method is redundant.

    Code:
    public void newStandardCooldown(Player player, Plugin plugin, long cooldownDelay) {
    runStandardCooldown(player, plugin, cooldownDelay);
    }
    

    All this method is doing is running the second method. You can safely delete the first method, and still run the second method. But not before...

    2) Because this is just a function method that your passing parameters, you can make the second method (which is now the first method because you deleted the first one)
    Code:
    public static void runStandardCooldown(parameters)
    To call this method anywhere in your code, you would just
    Code:
    Cooldown.runStandardCooldown(parameters) {
    3) Change the 10L you have in runTaskTimer() to 1L. This parameter is saying the task should run again after x amount of ticks. Since you had 10L, it probably wouldn't look right.

    I know I've said this much, but I just realized your method call wasn't even correct. I don't have the patience to teach you Java right now. You were close, I'll give you that. I'll post what I believe the best way to code this is and you compare yours with mine, and try to figure out why I did what I did. If you have any question about something I did or why I did it, go ahead and ask. I'm glad to help, I'm just not writing a tutorial.

    Main class
    Code:
    public class mainclass extends JavaPlugin implements Listener {
      ....
        @EventHandler
        public void onPlayerToggleSneakEvent(PlayerToggleSneakEvent event) {
            final Player player = event.getPlayer();
            if (player.isSneaking()) {
                if(!(player.getExp() == 0F) || (!(player.getExp() == 1F))) {
                    event.setCancelled(true);
                    player.setSneaking(false);
                    Cooldown.runStandardCooldown(player, plugin, 7);
                }
            }
           
        }
    
    Cooldown Class
    Code:
    public class Cooldown { 
     
        public static void runStandardCooldown(final Player player, Plugin plugin, long cooldownDelay) {
                new BukkitRunnable() {
                    @Override
                    public void run() {
                        if(!(player.getExp() == 1F)) {
                            player.setExp(player.getExp() + (1F/(10*20)));
                        } else {
                            player.setExp(0F);
                            cancel();
                        }
                    }
                } .runTaskTimer(plugin, cooldownDelay, 1L);
            }
    }
     
  25. Offline

    electrobricks

    FunnyGopher So the problem really from the beginning (your code still has the bug) is that you can send multiple requests so much so the the xp bar fills up fast and creates another xp bar. And thats not what I want. At this current moment in time I still can't solve that. I have tried a lot of things. Do you have a suggestion to eliminate this bug?
     
  26. Offline

    FunnyGopher

    electrobricks
    Try this, it won't fix the bug, just in general programming. Instead of doing if(!(something == somethingelse)), do if(something != somethingelse). It's the same thing but uses less parenthesis, which means less parenthesis to get confused by. Also, your if logic in the togglesneakevent says if exp doesn't equal 0 or doesn't equal 1, run the cooldown. So unless you start out with some of the bar full, you're not going to get anywhere because of the if exp doesn't equal 0. Just letting you know.

    Okay, so this is how it's supposed to work.
    Hold down shift, bar fills up slowly over a 10 second period. At 10 seconds, the bar is full and stops. Let go of shift, bar empties itself.

    The way the code above runs:
    If you hold shift and you have some xp, it waits 7 ticks then fills up slowly over a 10 second period. Once it's full, it goes back down to 0. Because you have it going back to 0 here:
    Code:
    @Override
                    public void run() {
                        if(!(player.getExp() == 1F)) { //This sees exp is full
                            player.setExp(player.getExp() + (1F/(10*20)));
                        } else { //Goes to else
                            player.setExp(0F); //Here it goes back to 0
                            cancel();
                        }
                    }
    
    The if statement above starts over.
    Code:
    @Override
                    public void run() {
                        if(!(player.getExp() == 1F)) { //This sees its not 1
                            player.setExp(player.getExp() + (1F/(10*20))); //Starts over
                        } else { //Get rid of this line
                            player.setExp(0F); //Get rid of this line
                            cancel(); //Get rid of this line
                        } //Get rid of this line
                    }
    
    There's a problem I've come across with canceling tasks inside themselves. You have to cancel them outside themselves. It's either a problem or I don't know enough about how they work to use them correctly. (Look at other post. I think I solved it.)

    So in the togglesneakevent, when isSneaking() = false, or when they let go of shift, you have to set exp to 0 and cancel the task. You can either save the BukkitTask (which is whats returned when running a BukkitRunnable) as metadata to the player and get it back when they un-shift, store the player and BukkitTask in a hashmap and get it from there when they unshift, or if your not running any other tasks, you can just Bukkit.getSchedular().cancelTasks(). The last one will cancel every task though. In my plugin, I just canceled all tasks, because the only thing the plugin did was run that one task.

    electrobricks
    Okay, just read a thread on how to cancel a plugin within itself. Your cooldown runnable needs to be it's own class.
    Code:
    public class Cooldown extends BukkitRunnable{
     
        private Player player;
     
        public Cooldown(Player argPlayer) {
            player = argPlayer;
        }
     
        public void run() {
            if(player.getExp() < 1F) {
                player.setExp(player.getExp() + (1F/(10*20)));
            } else {
                player.setExp(0F);
                this.cancel();
            }
        }
    }
    
    So this is the new Cooldown class. Now, I learned you can only cancel tasks within themselves if they schedule themselves. So this is how you call it from your togglesneakevent.
    Code:
    if (player.isSneaking()) {
        if(!(player.getExp() == 0F) || (!(player.getExp() == 1F))) {
            event.setCancelled(true);
            player.setSneaking(false);
            BukkitTask task = new Cooldown(player).runTaskTimer(plugin, delay, 1);
        }
    }
    
    I'm sorry. My class was actually a BukkitRunnable, not just a class with a static method. I feel bad for telling you wrong before. But thank you for making me learn how to cancel tasks within themselves. I was having problems with that. :)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  27. Offline

    electrobricks

    -- Message to FunnyGopher I finished it! Thanks so much for your hard work! --

    Anyone else out there can use this code. (BTW, Its has some modifications to FunnyGopher's code)

    Cooldown Manger Class:

    Code:
    ... //You know what goes here. If not, Learn Java...
     
    public static HashSet<String> cooldowns = new HashSet<String>();
     
    ...
     
        @EventHandler
        public void onPlayerToggleSneakEvent(PlayerToggleSneakEvent event) {
            final Player player = event.getPlayer();
            if (player.isSneaking()) {
                if(!(player.getExp() == 0F) || (!(player.getExp() == 1F))) {
                    if (cooldowns.contains(player.getDisplayName())) {
                        return;
                    }
                    event.setCancelled(true);
                    player.setSneaking(false);
                    BukkitTask task = new Cooldown(player).runTaskTimer(this, 2, 1);
                    cooldowns.add(player.getDisplayName());
                }
            }
        }
     
    ...// Do other stuff you need here and end the class. If you do not what this means, Learn Java...

    Cooldown Class:

    Code:
    package com.gmail.amclose97;
     
    import org.bukkit.entity.Player;
    import org.bukkit.scheduler.BukkitRunnable;
     
        public class Cooldown extends BukkitRunnable{
     
        private Player player;
     
        public Cooldown(Player argPlayer) {
            player = argPlayer;
        }
     
        public void run() {
            if(player.getExp() < 1F) {
                player.setExp(player.getExp() + (1F/(10*20)));
            } else {
                player.setExp(0F);
                mainclass.cooldowns.remove(player.getDisplayName());
                this.cancel();
            }
        }
    }
     
  28. Offline

    FunnyGopher

    Yay! Glad to see it working for you. :)
     

Share This Page