Teleport Queue - Help with code

Discussion in 'Plugin Development' started by Kepler_, Aug 23, 2012.

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

    Kepler_

    There is a glitch in bukkit where when multiple people are teleported to the same spot at the same time no one can see each other. I want to work around this glitch by making a queue, where there is a list of players and their destination, and one player gets teleported per tick. Here is the code i have so far:
    Code:
    import java.util.ArrayList;
    import java.util.List;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.entity.Player;
    import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
     
    public class SafeTeleport {
        private static List<String> playerQueue = new ArrayList<String>();
        private static List<Location> playerDestinationQueue = new ArrayList<Location>();
        private static List<TeleportCause> playerReasonQueue = new ArrayList<TeleportCause>();
       
        public static void Teleport(Player player, Location destination, TeleportCause teleportCause){
            playerQueue.add(player.getName());
            playerDestinationQueue.add(destination);
            playerReasonQueue.add(teleportCause);
     
            Bukkit.getScheduler().scheduleSyncDelayedTask(Bukkit.getPluginManager().getPlugin("MyServer"), new Runnable() {
                public void run() {
                    Player p = Bukkit.getPlayer(playerQueue.get(0));
                    if (p != null) {
                        p.teleport(playerDestinationQueue.get(0), playerReasonQueue.get(0));
                    }
                    playerQueue.remove(0);
                    playerDestinationQueue.remove(0);
                    playerReasonQueue.remove(0);
                   
                }
            }, 1L);
        }
    }
    How can i make the delayed scheduled task re-schedule its self, so it executes at the next tick (if there are still players in the queue)?

    Thanks :D
     
  2. Offline

    keensta

    Bukkit.getScheduler().scheduleAsyncRepeatingTask(arg0, arg1, arg2, arg3);
    Just use this inside your onEnable.

    Then just have something else that runs the adding to the lists..
     
  3. Offline

    Jnorr44

    Why not just make a new thread, then do:

    for(Player p : playerQueue){
    p.teleport(/*You know... */);
    Thread.sleep(1000); //1 second
    }
     
  4. Offline

    Kepler_

    Keensta:
    can you explain a bit more? I'm not really understanding how it works.

    Jnorr:
    Players can be added to the thread while the schedule is running, so i don't think that idea would work :/
     
  5. Offline

    keensta

    So like what you have.
    Code:
    Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
                    public void run() {
                        Player p = Bukkit.getPlayer(playerQueue.get(0));
                        if (p != null) {
                            p.teleport(playerDestinationQueue.get(0), playerReasonQueue.get(0));
                        }
                        playerQueue.remove(0);
                        playerDestinationQueue.remove(0);
                        playerReasonQueue.remove(0);
                       
                    }
                }, 1L, 1L);
    
    Put that in your public void onEnable(){} But i suggest putting the Runnable into a complete new class Rather then just doing it that way. Then what that will do is on the plugin startup it will set a new repeatingTask(Constantly checking for Tps.) Just add it so you know how you do
    Code:
    playerQueue.add(player.getName());
            playerDestinationQueue.add(destination);
            playerReasonQueue.add(teleportCause);
    just put that into another method rather then having it in the runnable.That way you add the people to the list and the server every Tick will run that RepeatingTask and will teleport people.
     
  6. Offline

    chaseoes

    Never use thread.sleep! Use the Bukkit Scheduler!
     
  7. Offline

    Jnorr44

    You can if you are using threading

    public class CLASSNAME implements/extends (cant remember) Thread{
     
    keensta likes this.
  8. Offline

    keensta

    He said create a new thread. So he won't be putting the Bukkit one to sleep (I don't think so anyway).
     
  9. Offline

    Jnorr44

    Correct you are!
     
  10. Offline

    Kepler_

    Shorter question:

    How can I re-run a delayed task if I have the task's ID?

    I figured it out. I put the delayed task into a function, then run that function:
    Code:
    import java.util.ArrayList;
    import java.util.List;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.entity.Player;
    import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
     
    public class SafeTeleport {
        private static List<String> playerQueue = new ArrayList<String>();
        private static List<Location> playerDestinationQueue = new ArrayList<Location>();
        private static List<TeleportCause> playerReasonQueue = new ArrayList<TeleportCause>();
       
        public static void Teleport(Player player, Location destination, TeleportCause teleportCause){
            playerQueue.add(player.getName());
            playerDestinationQueue.add(destination);
            playerReasonQueue.add(teleportCause);
     
            if (playerQueue.size() == 1){
                schedule();
            }
        }
       
        private static void schedule(){
            Bukkit.getScheduler().scheduleSyncDelayedTask(Bukkit.getPluginManager().getPlugin("MyServer"), new Runnable() {
                public void run() {
                    Player p = Bukkit.getPlayer(playerQueue.get(0));
                    if (p != null) {
                        p.teleport(playerDestinationQueue.get(0), playerReasonQueue.get(0));
                    }
                    playerQueue.remove(0);
                    playerDestinationQueue.remove(0);
                    playerReasonQueue.remove(0);
                   
                    if (playerQueue.size() > 0){
                        schedule();
                    }
                }
            }, 1L);
        }
    }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  11. Offline

    caldabeast

    Why not use Scheduler? It's made by people a lot better at coding than you are, and they had good reason to make it.
    If you could merely create another thread and not lose any performance or anything at all, they wouldn't have made it.
     
  12. Offline

    Fl1pzta

    Do we need to replace MyServer with our class name
     
  13. Offline

    Kepler_

    Yes
     
Thread Status:
Not open for further replies.

Share This Page