Timed If Statement?

Discussion in 'Spigot Plugin Development' started by Surprisejedi, Jun 6, 2017.

  1. I know, this is probably a "Very Basic & Important step of Java that I should've learned before coming here" and people are going to tell me "Go learn Java before you start coding". I have a basic understanding of Java, that combined with trial and error. I don't use textbooks/tutorials. I learn from my mistakes. Anyway,

    Is it possible to make a "Timed" if statement?
    Like this fake example?
    Code (Text):
    boolean timedIf;
    if(timedIf = true "for 5 seconds") {

    //run code

    }
     
  2. Make a method called timedFiveSeconds and make it return a boolean value, inside it out a runnable for 5 seconds then make it return true.
     
  3. electronicboy

    IRC Staff

    time if statement implies that you're lacking understanding of control flow... but, beyond that, if you wanna "time" something, use a for statement and a sleep or something. If you're talking bukkit, use the scheduler, sleeping should only be done in async tasks, not on the main thread!
     
  4. Not really. You can schedule a repeating task (using BukkitScheduler) to run for 5 x 20 ticks, check some condition every one of those ticks, then at the end do something if condition was true all the way through.
     
  5. That's not exactly what I want. I want to check if a player is above ground for more than 5 seconds using this:
    Code (Java):
        @EventHandler
        public void isFlying(PlayerMoveEvent e) {
            Player player = (Player) e.getPlayer();
            if (player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR (For more than 5 seconds)) {
                player.sendMessage(ChatColor.RED + "Are you Flying?");
            }
        }
     
  6. Could have a hashmap <STRING, INT> - then for every tick you set the int ++ if they're above ground, if they aren't set it to zero then if it gets to 5 (or 100) then do the message thing?

    Might also need to have a check to remove anyone who's gone offline
     
  7. Hey,

    you could save the current time millis on the player move event.
    Then you check in every MoveEvent if the player is above ground.
    If that's true and current time millis - before saved time millis is bigger than 5000 then you can send the message :)
    If it's false, reset the saved time millis

    I hope I could help you :)
     
  8. electronicboy

    IRC Staff

    use a hashmap for the player and an integer, if they're not in a state that you want to time them, remove them from the hashmap, if they are, get their entry from the hashmap, if it's null, set it to 1, otherwise increment it (and check it) and shove it back. if your check shows that they're above the interval you wanna check, then do what you wanna do
     
  9. The fact you are asking this question at all shows you need to stop learning by copy-paste and follow some tutorials. It will save you so much time and improve your code massively.

    If you continue down this path, you will never be able to make any original, functional code and will waste a ton of time having to unlearn bad habits.
     
    • Like Like x 1
  10. But unfortunately about 70%(in my opinion) of the bukkit/spigot coders only copy and paste code :/
     
  11. I don't copy and paste. I don't know how you could conclude that from my posts anyway. I have an understanding of Java, and I LEARN from other people's posts. I don't copy them.
     
  12. But you should know how to code that. If you know what an HashMap is or how to work with times.
    If you really know as you say, how to code in Java, you should think more about your projects before you code them ^^

    And that's only an advise ;)
     
  13. Here is what you will want:

    Code (Text):
    @EventHandler
        public void isFlying(PlayerMoveEvent e) {
            Player player = (Player) e.getPlayer();
            long time = 0;
            if (player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR {
                time = System.currentTimeMillis();
                if ((System.currentTimeMillis() - Time) > 5000L) {
                    time = 0;
                    player.sendMessage(ChatColor.RED + "Are you Flying?");
                }
            }
        }
    Here's an explanation for what this does. It simply just sets the timer (hence changes the time value) and it checks if 5000 milliseconds have passed. If 5000 milliseconds (or 5 seconds) have passed, then it will send the message.
     
    #13 funkemunky, Jun 6, 2017
    Last edited: Jun 6, 2017
    • Like Like x 1
  14. How should that work?
    You need a HashMap<String,Long> or HashMap<Player,Long> to save the timestamp.
    You only set the "long time" as the current time millis, which is always bigger than 5000L
     
  15. You must be a novice at Java development. No, you do not need a HashMap. The Listener's values within the statement will always be unique to the call.

    I ammended my code
     
    • Funny Funny x 1
  16. Sorry, but I think you are a novice ^^
    Even your if statement
    Code (Text):
    if (time = (System.currentTimeMillis() - 5000L)) {
    does not work
    It is
    Code (Text):
    if (time == (System.currentTimeMillis() - 5000L)) {
    Here is what you need:
    Code (Text):
    public class MoveListener implements Listener {
     
        private HashMap<String, Long> times = new HashMap<>();
     
        @EventHandler
        public void onMoveEvent(PlayerMoveEvent event) {
            Player player = event.getPlayer();
            if(player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) {
                long currentTime = System.currentTimeMillis(); //Current time
                long timeBefore;
                if(times.containsKey(player.getName())) {
                    timeBefore = times.get(player.getName()); //Time when he was the first time in the air and not came to the ground
                }else{
                    times.put(player.getName(), currentTime);
                    timeBefore = System.currentTimeMillis();
                }
             
                if(currentTime - timeBefore >= 5000L) {
                    //TODO He flies since more than 5 seconds
                }
            }else{
                //We need to remove the player because he is no longer in the air
                if(times.containsKey(player.getName())) {
                    times.remove(player.getName());
                }
            }
        }
     
    }
     
  17. Sorry you are right, I screwed up my shit. One minor error that can be found in an IDE :)

    Also you do not need a HashMap. It is useless and unneeded if you don't need to call for values elsewhere. Even then, you can just do something like this if you want to.

    Code (Text):
    public class RandomClass {

       public boolean time;

       public RandomClass() {
           this.time = 0;
       }
    }
    And it would still work.
     
    #17 funkemunky, Jun 6, 2017
    Last edited: Jun 6, 2017
    • Agree Agree x 1
  18. This thread proves you do not have the understanding you think you have, on top of no idea how program control flow works. This is going to make it impossible for you to write anything beyond simple scripts.

    Being new is not bad, everyone started somewhere; but refusing to admit that you know next to nothing while making it clear that you know next to nothing is just going to hurt you and cause people to not take you seriously.

    Just find a good tutorial or textbook, it will make everything far easier and faster.

    (Incidentally this is most of why i despise lambdas and messy callback systems, it prevents new programmers from ever learning how flow actually works, crippling them for eternity)
     
    • Agree Agree x 1
  19. Code (Text):

    player move event
      if player is flying/block under is air
         new runnable that runs every second (20 ticks)
            if player isnt in hashmap <string (player name), integer> -> add them
            if int in hashmap = 5 {
               do stuff
                cancel runnable
            }
            get int from hashmap and add one
     
    Edit: actually this can be down without a runnable im dumb, check @illoTech
     
    • Funny Funny x 1
  20. I'm self-taught. After learning from tutorials and then going through the JavaDocs I worked in teams, I got a lot of background and new knowledge. I'm currently working on the Shotbow Civ-War team.
     
    • Informative Informative x 1