package net.glowstone.generator; 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.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; import org.bukkit.util.noise.OctaveGenerator; import java.util.*; /** * Base chunk generator class. */ public abstract class GlowChunkGenerator extends ChunkGenerator { // distinct from GlowChunk.DEPTH, only used in the wgen protected static final int WORLD_DEPTH = 128; private static final Set<Material> noSpawnFloors = EnumSet.of(Material.FIRE, Material.CACTUS); private final Map<String, Map<String, OctaveGenerator>> octaveCache = new HashMap<>(); private final List<BlockPopulator> populators; protected GlowChunkGenerator(BlockPopulator... args) { populators = Arrays.asList(args); } /** * @param world The world to create OctaveGenerators for * @param octaves The map to put the OctaveGenerators into */ protected void createWorldOctaves(World world, Map<String, OctaveGenerator> octaves) { } /** * @param world The world to look for in the cache * @return A map of {@link OctaveGenerator}s created by {@link #createWorldOctaves(World, Map)} */ protected final Map<String, OctaveGenerator> getWorldOctaves(World world) { if (octaveCache.get(world.getName()) == null) { Map<String, OctaveGenerator> octaves = new HashMap<>(); createWorldOctaves(world, octaves); octaveCache.put(world.getName(), octaves); return octaves; } return octaveCache.get(world.getName()); } @Override public final List<BlockPopulator> getDefaultPopulators(World world) { return populators; } @Override public boolean canSpawn(World world, int x, int z) { Block block = world.getHighestBlockAt(x, z).getRelative(BlockFace.DOWN); return !block.isLiquid() && !block.isEmpty() && !noSpawnFloors.contains(block.getType()); } @Override public Location getFixedSpawnLocation(World world, Random random) { int spawnX = random.nextInt(256) - 128, spawnZ = random.nextInt(256) - 128; for (int tries = 0; tries < 1000 && !canSpawn(world, spawnX, spawnZ); ++tries) { spawnX += random.nextInt(128) - 64; spawnZ += random.nextInt(128) - 64; } return new Location(world, spawnX, world.getHighestBlockYAt(spawnX, spawnZ), spawnZ); } }