Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package red.mirai.spawnsystems;
- import org.bukkit.Chunk;
- import org.bukkit.Location;
- import org.bukkit.Material;
- import org.bukkit.World;
- import org.bukkit.block.Block;
- import org.bukkit.block.BlockFace;
- import org.bukkit.entity.Player;
- import org.bukkit.scheduler.BukkitRunnable;
- import red.mirai.spawnsystems.Events.SpawnProtection;
- import java.util.ArrayList;
- import java.util.Objects;
- import java.util.Random;
- import java.util.concurrent.ThreadLocalRandom;
- import static org.bukkit.Bukkit.getServer;
- public class RandomSpawnLocation {
- public ArrayList<Player> respawnQueue = new ArrayList<>();
- private static int randomInRange(int min, int max) {
- if ( min >= max ) {
- throw new IllegalArgumentException( "max must be greater than min" );
- }
- Random r = ThreadLocalRandom.current();
- return r.nextInt( ( max - min ) + 1 ) + min;
- }
- private static Block findSuitableBlock(World world, Block block, Chunk chunk) {
- boolean found = false;
- boolean checkingArea = false;
- boolean exit = false;
- int x = chunk.getX();
- int z = chunk.getZ();
- ArrayList<Block> blocks = new ArrayList<>();
- while ( !found && !exit ) {
- Material blockMaterial = block.getType();
- if ( blockMaterial == Material.AIR ) {
- blockMaterial = block.getRelative( BlockFace.DOWN ).getType();
- }
- switch ( blockMaterial ) {
- case LAVA:
- case CACTUS:
- case MAGMA_BLOCK:
- case SWEET_BERRY_BUSH:
- case ROSE_BUSH:
- case FIRE:
- case DEAD_BUSH:
- case CAMPFIRE:
- if ( !checkingArea ){
- checkingArea = true;
- for ( int ix = x - 7; ix <= x + 7; ix++ ) {
- for ( int iz = z - 7; iz <= z + 7; iz++ ) {
- blocks.add( chunk.getWorld().getHighestBlockAt( x, z ) );
- }
- }
- }
- int size = blocks.size();
- if ( size <= 0 ){
- exit = true;
- continue;
- }
- int i = ThreadLocalRandom.current().nextInt( size );
- block = blocks.get( i );
- blocks.remove( i );
- continue;
- default:
- found = true;
- }
- }
- return found ? block : null;
- }
- public void send(Player ply) {
- respawnQueue.add( ply );
- World world = getServer().getWorld( "world" );
- Objects.requireNonNull(world);
- int worldRadius = (int) world.getWorldBorder().getSize() / 2;
- int borderDistance = worldRadius / 1000;
- int max = worldRadius - borderDistance;
- new BukkitRunnable() {
- Location location;
- @Override
- public void run() {
- int x = randomInRange( -max, max );
- int z = randomInRange( -max, max );
- for ( Player ply : getServer().getOnlinePlayers() ) {
- World plyWorld = ply.getWorld();
- if ( plyWorld != world ) {
- continue;
- }
- Location plyLocation = ply.getLocation();
- int px = plyLocation.getBlockX();
- int pz = plyLocation.getBlockZ();
- int distance = (int) Math.sqrt( ( pz - z ) * ( pz - z ) + ( px - x ) * ( px - x ) );
- if ( distance < 512 ) {
- return;
- }
- }
- Chunk chunk = world.getChunkAt( x, z );
- SpawnSystems.plugin.getLogger().info( "Loading Chunk @ X: " + x + " Z: " + z );
- world.loadChunk( chunk );
- Block block = world.getHighestBlockAt( x, z );
- switch ( block.getBiome() ) {
- case OCEAN:
- case COLD_OCEAN:
- case WARM_OCEAN:
- case FROZEN_OCEAN:
- case LUKEWARM_OCEAN:
- case DEEP_OCEAN:
- case DEEP_COLD_OCEAN:
- case DEEP_WARM_OCEAN:
- case DEEP_FROZEN_OCEAN:
- case DEEP_LUKEWARM_OCEAN:
- return;
- }
- Block safeBlock = findSuitableBlock( world, block, chunk );
- if ( safeBlock == null ) {
- return;
- }
- location = safeBlock.getLocation();
- world.strikeLightningEffect( location );
- if ( !world.isDayTime() ) {
- SpawnProtection.apply( ply );
- }
- ply.teleportAsync( location );
- respawnQueue.remove( ply );
- cancel();
- }
- }.runTaskTimer( SpawnSystems.plugin, 0L, 5L );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement