package com.iridium.iridiumskyblock; import com.iridium.iridiumskyblock.configs.Config; import com.iridium.iridiumskyblock.configs.Schematics; import org.bukkit.*; import org.bukkit.World.Environment; import org.bukkit.entity.Player; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class IslandManager { public Map<Integer, Island> islands = new HashMap<>(); public Map<String, User> users = new HashMap<>(); public Map<List<Integer>, Set<Integer>> islandCache = new HashMap<>(); int length = 1; int current = 0; public Direction direction = Direction.NORTH; public Location nextLocation; public int nextID = 1; public IslandManager() { makeWorld(); nextLocation = new Location(getWorld(), 0, 0, 0); } public World getWorld() { return Bukkit.getWorld(IridiumSkyblock.getConfiguration().worldName); } public World getNetherWorld() { return Bukkit.getWorld(IridiumSkyblock.getConfiguration().netherWorldName); } public void createIsland(Player player) { User user = User.getUser(player); if (user.lastCreate != null && new Date().before(user.lastCreate) && IridiumSkyblock.getConfiguration().createCooldown && !user.bypassing) { //The user cannot create an island long time = (user.lastCreate.getTime() - System.currentTimeMillis()) / 1000; int day = (int) TimeUnit.SECONDS.toDays(time); int hours = (int) Math.floor(TimeUnit.SECONDS.toHours(time - day * 86400)); int minute = (int) Math.floor((time - day * 86400 - hours * 3600) / 60.00); int second = (int) Math.floor((time - day * 86400 - hours * 3600) % 60.00); player.sendMessage(Utils.color(IridiumSkyblock.getMessages().createCooldown.replace("%days%", day + "").replace("%hours%", hours + "").replace("%minutes%", minute + "").replace("%seconds%", second + "").replace("%prefix%", IridiumSkyblock.getConfiguration().prefix))); return; } Calendar c = Calendar.getInstance(); c.add(Calendar.SECOND, IridiumSkyblock.getConfiguration().regenCooldown); user.lastCreate = c.getTime(); Location pos1 = nextLocation.clone().subtract(IridiumSkyblock.getUpgrades().sizeUpgrade.upgrades.get(1).size / 2.00, 0, IridiumSkyblock.getUpgrades().sizeUpgrade.upgrades.get(1).size / 2.00); Location pos2 = nextLocation.clone().add(IridiumSkyblock.getUpgrades().sizeUpgrade.upgrades.get(1).size / 2.00, 0, IridiumSkyblock.getUpgrades().sizeUpgrade.upgrades.get(1).size / 2.00); Location center = nextLocation.clone().add(0, 100, 0); Location home = nextLocation.clone(); Location netherhome = home.clone(); if (IridiumSkyblock.getConfiguration().netherIslands) { netherhome.setWorld(IridiumSkyblock.getIslandManager().getNetherWorld()); } Island island = new Island(player, pos1, pos2, center, home, netherhome, nextID); islands.put(nextID, island); user.islandID = nextID; user.role = Role.Owner; if (IridiumSkyblock.getSchematics().schematics.size() == 1) { for (Schematics.FakeSchematic schematic : IridiumSkyblock.getSchematics().schematics) { island.setSchematic(schematic.name); island.setNetherschematic(schematic.netherisland); island.setHome(island.getHome().add(schematic.x, schematic.y, schematic.z)); island.setNetherhome(island.getNetherhome().add(schematic.x, schematic.y, schematic.z)); } island.pasteSchematic(player, false); } else { player.openInventory(island.getSchematicSelectGUI().getInventory()); } switch (direction) { case NORTH: nextLocation.add(IridiumSkyblock.getConfiguration().distance, 0, 0); break; case EAST: nextLocation.add(0, 0, IridiumSkyblock.getConfiguration().distance); break; case SOUTH: nextLocation.subtract(IridiumSkyblock.getConfiguration().distance, 0, 0); break; case WEST: nextLocation.subtract(0, 0, IridiumSkyblock.getConfiguration().distance); break; } current++; if (current == length) { current = 0; direction = direction.next(); if (direction == Direction.SOUTH || direction == Direction.NORTH) { length++; } } IridiumSkyblock.getInstance().saveConfigs(); nextID++; } private void makeWorld() { makeWorld(Environment.NORMAL, IridiumSkyblock.getConfiguration().worldName); if (IridiumSkyblock.getConfiguration().netherIslands) makeWorld(Environment.NETHER, IridiumSkyblock.getConfiguration().netherWorldName); } private void makeWorld(Environment env, String name) { WorldCreator wc = new WorldCreator(name); wc.type(WorldType.FLAT); wc.generateStructures(false); wc.generator(new SkyblockGenerator()); wc.environment(env); wc.createWorld(); } public Island getIslandViaLocation(Location location) { if (location == null) return null; if (!isIslandWorld(location)) return null; final Chunk chunk = location.getChunk(); final List<Integer> chunkKey = Collections.unmodifiableList(Arrays.asList(chunk.getX(), chunk.getZ())); final double x = location.getX(); final double z = location.getZ(); final Set<Integer> islandIds = islandCache.computeIfAbsent(chunkKey, (hash) -> islands .values() .stream() .filter(island -> island.isInIsland(x, z)) .map(Island::getId) .collect(Collectors.toSet())); for (int id : islandIds) { final Island island = islands.get(id); if (island == null) continue; if (island.isInIsland(x, z)) return island; } for (Island island : islands.values()) { if (!island.isInIsland(x, z)) continue; islandIds.add(island.getId()); return island; } return null; } public Island getIslandViaId(int i) { return islands.get(i); } public boolean isIslandWorld(Location location) { if (location == null) return false; return isIslandWorld(location.getWorld()); } public boolean isIslandWorld(World world) { if (world == null) return false; final String name = world.getName(); return isIslandWorld(name); } public boolean isIslandWorld(String name) { final Config config = IridiumSkyblock.getConfiguration(); return (name.equals(config.worldName) || name.equals(config.netherWorldName)); } public void removeIsland(Island island) { final int id = island.getId(); islands.remove(id); islandCache .forEach((key, value) -> value.remove(id)); } }