What's wrong with my Scheduler?

Discussion in 'Plugin Development' started by AcpSoldier, Oct 31, 2014.

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

    AcpSoldier

    EDIT: The error is at line 5

    If a player is in the water for 3 seconds, I want to send him a message saying that he's getting cold. Here's what I got.
    Code:java
    1. @EventHandler
    2. public void onPlayerMove(final PlayerMoveEvent e) {
    3. Material m = e.getPlayer().getLocation().getBlock().getType();
    4. if (m == Material.STATIONARY_WATER || m == Material.WATER) { // Checks if a player is in water.
    5. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask((Plugin) this, new Runnable() {
    6. public void run() {
    7. e.getPlayer().sendMessage("You are getting colder."); //For every 3 seconds the player is in water, send this message.
    8. }
    9. }, 20 * 3); // 20 = one second in ticks.
    10. }
    11. }

    For some reason, it never sends the message. What am I doing wrong? (It's not my event, because I've tested going in the water without the 3 second thing and it works fine.)

    I would really appreciate some more help!
    - Soldier
     
  2. Offline

    Gerov

    Why'd you cast 'this' to plugin on line 5?
     
  3. Offline

    Relicum

    Your issue is your not recording if they have already have a scheduler for the player. Think about it player moves in water a scheduler is created. Player moves in water before scheduler goes off another is started. They ever just turn their head and a playermoveevent is triggered. Your most likely blocking the thread and shortly will crash the server.

    Re think your logic. If you still need help let me know, its very simple, but if I tell you now your never learn to think logically and become a better programmer.
     
  4. Offline

    AcpSoldier

    Relicum
    I'm not sure what you mean. In a player move event, every time you move even your mouse, it counts as moving. So you think my program is starting tons and tons of schedulers every time I move in the water? I still don't know how to fix it.

    If you, or someone can tell me how to fix this, I would really appreciate it.
     
  5. to only continue when the player is moving and not looking around:
    Code:java
    1.  
    2. if (e.getFrom() == e.getTo()) return;
    3.  
     
  6. Offline

    AcpSoldier


    I don't think I need that to fix what ever is wrong with my scheduler.

    Anyone else know how to fix it/ what is wrong?
     
  7. Offline

    sebcio98

    As Relicum said, your problem is that you are creating a new scheduler every time a player moves in water. That's about 20 times per second. So after 5 seconds you have 100 parallel schedulers running and the server is simply lagged. You need to check if your scheduler is running for certain player before creating another one.
    And I 100% agree with Relicum (again) that you should focus for a few minutes and find a logical solution. If you get the solution from the Internet you'll never become a good programmer.
     
  8. Offline

    AcpSoldier


    To be honest, I get feel ashamed coming to the forum every time for help. But can you give me a hint? I think it has something to do with
    Code:
    scheduler.isCurrentlyRunning
    And the internet is pretty much how everyone finds solutions.
     
  9. Offline

    sebcio98

    AcpSoldier That's true, but those who are searching the Internet for the copy-and-paste solutions will never be better than the one's who are finding the solutions themselves.
    Let's go back to the topic. My idea is to simply put the scheduled task's ID in a variable. I'd put the whole Runnable thing to a new class. Like this:
    Code:java
    1. package this.is.such.an.awesome.package;
    2.  
    3. //the imports
    4.  
    5. public class TheGreatScheduledClass implements Runnable
    6. {
    7. public void run()
    8. {
    9. //blah blah blah
    10. }
    11. }

    And how to use this in other classes:
    Code:java
    1. //variable nick contains a player's name (you wouldn't guess, would you?)
    2. public static HashMap<String,Integer> TackIdTheGreatClassLOL = new HashMap<>();
    3.  
    4. TackIdTheGreatClassLOL.put(nick, Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new TheGreatScheduledClass(), 0, 60L));

    Then you just check if the TackIdTheGreatClassLOL is more than 0 (task ID's are never below 0). Of course to make it work you need to set the TackIdTheGreatClassLOL to -1 after a cartain player leaves the water.

    That's just how I'm doing it in my plugins, there should be an easier way..
     
Thread Status:
Not open for further replies.

Share This Page