Preloading chunks before teleport!

Discussion in 'Plugin Development' started by QRS%, Jul 17, 2015.

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

    QRS%

    Hey there.
    I've spent all day and all of yesterday trying to solve my plugin.
    What I am trying to do is to preload the chunks around the player as well as the chunk that the player will get teleported to. However, the player seems to get stuck quite often after being teleported.

    This is the randomiser which runs every 30 minutes:

    Code:
            BukkitScheduler s_randomSpawn = Bukkit.getServer().getScheduler();
    
            s_randomSpawn.scheduleSyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
    
                    Location temp;
                    double x, y, z;
    
                    do{
    
                        Random rand = new Random();
    
                        x = rand.nextInt(10000);
                        y = 65 + rand.nextInt(75 - 65 + 1);
                        z = rand.nextInt(10000);
    
                        World w = Bukkit.getWorld("world");
    
                        temp = new Location(w,x,y,z);
    
                    }while(temp.getBlock().getRelative(BlockFace.DOWN).getType() != Material.GRASS);
    
                    getConfig().set("loc.world", "world");
                    getConfig().set("loc.x", x);
                    getConfig().set("loc.y", y);
                    getConfig().set("loc.z", z);
                    saveConfig();
    
                    Bukkit.getServer().broadcastMessage(serverPrefix + ChatColor.GRAY + " World spawn updated with random x, y, z!");
    
                }
            }, 0L, 30 * minute);
    
    And this is what I do during respawnEvent:

    Code:
    @EventHandler
        public void playerRespawn(PlayerRespawnEvent event){
    
            Player p = event.getPlayer();
    
            if(p.getBedSpawnLocation() == null){
    
                // Set spectator while loading
                p.setGameMode(GameMode.SPECTATOR);
                p.sendMessage(serverPrefix + ChatColor.GRAY + " Pre-loading the new area...");
    
                getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    
                    public void run() {
    
                        World w = Bukkit.getWorld(getConfig().getString("loc.world"));
                        double x = getConfig().getDouble("loc.x");
                        double y = getConfig().getDouble("loc.y");
                        double z = getConfig().getDouble("loc.z");
    
                        Location temp = new Location(w,x,y,z);
    
                        temp.getChunk().load(true);
    
                        while(!temp.getChunk().isLoaded()){
                            p.sendMessage(serverPrefix + ChatColor.GRAY + " Hold on...");
                        }
    
                        p.teleport(temp);
                        p.setGameMode(GameMode.SURVIVAL);
                        p.sendMessage(serverPrefix + ChatColor.GRAY + " Teleported!");
    
                    }
    
                }, 80L);
    
            }else{
    
                p.setGameMode(GameMode.SPECTATOR);
                p.sendMessage(serverPrefix + ChatColor.GRAY + " Lol, n00b! Teleporting");
    
                getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    
                    public void run() {
    
                        p.getBedSpawnLocation().getChunk().load(true);
    
                        while(!p.getBedSpawnLocation().getChunk().isLoaded()){
                            p.sendMessage(serverPrefix + ChatColor.GRAY + " Hold on...");
                        }
    
                        p.teleport(p.getBedSpawnLocation());
                        p.setGameMode(GameMode.SURVIVAL);
                        p.sendMessage(serverPrefix + ChatColor.GRAY + " Teleported!");
    
                    }
    
                }, 80L);
    
            }
    
        }
    Why do I sometimes get stuck when teleporting even though I load the chunk first?
    (I'm developing locally on a system with an i7, 16GB RAM and SSD)
     
  2. Offline

    schwabfl

    because your y location is inside the ground
    World has a method called getHighextBlockYAt(int x, int z), get that and add 2 to it, that should return a safe y level, where you can teleport the player at
     
  3. Offline

    QRS%

    So like this then? Except I won't use a static string for getting world:
    Code:
    y = Bukkit.getWorld("world").getHighestBlockYAt(temp) + 2;
     
  4. Offline

    schwabfl

    Code:
    x = rand.nextInt(10000);
    z = rand.nextInt(10000);
    y = world.getHighestBlockYAt(x, z) + 2;
    You have not set temp equal to anything yet,
    aka NPE incoming

    EDIT: I just saw your while condition,
    remove the do {stuff} while {stuff} part, but not the stuff inside of do {this stuff}
     
  5. @schwabfl
    Just so you know. In a do {} while {} statement, the do always is called 1 time before the while check.
     
    schwabfl likes this.
  6. Offline

    QRS%

    I've changed all that I still get stuck sometimes in the ground? What could be the problem?
     
  7. @QRS%
    What is your current code and how are you teleporting them?
     
  8. Offline

    QRS%

    Code:
    package XX.XX.XX;
    
    import org.bukkit.*;
    import org.bukkit.event.Listener;
    import org.bukkit.event.EventHandler;
    import org.bukkit.entity.Player;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerQuitEvent;
    import org.bukkit.event.player.AsyncPlayerChatEvent;
    import org.bukkit.event.player.PlayerRespawnEvent;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
    import org.bukkit.scheduler.BukkitScheduler;
    import org.bukkit.event.world.ChunkLoadEvent;
    import java.util.Random;
    
    public class Main extends JavaPlugin implements Listener{
    
        String serverPrefix = ChatColor.DARK_GRAY + "[" + ChatColor.DARK_PURPLE + "E" + ChatColor.DARK_GRAY + "]" + ChatColor.RESET;
    
        @Override
        public void onEnable(){
    
            // Load config
            loadConfiguration();
    
            // Enable listeners
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
    
            int ticks = 20; // 1 second
    
            long second = 1*ticks;
            long minute = 60*ticks;
            long hour = 60*60*ticks;
            long day = 60*60*24*ticks;
            long week = 60*60*24*7*ticks;
    
            // Set default game mode
            Bukkit.getServer().setDefaultGameMode(GameMode.SURVIVAL);
            Bukkit.getConsoleSender().sendMessage(serverPrefix + ChatColor.GRAY + " Survival set to default game mode.");
    
            // Random Spawn
            BukkitScheduler s_randomSpawn = Bukkit.getServer().getScheduler();
    
            s_randomSpawn.scheduleSyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
    
                    Integer x, y, z;
    
                    Random rand = new Random();
    
                    World w = Bukkit.getWorld("world");
    
                    x = rand.nextInt(10000);
                    z = rand.nextInt(10000);
                    y = w.getHighestBlockYAt(x, z) + 4;
    
                    getConfig().set("loc.world", "world");
                    getConfig().set("loc.x", x);
                    getConfig().set("loc.y", y);
                    getConfig().set("loc.z", z);
                    saveConfig();
    
                    Bukkit.getServer().broadcastMessage(serverPrefix + ChatColor.GRAY + " World spawn updated with random x, y, z!");
    
                }
            }, 0L, 30 * minute);
    
        }
    
        @EventHandler
        public void playerJoin(PlayerJoinEvent event){
    
            Player p = event.getPlayer();
    
            if(!p.hasPlayedBefore()){
    
                World w = Bukkit.getWorld(getConfig().getString("loc.world"));
                double x = getConfig().getDouble("loc.x");
                double y = getConfig().getDouble("loc.y");
                double z = getConfig().getDouble("loc.z");
    
                Location temp = new Location(w,x,y,z);
    
                p.teleport(temp);
                p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 100, 10));
    
                Bukkit.getServer().broadcastMessage(serverPrefix + ChatColor.GOLD + " Welcome our new player, " + p.getName() + "!");
                p.sendMessage(serverPrefix + ChatColor.GRAY + " Welcome to Emise, " + p.getName() + "!");
                p.sendMessage(serverPrefix + ChatColor.GRAY + " HP[" + ChatColor.GREEN + p.getHealth() + ChatColor.GRAY + "] LVL[" + ChatColor.GOLD + p.getLevel() + ChatColor.GRAY + "]");
                p.sendMessage(serverPrefix + ChatColor.GRAY + " XYZ[" + ChatColor.AQUA + (int) Math.ceil(p.getLocation().getX()) + ", " + (int) Math.ceil(p.getLocation().getY()) + ", " + (int) Math.ceil(p.getLocation().getZ()) + ChatColor.GRAY + "]");
    
            }else{
    
                p.sendMessage(serverPrefix + ChatColor.GRAY + " Welcome back, " + p.getName() + "!");
                p.sendMessage(serverPrefix + ChatColor.GRAY + " HP[" + ChatColor.GREEN + p.getHealth() + ChatColor.GRAY + "] LVL[" + ChatColor.GOLD + p.getLevel() + ChatColor.GRAY + "]");
                p.sendMessage(serverPrefix + ChatColor.GRAY + " XYZ[" + ChatColor.AQUA + (int) Math.ceil(p.getLocation().getX()) + ", " + (int) Math.ceil(p.getLocation().getY()) + ", " + (int) Math.ceil(p.getLocation().getZ()) + ChatColor.GRAY + "]");
                p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 100, 10));
    
            }
    
            for(Player x : Bukkit.getOnlinePlayers()){
                x.playSound(x.getLocation(), Sound.NOTE_BASS_GUITAR, 5, 1);
            }
    
        }
    
        @EventHandler
        public void playerQuit(PlayerQuitEvent event){
    
            for(Player x : Bukkit.getOnlinePlayers()){
                x.playSound(x.getLocation(), Sound.NOTE_PIANO, 5, 1);
            }
    
        }
    
        @EventHandler
        public void playerChat(AsyncPlayerChatEvent event){
    
            for(Player x : Bukkit.getOnlinePlayers()){
                x.playSound(x.getLocation(), Sound.NOTE_BASS, 1, 1);
            }
    
        }
    
        @EventHandler
        public void ChunkLoadEvent(ChunkLoadEvent event){
    
            if(event.isNewChunk()){
                Bukkit.getConsoleSender().sendMessage(serverPrefix + ChatColor.GRAY + " Loading a new chunk...");
            }else{
                Bukkit.getConsoleSender().sendMessage(serverPrefix + ChatColor.GRAY + " Loading an existing chunk...");
            }
    
            if(event.getChunk().isLoaded()){
                Bukkit.getConsoleSender().sendMessage(serverPrefix + ChatColor.GRAY + " Chunk at " + (int) Math.ceil(event.getChunk().getX()) + ", " + (int) Math.ceil(event.getChunk().getZ()) + " loaded!");
            }
    
            Bukkit.getConsoleSender().sendMessage(serverPrefix + ChatColor.GRAY + " " + Bukkit.getWorld("world").getLoadedChunks().length + " chunks loaded.");
    
        }
    
        @EventHandler
        public void playerRespawn(PlayerRespawnEvent event){
    
            Player p = event.getPlayer();
    
            if(p.getBedSpawnLocation() == null){
    
                // Set spectator while loading
                p.setGameMode(GameMode.SPECTATOR);
                p.sendMessage(serverPrefix + ChatColor.GRAY + " Pre-loading the new area...");
    
                getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    
                    public void run() {
    
                        World w = Bukkit.getWorld(getConfig().getString("loc.world"));
                        double x = getConfig().getDouble("loc.x");
                        double y = getConfig().getDouble("loc.y");
                        double z = getConfig().getDouble("loc.z");
    
                        Location temp = new Location(w, x, y, z);
    
                        temp.getChunk().load(true);
    
                        while (!temp.getChunk().isLoaded()) {
                            p.sendMessage(serverPrefix + ChatColor.GRAY + " Hold on...");
                        }
    
                        p.teleport(temp);
                        p.setGameMode(GameMode.SURVIVAL);
                        p.sendMessage(serverPrefix + ChatColor.GRAY + " Teleported!");
    
                    }
    
                }, 80L);
    
            }else{
    
                p.setGameMode(GameMode.SPECTATOR);
                p.sendMessage(serverPrefix + ChatColor.GRAY + " Lol, n00b! Teleporting");
    
                getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    
                    public void run() {
    
                        p.getBedSpawnLocation().getChunk().load(true);
    
                        while(!p.getBedSpawnLocation().getChunk().isLoaded()){
                            p.sendMessage(serverPrefix + ChatColor.GRAY + " Hold on...");
                        }
    
                        p.teleport(p.getBedSpawnLocation());
                        p.setGameMode(GameMode.SURVIVAL);
                        p.sendMessage(serverPrefix + ChatColor.GRAY + " Teleported!");
    
                    }
    
                }, 80L);
    
            }
    
        }
    
        public void loadConfiguration(){
    
            getConfig().options().copyDefaults(true);
    
            getConfig().set("loc.world", "world");
            getConfig().set("loc.x", 0);
            getConfig().set("loc.y", 0);
            getConfig().set("loc.z", 0);
    
            saveConfig();
    
        }
    
        @Override
        public void onDisable(){}
    
    }
    
    Did you have time to take a look? :) Would be very appreciated.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 11, 2016
Thread Status:
Not open for further replies.

Share This Page