package wtf.beatrice.limbomanager.listeners; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.World; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import wtf.beatrice.limbomanager.Cache; import wtf.beatrice.limbomanager.LimboManager; import wtf.beatrice.limbomanager.objects.Coordinates; import wtf.beatrice.limbomanager.utils.LocationUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class PlayerTeleporter implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); String playerName = player.getName(); Coordinates islandCoords = calcNewCoordinates(); Cache.playerIslands.put(playerName, islandCoords); Location islandLocation = new Location(player.getWorld(), islandCoords.getX(), 64, islandCoords.getZ()); // load chunk otherwise it will be buggy (no schem load, no tp) islandLocation.getWorld().loadChunk(islandLocation.getChunk().getX(), islandLocation.getChunk().getZ(), true); String testSchematicPath = LimboManager.getSchematicsFolder().getAbsolutePath() + File.separator + "endcityship.schem"; File schematicFile = new File(testSchematicPath); if(!schematicFile.exists()) System.out.println("no exist"); // todo: check if exists, but this is just a test World islandWEWorld = BukkitAdapter.adapt(islandLocation.getWorld()); Clipboard shematicClipboard; ClipboardFormat clipboardFormat = ClipboardFormats.findByFile(schematicFile); try (ClipboardReader reader = clipboardFormat.getReader(new FileInputStream(schematicFile))) { shematicClipboard = reader.read(); try (EditSession editSession = WorldEdit.getInstance().newEditSession(islandWEWorld)) { Operation operation = new ClipboardHolder(shematicClipboard) .createPaste(editSession) .to(BlockVector3.at(islandLocation.getX(), 64, islandLocation.getZ())) // configure here .build(); Operations.complete(operation); editSession.flushSession(); } catch (WorldEditException e) { throw new RuntimeException(e); } } catch (IOException e) { throw new RuntimeException(e); } LocationUtils.teleportToOwnIsland(player); } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { String playerName = event.getPlayer().getName(); Cache.playerIslands.remove(playerName); } private Coordinates calcNewCoordinates() { /* how are islands laid out? we start from (1000, 1000) and we put islands at 500 blocks distance up to 10000. then we move to a new row. */ Coordinates islandCoords = new Coordinates(Cache.baseCoords); for(Coordinates currentCoords : Cache.playerIslands.values()) { // if the two are not the same, it means we found a free spot. // we can thus quit the loop and keep the current coords as valid. if(!islandCoords.equals(currentCoords)) break; // else, if they are the same, // we have to either increase X or move to a new row, in case it's over 10000. if(islandCoords.getX() >= 10000) // if we need to create a new row { islandCoords.setX(1000); islandCoords.setZ(islandCoords.getZ() + 500); } else { // if we just need to increase the column islandCoords.setX(islandCoords.getX() + 500); } } return islandCoords; } } /* player joins -> we look for the first free space -> we add it to the list and generate the island */