diff --git a/resources/schematics/windmill2_0.txt b/resources/schematics/windmill2_0.txt index df2581e..34a7f02 100644 --- a/resources/schematics/windmill2_0.txt +++ b/resources/schematics/windmill2_0.txt @@ -18,7 +18,7 @@ grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] -glass grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] +grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] ==== air air air air air air air air air air air air air air air air air air air air air air air air air air air air diff --git a/resources/schematics/windmill2_180.txt b/resources/schematics/windmill2_180.txt index b949970..1a885a2 100644 --- a/resources/schematics/windmill2_180.txt +++ b/resources/schematics/windmill2_180.txt @@ -1,4 +1,4 @@ -grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] glass +grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] diff --git a/resources/schematics/windmill2_270.txt b/resources/schematics/windmill2_270.txt index 379e3df..ec208e8 100644 --- a/resources/schematics/windmill2_270.txt +++ b/resources/schematics/windmill2_270.txt @@ -1,4 +1,4 @@ -glass grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt dirt dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] +grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt dirt dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt stone stone stone dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt stone stone stone stone stone dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt stone stone stone stone stone stone stone dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] diff --git a/resources/schematics/windmill2_90.txt b/resources/schematics/windmill2_90.txt index fd6d2f4..26ab756 100644 --- a/resources/schematics/windmill2_90.txt +++ b/resources/schematics/windmill2_90.txt @@ -11,7 +11,7 @@ grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt stone stone stone stone stone stone stone dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt stone stone stone stone stone dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt stone stone stone dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] -grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt dirt dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] glass +grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] dirt dirt dirt grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] grass_block[snowy=false] ==== air air air air air air air air air oak_planks oak_door[facing=west,half=lower,hinge=right,open=false,powered=false] oak_planks air air air air air air air air air air air air air air air air air air oak_planks air oak_planks air air air air air air air air air diff --git a/resources/ship.json b/resources/ship.json new file mode 100644 index 0000000..aa8bc59 --- /dev/null +++ b/resources/ship.json @@ -0,0 +1,525 @@ +{ + "blocks": [ + { + "pos": [ + 2, + 1, + 1 + ], + "state": 0 + }, + { + "pos": [ + 2, + 0, + 2 + ], + "state": 0 + }, + { + "pos": [ + 1, + 1, + 2 + ], + "state": 0 + }, + { + "pos": [ + 2, + 1, + 2 + ], + "state": 0 + }, + { + "pos": [ + 3, + 1, + 2 + ], + "state": 0 + }, + { + "pos": [ + 1, + 0, + 3 + ], + "state": 0 + }, + { + "pos": [ + 2, + 0, + 3 + ], + "state": 0 + }, + { + "pos": [ + 3, + 0, + 3 + ], + "state": 0 + }, + { + "pos": [ + 1, + 1, + 3 + ], + "state": 0 + }, + { + "pos": [ + 3, + 1, + 3 + ], + "state": 0 + }, + { + "pos": [ + 1, + 0, + 4 + ], + "state": 0 + }, + { + "pos": [ + 3, + 0, + 4 + ], + "state": 0 + }, + { + "pos": [ + 0, + 1, + 4 + ], + "state": 0 + }, + { + "pos": [ + 4, + 1, + 4 + ], + "state": 0 + }, + { + "pos": [ + 1, + 0, + 5 + ], + "state": 0 + }, + { + "pos": [ + 3, + 0, + 5 + ], + "state": 0 + }, + { + "pos": [ + 0, + 1, + 5 + ], + "state": 0 + }, + { + "pos": [ + 4, + 1, + 5 + ], + "state": 0 + }, + { + "pos": [ + 1, + 0, + 6 + ], + "state": 0 + }, + { + "pos": [ + 2, + 0, + 6 + ], + "state": 0 + }, + { + "pos": [ + 3, + 0, + 6 + ], + "state": 0 + }, + { + "pos": [ + 0, + 1, + 6 + ], + "state": 0 + }, + { + "pos": [ + 4, + 1, + 6 + ], + "state": 0 + }, + { + "pos": [ + 1, + 0, + 7 + ], + "state": 0 + }, + { + "pos": [ + 2, + 0, + 7 + ], + "state": 0 + }, + { + "pos": [ + 3, + 0, + 7 + ], + "state": 0 + }, + { + "pos": [ + 0, + 1, + 7 + ], + "state": 0 + }, + { + "pos": [ + 4, + 1, + 7 + ], + "state": 0 + }, + { + "pos": [ + 2, + 3, + 7 + ], + "state": 1 + }, + { + "pos": [ + 2, + 4, + 7 + ], + "state": 1 + }, + { + "pos": [ + 2, + 5, + 7 + ], + "state": 1 + }, + { + "pos": [ + 1, + 0, + 8 + ], + "state": 0 + }, + { + "pos": [ + 2, + 0, + 8 + ], + "state": 0 + }, + { + "pos": [ + 3, + 0, + 8 + ], + "state": 0 + }, + { + "pos": [ + 0, + 1, + 8 + ], + "state": 0 + }, + { + "pos": [ + 4, + 1, + 8 + ], + "state": 0 + }, + { + "pos": [ + 2, + 3, + 8 + ], + "state": 1 + }, + { + "pos": [ + 2, + 4, + 8 + ], + "state": 1 + }, + { + "pos": [ + 1, + 1, + 9 + ], + "state": 0 + }, + { + "pos": [ + 2, + 1, + 9 + ], + "state": 0 + }, + { + "pos": [ + 3, + 1, + 9 + ], + "state": 0 + }, + { + "pos": [ + 2, + 3, + 9 + ], + "state": 1 + }, + { + "pos": [ + 2, + 1, + 0 + ], + "state": 3 + }, + { + "pos": [ + 0, + 1, + 3 + ], + "state": 3 + }, + { + "pos": [ + 2, + 1, + 3 + ], + "state": 4 + }, + { + "pos": [ + 4, + 1, + 3 + ], + "state": 3 + }, + { + "pos": [ + 2, + 0, + 4 + ], + "state": 5 + }, + { + "pos": [ + 2, + 0, + 5 + ], + "state": 5 + }, + { + "pos": [ + 2, + 1, + 6 + ], + "state": 6 + }, + { + "pos": [ + 2, + 2, + 6 + ], + "state": 6 + }, + { + "pos": [ + 2, + 3, + 6 + ], + "state": 6 + }, + { + "pos": [ + 2, + 4, + 6 + ], + "state": 6 + }, + { + "pos": [ + 2, + 5, + 6 + ], + "state": 6 + }, + { + "pos": [ + 2, + 6, + 6 + ], + "state": 6 + }, + { + "pos": [ + 2, + 2, + 7 + ], + "state": 6 + }, + { + "pos": [ + 1, + 1, + 8 + ], + "state": 7 + }, + { + "pos": [ + 2, + 1, + 8 + ], + "state": 7 + }, + { + "pos": [ + 3, + 1, + 8 + ], + "state": 7 + }, + { + "pos": [ + 2, + 2, + 8 + ], + "state": 6 + }, + { + "pos": [ + 0, + 1, + 9 + ], + "state": 8 + }, + { + "pos": [ + 4, + 1, + 9 + ], + "state": 8 + }, + { + "pos": [ + 2, + 2, + 9 + ], + "state": 6 + }, + { + "pos": [ + 4, + 6, + 9 + ], + "state": 2 + } + ], + "size": [ + 5, + 7, + 10 + ], + "author": "XxRexRaptorxX", + "palette": [ + "minecraft:oak_planks", + "minecraft:white_wool", + "minecraft:air", + "minecraft:oak_slab[type=top]", + "minecraft:chest", + "minecraft:oak_slab[type=bottom]", + "minecraft:oak_fence", + "minecraft:oak_stairs[half=bottom,shape=straight,facing=south]", + "minecraft:ladder[facing=south]" + ] +} \ No newline at end of file diff --git a/src/eu/over9000/nordic/Nordic.java b/src/eu/over9000/nordic/Nordic.java index ed7299f..21a21f4 100644 --- a/src/eu/over9000/nordic/Nordic.java +++ b/src/eu/over9000/nordic/Nordic.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.concurrent.ThreadLocalRandom; import java.util.logging.Logger; +import me.zhehe.nordic.Config; /** * Main class of Nordic @@ -46,7 +47,9 @@ public class Nordic extends JavaPlugin { private static final String DEFAULT_WORLD_NAME = "world_nordic"; private static final String WORLD_PREFIX = "world_"; - private final List populators = buildPopulators(this); + public static List populators; + + public static Nordic instance; @Override public void onDisable() { @@ -54,6 +57,9 @@ public void onDisable() { @Override public void onEnable() { + instance = this; + Config.reload(this); + populators = buildPopulators(this); wgen = new NordicChunkGenerator(populators); } @@ -114,11 +120,12 @@ public boolean onCommand(final CommandSender sender, final Command command, fina private static List buildPopulators(Nordic plugin) { final ArrayList populators = new ArrayList<>(); populators.add(new PopulatorLakes()); - populators.add(new PopulatorGravel()); - populators.add(new PopulatorLavaLakes()); - populators.add(new PopulatorCaves()); +// populators.add(new PopulatorGravel()); +// populators.add(new PopulatorLavaLakes()); +// populators.add(new PopulatorCaves()); populators.add(new PopulatorOres()); - populators.add(new PopulatorWindMill(plugin)); + if(Config.generateWindMill()) populators.add(new PopulatorWindMill(plugin)); + populators.add(new PopulatorBoat(plugin)); populators.add(new PopulatorCustomTrees()); populators.add(new PopulatorTrees()); populators.add(new PopulatorFlowers()); diff --git a/src/eu/over9000/nordic/NordicChunkGenerator.java b/src/eu/over9000/nordic/NordicChunkGenerator.java index 464bf98..da74fca 100644 --- a/src/eu/over9000/nordic/NordicChunkGenerator.java +++ b/src/eu/over9000/nordic/NordicChunkGenerator.java @@ -20,6 +20,7 @@ import eu.over9000.nordic.noise.Voronoi; import eu.over9000.nordic.noise.Voronoi.DistanceMetric; +import java.util.ArrayList; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; @@ -29,6 +30,9 @@ import java.util.List; import java.util.Random; +import me.zhehe.nordic.NordicPopulator; +import me.zhehe.nordic.WorldGenBaseOld; +import me.zhehe.nordic.WorldGenCavesOld; /** * The ChunkGenerator of this Plugin @@ -58,6 +62,8 @@ public NordicChunkGenerator(final List populators) { this.usedSeed = 1337L; this.populators = populators; +// this.populators = new ArrayList<>(); +// this.populators.add(new NordicPopulator()); changeSeed(usedSeed); } @@ -141,8 +147,17 @@ public ChunkData generateChunkData(World world, Random random, int chunkx, int c // ############################## } } + generateCaves(world, chunkx, chunkz, result); +// result.setBlock(1, 0, 1, Material.GLASS); return result; } + + private WorldGenBaseOld caves = null; + + public void generateCaves(World world, int x, int z, ChunkGenerator.ChunkData data) { + if(caves == null) caves = new WorldGenCavesOld(); + caves.generate(world, x, z, data); + } /** * Writes the Value from the heightmap to the Chunk byte array @@ -263,9 +278,10 @@ private void genWater(final BiomeGrid biomes, final int x, final int z, final Ch if (getMaterialAt(chunk_data, x, y, z) == Material.AIR) { setMaterialAt(chunk_data, x, y, z, Material.WATER); biomes.setBiome(x, z, Biome.COLD_OCEAN); - } + } else break; y--; } + setMaterialAt(chunk_data, x, y, z, Material.GRAVEL); } @Override diff --git a/src/eu/over9000/nordic/populators/PopulatorBoat.java b/src/eu/over9000/nordic/populators/PopulatorBoat.java new file mode 100644 index 0000000..2f5b9ed --- /dev/null +++ b/src/eu/over9000/nordic/populators/PopulatorBoat.java @@ -0,0 +1,73 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package eu.over9000.nordic.populators; + +import eu.over9000.nordic.Nordic; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import ops.zhehe.Util.NordicJsonSchematic; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.generator.BlockPopulator; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; + +/** + * + * @author Zhehe + */ +public class PopulatorBoat extends BlockPopulator { + private static NordicJsonSchematic boat = null; + private final Nordic plugin; + private static List items; + static { + items = new ArrayList<>(); + items.add(Material.OAK_SAPLING); + items.add(Material.DARK_OAK_SAPLING); + items.add(Material.BIRCH_SAPLING); + items.add(Material.JUNGLE_SAPLING); + items.add(Material.ACACIA_SAPLING); + items.add(Material.BEETROOT_SEEDS); + items.add(Material.MELON_SEEDS); + items.add(Material.PUMPKIN_SEEDS); + items.add(Material.BAMBOO); + items.add(Material.CACTUS); + items.add(Material.VINE); + items.add(Material.SUGAR_CANE); + } + public PopulatorBoat(Nordic plugin) { + this.plugin = plugin; + if(boat == null) { + boat = new NordicJsonSchematic(plugin.getResource("ship.json")); + } + } + @Override + public void populate(final World world, final Random random, final Chunk source) { + if(random.nextInt(300) > 0) return; + int rx = random.nextInt(16) + 16 * source.getX(); + int rz = random.nextInt(16) + 16 * source.getZ(); + + if(world.getBiome(rx, rz) != Biome.COLD_OCEAN) return; + Block chest = boat.place(world, source); + if(chest != null) { + InventoryHolder ih = (InventoryHolder) chest.getState(); + Inventory inv = ih.getInventory(); + for(Material mat : items) { + if(random.nextInt(4) <= 1) { + int amount = 1 + random.nextInt(5); + ItemStack item = new ItemStack(mat, amount); + int slot = random.nextInt(27); + inv.setItem(slot, item); + } + } + } + } +} diff --git a/src/eu/over9000/nordic/populators/PopulatorCaves.java b/src/eu/over9000/nordic/populators/PopulatorCaves.java index 33223b1..b719dad 100644 --- a/src/eu/over9000/nordic/populators/PopulatorCaves.java +++ b/src/eu/over9000/nordic/populators/PopulatorCaves.java @@ -138,7 +138,7 @@ static void buildCave(final World world, final XYZ[] snakeBlocks) { for (final XYZ loc : snakeBlocks) { final Block block = world.getBlockAt(loc.x, loc.y, loc.z); if (!block.isEmpty() && !block.isLiquid() && block.getType() != Material.BEDROCK) { - block.setType(Material.AIR); + block.setType(Material.AIR, false); } } } diff --git a/src/eu/over9000/nordic/populators/PopulatorCustomTrees.java b/src/eu/over9000/nordic/populators/PopulatorCustomTrees.java index ea61c30..476cec5 100644 --- a/src/eu/over9000/nordic/populators/PopulatorCustomTrees.java +++ b/src/eu/over9000/nordic/populators/PopulatorCustomTrees.java @@ -44,8 +44,8 @@ public class PopulatorCustomTrees extends BlockPopulator { public void populate(final World world, final Random random, final Chunk source) { if (random.nextInt(100) < 2) { - final int x = 4 + random.nextInt(8) + source.getX() * 16; - final int z = 4 + random.nextInt(8) + source.getZ() * 16; + final int x = 5 + random.nextInt(6) + source.getX() * 16; + final int z = 5 + random.nextInt(6) + source.getZ() * 16; final Block high = world.getHighestBlockAt(x, z); if (!high.getRelative(BlockFace.DOWN).getType().equals(Material.GRASS_BLOCK)) { return; @@ -56,9 +56,9 @@ public void populate(final World world, final Random random, final Chunk source) } final Set snake = selectBlocksForTree(world, random, x, maxY - 5, z); buildTree(world, snake.toArray(new XYZ[snake.size()])); - for (final XYZ block : snake) { - world.unloadChunkRequest(block.x / 16, block.z / 16); - } +// for (final XYZ block : snake) { +// world.unloadChunkRequest(block.x / 16, block.z / 16); +// } } } @@ -103,11 +103,11 @@ private static void buildTree(final World world, final XYZ[] snakeBlocks) { for (final XYZ loc : snakeBlocks) { final Block block = world.getBlockAt(loc.x, loc.y, loc.z); if (block.isEmpty() && !block.isLiquid() && block.getType() != Material.BEDROCK) { - if (slices.containsKey(Integer.valueOf(loc.y))) { - slices.get(Integer.valueOf(loc.y)).add(block); + if (slices.containsKey(loc.y)) { + slices.get(loc.y).add(block); } else { - slices.put(Integer.valueOf(loc.y), new ArrayList<>()); - slices.get(Integer.valueOf(loc.y)).add(block); + slices.put(loc.y, new ArrayList<>()); + slices.get(loc.y).add(block); } } } diff --git a/src/eu/over9000/nordic/populators/PopulatorFlowers.java b/src/eu/over9000/nordic/populators/PopulatorFlowers.java index 57f1f88..7f9f478 100644 --- a/src/eu/over9000/nordic/populators/PopulatorFlowers.java +++ b/src/eu/over9000/nordic/populators/PopulatorFlowers.java @@ -37,12 +37,12 @@ public void populate(final World world, final Random random, final Chunk source) final int chance = random.nextInt(100); if (chance < 10) { final int flowercount = random.nextInt(3) + 2; - final int type = random.nextInt(300); + final int type = random.nextInt(270); final int choose = random.nextInt(2); if(choose == 1) { for (int t = 0; t <= flowercount; t++) { - final int flower_x = random.nextInt(15); - final int flower_z = random.nextInt(15); + final int flower_x = 1 + random.nextInt(14); + final int flower_z = 1 + random.nextInt(14); final Block handle = world.getBlockAt(flower_x + source.getX() * 16, world.getHighestBlockYAt(flower_x + source.getX() * 16, flower_z + source.getZ() * 16), flower_z + source.getZ() * 16); if (handle.getRelative(BlockFace.DOWN).getType().equals(Material.GRASS_BLOCK)) { @@ -64,8 +64,14 @@ public void populate(final World world, final Random random, final Chunk source) handle.setType(Material.WHITE_TULIP); } else if(type < 190) { handle.setType(Material.PINK_TULIP); - } else { + } else if(type < 200) { handle.setType(Material.OXEYE_DAISY); + } else if(type < 220) { + handle.setType(Material.LILY_OF_THE_VALLEY); + } else if(type < 240) { + handle.setType(Material.CORNFLOWER); + } else { + handle.setType(Material.SWEET_BERRY_BUSH); } } } @@ -76,7 +82,7 @@ public void populate(final World world, final Random random, final Chunk source) Block handle = world.getBlockAt(flower_x + source.getX() * 16, world.getHighestBlockYAt(flower_x + source.getX() * 16, flower_z + source.getZ() * 16), flower_z + source.getZ() * 16); if (handle.getRelative(BlockFace.DOWN).getType().equals(Material.GRASS_BLOCK)) { - if(type < 40) { + if(type < 50) { BlockData data = createBlockData(Material.SUNFLOWER); ((Bisected)data).setHalf(Bisected.Half.BOTTOM); handle.setBlockData(data, false); @@ -85,7 +91,7 @@ public void populate(final World world, final Random random, final Chunk source) data = createBlockData(Material.SUNFLOWER); ((Bisected)data).setHalf(Bisected.Half.TOP); handle.setBlockData(data, false); - } else if(type < 80) { + } else if(type < 100) { BlockData data = createBlockData(Material.LILAC); ((Bisected)data).setHalf(Bisected.Half.BOTTOM); handle.setBlockData(data, false); @@ -94,7 +100,7 @@ public void populate(final World world, final Random random, final Chunk source) data = createBlockData(Material.LILAC); ((Bisected)data).setHalf(Bisected.Half.TOP); handle.setBlockData(data, false); - } else if(type < 120) { + } else if(type < 150) { BlockData data = createBlockData(Material.LARGE_FERN); ((Bisected)data).setHalf(Bisected.Half.BOTTOM); handle.setBlockData(data, false); @@ -103,7 +109,7 @@ public void populate(final World world, final Random random, final Chunk source) data = createBlockData(Material.LARGE_FERN); ((Bisected)data).setHalf(Bisected.Half.TOP); handle.setBlockData(data, false); - } else if(type < 160) { + } else if(type < 200) { BlockData data = createBlockData(Material.ROSE_BUSH); ((Bisected)data).setHalf(Bisected.Half.BOTTOM); handle.setBlockData(data, false); diff --git a/src/eu/over9000/nordic/populators/PopulatorLakes.java b/src/eu/over9000/nordic/populators/PopulatorLakes.java index 7ec3940..fc051f7 100644 --- a/src/eu/over9000/nordic/populators/PopulatorLakes.java +++ b/src/eu/over9000/nordic/populators/PopulatorLakes.java @@ -18,6 +18,7 @@ */ package eu.over9000.nordic.populators; +import eu.over9000.nordic.Nordic; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; @@ -30,6 +31,7 @@ import java.util.*; import java.util.stream.Collectors; import org.bukkit.block.Biome; +import org.bukkit.scheduler.BukkitRunnable; public class PopulatorLakes extends BlockPopulator { @@ -44,39 +46,71 @@ public class PopulatorLakes extends BlockPopulator { private static final EnumSet GROUND_MATERIALS = EnumSet.of(Material.DIRT, Material.GRASS_BLOCK); private static final EnumSet FACES_TO_CHECK = EnumSet.of(BlockFace.DOWN, BlockFace.UP, BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH); + private static class Node { + public int x, z; + public Node(int x, int z) { + this.x = x; + this.z = z; + } + } + + private final static int DISTANCE = 4; + private final static int MAX_SIZE = 8; + + private final static Map> dict = new HashMap<>(); + + private static boolean isValid(World world, int chunkX, int chunkZ) { + synchronized(dict) { + String name = world.getName(); + if(dict.get(name) == null) { + List l = new ArrayList<>(); + l.add(new Node(chunkX, chunkZ)); + dict.put(name, l); + return true; + } + List list = dict.get(name); + for(Node n : list) { + int dx = chunkX - n.x; + int dz = chunkZ - n.z; + dx = dx > 0 ? dx : -dx; + dz = dz > 0 ? dz : -dz; + int dis = dx + dz; + + if(dis < DISTANCE) return false; + } + list.add(new Node(chunkX, chunkZ)); + if(list.size() > MAX_SIZE) { + list.remove(0); + } + return true; + } + } @Override public void populate(final World world, final Random random, final Chunk source) { if (random.nextInt(100) >= LAKE_CHANCE) { return; } - - final int start_x = random.nextInt(16); - final int start_z = random.nextInt(16); - - final Block lake_start = world.getHighestBlockAt(source.getX() * 16 + start_x, source.getZ() * 16 + start_z); - - if (lake_start.getY() - 1 <= 48) { - return; - } - - final Set lake_form = collectLakeLayout(world, lake_start, random); - final Set[] form_result = startLakeBuildProcess(world, lake_form); - if (form_result == null) { - return; - } - final Block creek_start = buildLake(form_result[0], random, world); - - buildAirAndWaterfall(form_result[0], form_result[1], random, world); - - //if (creek_start == null || random.nextInt(100) >= CREEK_CHANCE) { - //return; - //} - -// final List creekblocks = collectCreekBlocks(world, creek_start, random); -// if (creekblocks != null) { -// buildCreek(world, creekblocks); -// } + +// if(!isValid(world, source.getX(), source.getZ())) return; + + final int start_x = random.nextInt(16); + final int start_z = random.nextInt(16); + + final Block lake_start = world.getHighestBlockAt(source.getX() * 16 + start_x, source.getZ() * 16 + start_z); + + if (lake_start.getY() - 1 <= 48) { + return; + } + + final Set lake_form = collectLakeLayout(world, lake_start, random); + final Set[] form_result = startLakeBuildProcess(world, lake_form); + if (form_result == null) { + return; + } + final Block creek_start = buildLake(form_result[0], random, world); + + buildAirAndWaterfall(form_result[0], form_result[1], random, world); } private List collectCreekBlocks(final World world, final Block creekStart, final Random random) { @@ -112,77 +146,6 @@ private List collectCreekBlocks(final World world, final Block creekStart } return null; } -/* - private void buildCreek(final World world, final List center_blocks) { - final Set collected_blocks_air = new HashSet<>(); - final Set collected_blocks_water = new HashSet<>(); - - final int radius = 3; - final int radius_squared = 9; - int last_y = world.getMaxHeight(); - - final Set circle = new HashSet<>(); - for (final Block center : center_blocks) { - circle.clear(); - for (int x_mod = -radius; x_mod <= radius; x_mod++) { - for (int z_mod = -radius; z_mod <= radius; z_mod++) { - if ((x_mod * x_mod + z_mod * z_mod) < radius_squared) { - circle.add(center.getRelative(x_mod, 0, z_mod)); - } - } - } - int lowest = world.getMaxHeight(); - int highest = 0; - for (final Block block : circle) { - - final int x = block.getX(); - final int z = block.getZ(); - final int compare = world.getHighestBlockYAt(x, z); - - if (compare < lowest) { - lowest = compare; - } - if (compare > highest) { - highest = compare; - } - } - - if (lowest > last_y) { - lowest = last_y; - } else { - last_y = lowest; - if (last_y < 48) { - last_y = 48; - lowest = 48; - } - } - for (final Block block : circle) { - collected_blocks_water.add(world.getBlockAt(block.getX(), lowest - 3, block.getZ())); - for (int y = lowest - 2; y <= highest; y++) { - collected_blocks_air.add(world.getBlockAt(block.getX(), y, block.getZ())); - } - } - } - - //actually build it - for (final Block toWater : collected_blocks_water) { - toWater.setType(Material.WATER); - world.setBiome(toWater.getX(), toWater.getZ(), Biome.RIVER); - } - for (final Block toAir : collected_blocks_air) { - if (toAir.getY() <= 48) { - toAir.setType(Material.WATER); - world.setBiome(toAir.getX(), toAir.getZ(), Biome.RIVER); - } else if (toAir.getType() != Material.SPRUCE_LOG && - toAir.getType() != Material.SPRUCE_LEAVES && - toAir.getType() != Material.RED_MUSHROOM && - toAir.getType() != Material.VINE && - toAir.getType() != Material.GLOWSTONE) { - toAir.setType(Material.AIR); - } - } - } -*/ private Vector rotateVector(final Vector dir, final double angle) { final double new_x = dir.getX() * Math.cos(angle) - dir.getZ() * Math.sin(angle); final double new_z = dir.getX() * Math.sin(angle) + dir.getZ() * Math.cos(angle); @@ -238,7 +201,7 @@ private void buildAirAndWaterfall(final Set ground, final Set bloc if (TREE_MATERIALS.contains(block.getType())) { treeBlocksToCheck.add(block); } else { - block.setType(Material.AIR); + block.setType(Material.AIR, false); if (checkBlockIsOnBorderOfSlice(block, blocks) && isWaterfallQualified(block) && block.getY() >= ground_height + 3) { candidates.add(block); } @@ -345,7 +308,7 @@ private Block buildLake(Set top_layer, final Random random, final World w lowering++; } for (final Block block : to_air) { - block.setType(Material.AIR); + block.setType(Material.AIR, false); } //Build the First water layer diff --git a/src/eu/over9000/nordic/populators/PopulatorLavaLakes.java b/src/eu/over9000/nordic/populators/PopulatorLavaLakes.java index d3afcfe..a0334be 100644 --- a/src/eu/over9000/nordic/populators/PopulatorLavaLakes.java +++ b/src/eu/over9000/nordic/populators/PopulatorLavaLakes.java @@ -74,7 +74,7 @@ public void populate(final World world, final Random random, final Chunk source) // Ensure it's not air or liquid already lakeBlocks.stream().filter(block -> !block.isEmpty() && !block.isLiquid()).forEach(block -> { if (block.getY() >= ry) { - block.setType(Material.AIR); + block.setType(Material.AIR, false); } else { block.setType(solidMaterial); } diff --git a/src/eu/over9000/nordic/populators/PopulatorLonggrass.java b/src/eu/over9000/nordic/populators/PopulatorLonggrass.java index b268e39..17982fd 100644 --- a/src/eu/over9000/nordic/populators/PopulatorLonggrass.java +++ b/src/eu/over9000/nordic/populators/PopulatorLonggrass.java @@ -35,8 +35,8 @@ public class PopulatorLonggrass extends BlockPopulator { @Override public void populate(final World world, final Random random, final Chunk source) { - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { + for (int x = 1; x < 15; x++) { + for (int z = 1; z < 15; z++) { final int chance = random.nextInt(100); if (chance < 33) { Block handle = world.getHighestBlockAt(x + source.getX() * 16, z + source.getZ() * 16); diff --git a/src/eu/over9000/nordic/populators/PopulatorMushrooms.java b/src/eu/over9000/nordic/populators/PopulatorMushrooms.java index b4d950d..f744216 100644 --- a/src/eu/over9000/nordic/populators/PopulatorMushrooms.java +++ b/src/eu/over9000/nordic/populators/PopulatorMushrooms.java @@ -42,11 +42,10 @@ public void populate(final World world, final Random random, final Chunk source) } final int mushroomcount = random.nextInt(3) + 2; int placed = 0; - for (int t = 0; t <= mushroomcount; t++) { - for (int flower_x = 0; flower_x < 16; flower_x++) { - for (int flower_z = 0; flower_z < 16; flower_z++) { + for (int flower_x = 1; flower_x < 15; flower_x++) { + for (int flower_z = 1; flower_z < 15; flower_z++) { final Block handle = world.getBlockAt(flower_x + source.getX() * 16, getHighestEmptyBlockYAtIgnoreTreesAndFoliage(world, flower_x + source.getX() * 16, flower_z + source.getZ() * 16), flower_z + source.getZ() * 16); - if (handle.getRelative(BlockFace.DOWN).getType().equals(Material.GRASS_BLOCK) && isRelativeTo(handle, Material.SPRUCE_LOG) && handle.isEmpty()) { + if (handle.getRelative(BlockFace.DOWN).getType().equals(Material.GRASS_BLOCK) && handle.isEmpty()) { handle.setType(mushroom); placed++; if (placed >= mushroomcount) { @@ -55,7 +54,6 @@ public void populate(final World world, final Random random, final Chunk source) } } } - } } } @@ -69,16 +67,11 @@ private boolean isRelativeTo(final Block block, final Material material) { } private int getHighestEmptyBlockYAtIgnoreTreesAndFoliage(final World w, final int x, final int z) { - for (int y = w.getMaxHeight(); y >= 1; y--) { + for (int y = w.getHighestBlockYAt(x, z); y >= 1; y--) { final Block handle = w.getBlockAt(x, y - 1, z); final Material id = handle.getType(); - if (id != Material.AIR && id != Material.OAK_LOG - && id != Material.BIRCH_LOG && id != Material.JUNGLE_LOG - && id != Material.SPRUCE_LOG && id != Material.DARK_OAK_LOG - && id != Material.ACACIA_LOG && id != Material.OAK_LEAVES - && id != Material.BIRCH_LEAVES && id != Material.JUNGLE_LEAVES - && id != Material.SPRUCE_LEAVES && id != Material.DARK_OAK_LEAVES - && id != Material.ACACIA_LEAVES) { + if (id != Material.AIR && id != Material.SPRUCE_LOG + && id != Material.SPRUCE_LEAVES) { return y; } } diff --git a/src/eu/over9000/nordic/populators/PopulatorOres.java b/src/eu/over9000/nordic/populators/PopulatorOres.java index bdee26f..7ab23b6 100644 --- a/src/eu/over9000/nordic/populators/PopulatorOres.java +++ b/src/eu/over9000/nordic/populators/PopulatorOres.java @@ -36,7 +36,9 @@ public class PopulatorOres extends BlockPopulator { private static final int[] iterations = new int[]{10, 16, 20, 20, 2, 8, 1, 1, 1}; private static final int[] amount = new int[]{32, 32, 16, 8, 8, 7, 7, 6}; - private static final Material[] type = new Material[]{Material.GRAVEL, Material.SAND, Material.COAL_ORE, Material.IRON_ORE, Material.GOLD_ORE, Material.REDSTONE_ORE, Material.DIAMOND_ORE, Material.LAPIS_ORE}; + private static final Material[] type = new Material[]{Material.GRAVEL, + Material.SAND, Material.COAL_ORE, Material.IRON_ORE, Material.GOLD_ORE, + Material.REDSTONE_ORE, Material.DIAMOND_ORE, Material.LAPIS_ORE}; private static final int[] maxHeight = new int[]{128, 45, 128, 128, 32, 32, 32, 32, 16, 16, 32}; /** diff --git a/src/eu/over9000/nordic/populators/PopulatorTrees.java b/src/eu/over9000/nordic/populators/PopulatorTrees.java index 9af7657..beefac7 100644 --- a/src/eu/over9000/nordic/populators/PopulatorTrees.java +++ b/src/eu/over9000/nordic/populators/PopulatorTrees.java @@ -32,8 +32,8 @@ public void populate(final World world, final Random random, final Chunk source) final int treecount = random.nextInt(3); for (int t = 0; t <= treecount; t++) { - final int tree_x = random.nextInt(15); - final int tree_z = random.nextInt(15); + final int tree_x = 4 + random.nextInt(8); + final int tree_z = 4 + random.nextInt(8); final Block block = world.getHighestBlockAt(tree_x + source.getX() * 16, tree_z + source.getZ() * 16); final Location high = block.getLocation(); diff --git a/src/eu/over9000/nordic/populators/PopulatorWindMill.java b/src/eu/over9000/nordic/populators/PopulatorWindMill.java index 9c78015..e2753cc 100644 --- a/src/eu/over9000/nordic/populators/PopulatorWindMill.java +++ b/src/eu/over9000/nordic/populators/PopulatorWindMill.java @@ -6,6 +6,10 @@ package eu.over9000.nordic.populators; import eu.over9000.nordic.Nordic; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Random; import ops.zhehe.Util.NordicSchematic; import ops.zhehe.Util.Tools; @@ -15,16 +19,57 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.generator.BlockPopulator; +import org.bukkit.scheduler.BukkitRunnable; /** * - * @author zhiqiang.hao + * @author zhehe */ public class PopulatorWindMill extends BlockPopulator { private static NordicSchematic[] windmill = null; private Nordic plugin; + private static class Node { + public int x, z; + public Node(int x, int z) { + this.x = x; + this.z = z; + } + } + + private final static int DISTANCE = 10; + private final static int MAX_SIZE = 8; + + private final static Map> dict = new HashMap<>(); + + private boolean isValid(World world, int chunkX, int chunkZ) { + synchronized(dict) { + String name = world.getName(); + if(dict.get(name) == null) { + List l = new ArrayList<>(); + l.add(new Node(chunkX, chunkZ)); + dict.put(name, l); + return true; + } + List list = dict.get(name); + for(Node n : list) { + int dx = chunkX - n.x; + int dz = chunkZ - n.z; + dx = dx > 0 ? dx : -dx; + dz = dz > 0 ? dz : -dz; + int dis = dx + dz; + + if(dis < DISTANCE) return false; + } + list.add(new Node(chunkX, chunkZ)); + if(list.size() > MAX_SIZE) { + list.remove(0); + } + return true; + } + } + public PopulatorWindMill(Nordic p) { plugin = p; if(windmill == null) { @@ -42,7 +87,20 @@ public PopulatorWindMill(Nordic p) { @Override public void populate(final World world, final Random random, final Chunk source) { - if (random.nextInt(2000) < 10) { + if(random.nextInt(2000) >= 10) return; + if(!isValid(world, source.getX(), source.getZ())) return; + BukkitRunnable run = new BukkitRunnable() { + @Override + public void run() { + place(world, random, source); + this.cancel(); + } + }; + run.runTaskTimer(Nordic.instance, 1, 1); + } + + private void place(final World world, final Random random, final Chunk source) { + if (true) { int x = random.nextInt(15); int z = random.nextInt(15); int realx = source.getX() * 16 + x; diff --git a/src/me/zhehe/nordic/Config.java b/src/me/zhehe/nordic/Config.java new file mode 100644 index 0000000..fa9e96f --- /dev/null +++ b/src/me/zhehe/nordic/Config.java @@ -0,0 +1,64 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package me.zhehe.nordic; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +/** + * + * @author Zhehe + */ +public class Config { + private static class ConfigFile { + public boolean GenerateWindMill = true; + } + + public static ConfigFile config = new ConfigFile(); + + public static boolean generateWindMill() { + return config.GenerateWindMill; + } + + public static void reload(JavaPlugin plugin) { + File dir = plugin.getDataFolder(); + if(!dir.exists()) dir.mkdir(); + + File file = new File(plugin.getDataFolder().toString() + File.separator + "config.json"); + if(file.exists()) { + try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"))) { + StringBuilder sb = new StringBuilder(); + String line = reader.readLine(); + while (line != null) { + sb.append(line); + line = reader.readLine(); + } + config = (new Gson()).fromJson(sb.toString(), ConfigFile.class); + } catch (Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "[NordicReload] Error while loading config file."); + return; + } + } + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + String json = gson.toJson(config); + try(OutputStreamWriter oStreamWriter = new OutputStreamWriter(new FileOutputStream(file), "utf-8")) { + oStreamWriter.append(json); + oStreamWriter.close(); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "[NordicReload] Error while saving config file."); + } + } +} diff --git a/src/me/zhehe/nordic/MathHelper.java b/src/me/zhehe/nordic/MathHelper.java new file mode 100644 index 0000000..3d4fe74 --- /dev/null +++ b/src/me/zhehe/nordic/MathHelper.java @@ -0,0 +1,54 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package me.zhehe.nordic; + +@SuppressWarnings("cast") +public class MathHelper { + + public static final float PI = 3.1415927F; + private static float SIN_TABLE[]; + + static { + SIN_TABLE = new float[0x10000]; + for(int i = 0; i < 0x10000; i++) { + SIN_TABLE[i] = (float)Math.sin((i * Math.PI * 2D) / 65536D); + } + } + + public static float sin(float f) { + return SIN_TABLE[(int)(f * 10430.38F) & 0xffff]; + } + + public static float cos(float f) { + return SIN_TABLE[(int)(f * 10430.38F + 16384F) & 0xffff]; + } + + public static float sqrt(float f) { + return (float)Math.sqrt(f); + } + + public static float sqrt(double d) { + return (float)Math.sqrt(d); + } + + public static int floor(float f) { + int i = (int)f; + return f >= (float)i ? i : i - 1; + } + + public static int floor(double d) { + int i = (int)d; + return d >= (double)i ? i : i - 1; + } + + public static float abs(float f) { + return f < 0.0F ? -f : f; + } + + public static double clamp(double f, double f1, double f2) { + return f < f1 ? f1 : (f > f2 ? f2 : f); + } +} diff --git a/src/me/zhehe/nordic/NordicPopulator.java b/src/me/zhehe/nordic/NordicPopulator.java new file mode 100644 index 0000000..2eaf7d0 --- /dev/null +++ b/src/me/zhehe/nordic/NordicPopulator.java @@ -0,0 +1,69 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package me.zhehe.nordic; + +import eu.over9000.nordic.Nordic; +import java.util.Random; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.generator.BlockPopulator; + +/** + * + * @author Zhehe + */ +public class NordicPopulator extends BlockPopulator { + @Override + public void populate(final World world, final Random random, final Chunk source) { + int chunkX = source.getX(), chunkZ = source.getZ(); + if( + isValidChunk(world, chunkX - 1, chunkZ - 1) > 0 && + isValidChunk(world, chunkX - 1, chunkZ) > 0 && + isValidChunk(world, chunkX - 1, chunkZ + 1) > 0 && + isValidChunk(world, chunkX, chunkZ - 1) > 0 && + isValidChunk(world, chunkX, chunkZ + 1) > 0 && + isValidChunk(world, chunkX + 1, chunkZ - 1) > 0 && + isValidChunk(world, chunkX + 1, chunkZ) > 0 && + isValidChunk(world, chunkX + 1, chunkZ + 1) > 0 + ) + actualPopulate(world, random, source, true); + } + + private void actualPopulate(final World world, final Random random, final Chunk source, final boolean spread) { + for(BlockPopulator bp : Nordic.populators) { + bp.populate(world, random, source); + } + source.getBlock(1, 0, 1).setType(Material.BEDROCK); + if(spread) { + int chunkX = source.getX(), chunkZ = source.getZ(); + if(isValidChunk(world, chunkX - 1, chunkZ - 1) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX - 1, chunkZ - 1), false); + if(isValidChunk(world, chunkX - 1, chunkZ) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX - 1, chunkZ), false); + if(isValidChunk(world, chunkX - 1, chunkZ + 1) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX - 1, chunkZ + 1), false); + + if(isValidChunk(world, chunkX, chunkZ - 1) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX, chunkZ - 1), false); + if(isValidChunk(world, chunkX, chunkZ + 1) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX, chunkZ + 1), false); + + if(isValidChunk(world, chunkX + 1, chunkZ - 1) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX + 1, chunkZ - 1), false); + if(isValidChunk(world, chunkX + 1, chunkZ) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX + 1, chunkZ), false); + if(isValidChunk(world, chunkX + 1, chunkZ + 1) == 1) + actualPopulate(world, random, world.getChunkAt(chunkX + 1, chunkZ + 1), false); + } + } + + private int isValidChunk(final World world, final int chunkX, int chunkZ) { + if(!world.isChunkGenerated(chunkX, chunkZ)) return 0; + if(world.getChunkAt(chunkX, chunkZ).getBlock(1, 0, 1).getType() == Material.GLASS) return 1; + return 2; + } +} diff --git a/src/me/zhehe/nordic/WorldGenBaseOld.java b/src/me/zhehe/nordic/WorldGenBaseOld.java new file mode 100644 index 0000000..68ca5da --- /dev/null +++ b/src/me/zhehe/nordic/WorldGenBaseOld.java @@ -0,0 +1,30 @@ +package me.zhehe.nordic; + +import java.util.Random; +import org.bukkit.World; +import org.bukkit.generator.ChunkGenerator; + +public abstract class WorldGenBaseOld { + protected int maxGenerationRadius; + protected Random rand; + + public WorldGenBaseOld() { + maxGenerationRadius = 8; + rand = new Random(); + } + + public void generate(World world, int generatedChunkX, int generatedChunkZ, ChunkGenerator.ChunkData data) { + int radius = maxGenerationRadius; + rand.setSeed(world.getSeed()); + long l = (rand.nextLong() / 2L) * 2L + 1L; + long l1 = (rand.nextLong() / 2L) * 2L + 1L; + for(int structureOriginXhunkX = generatedChunkX - radius; structureOriginXhunkX <= generatedChunkX + radius; structureOriginXhunkX++) { + for(int structureOriginChunkZ = generatedChunkZ - radius; structureOriginChunkZ <= generatedChunkZ + radius; structureOriginChunkZ++) { + rand.setSeed((long)structureOriginXhunkX * l + (long)structureOriginChunkZ * l1 ^ world.getSeed()); + generate(world, structureOriginXhunkX, structureOriginChunkZ, generatedChunkX, generatedChunkZ, data); + } + } + } + + protected abstract void generate(World world, int structureOriginChunkX, int structureOriginChunkZ, int generatedChunkX, int generatedChunkZ, ChunkGenerator.ChunkData data); +} diff --git a/src/me/zhehe/nordic/WorldGenCavesOld.java b/src/me/zhehe/nordic/WorldGenCavesOld.java new file mode 100644 index 0000000..a67a1f4 --- /dev/null +++ b/src/me/zhehe/nordic/WorldGenCavesOld.java @@ -0,0 +1,231 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package me.zhehe.nordic; + +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.generator.ChunkGenerator; + +import java.util.Random; +import static me.zhehe.nordic.MathHelper.cos; +import static me.zhehe.nordic.MathHelper.floor; +import static me.zhehe.nordic.MathHelper.sin; + +public class WorldGenCavesOld extends WorldGenBaseOld { + + public static final double MIN_HORIZONTAL_SIZE = 1.5D; + + protected void generateDefaultBranch(int generatedChunkX, int generatedChunkZ, ChunkGenerator.ChunkData data, double structureOriginBlockX, double structureOriginBlockY, double structureOriginBlockZ) { + generateBranch( + generatedChunkX, generatedChunkZ, + data, + structureOriginBlockX, structureOriginBlockY, structureOriginBlockZ, + 1.0F + rand.nextFloat() * 6F, 0.0F, 0.0F, + -1, -1, 0.3D); + } + + protected void generateBranch(int generatedChunkX, int generatedChunkZ, + ChunkGenerator.ChunkData data, + double currentBlockX, double currentBlockY, double currentBlockZ, + float maxHorizontalSize, float directionAngleHorizontal, float directionAngleVertical, + int currentCaveSystemRadius, int maxCaveSystemRadius, double verticalCaveSizeMultiplier) { + + double generatedChunkCenterX = generatedChunkX * 16 + 8; + double generatedChunkCenterZ = generatedChunkZ * 16 + 8; + float directionHorizontalChange = 0.0F; + float directionVerticalChange = 0.0F; + Random random = new Random(rand.nextLong()); + //negative means not generated yet + if (maxCaveSystemRadius <= 0) { + int maxBlockRadius = maxGenerationRadius * 16 - 16; + maxCaveSystemRadius = maxBlockRadius - random.nextInt(maxBlockRadius / 4); + } + boolean noSplitBranch = false; + if (currentCaveSystemRadius == -1) { + currentCaveSystemRadius = maxCaveSystemRadius / 2; + noSplitBranch = true; + } + int splitDistance = random.nextInt(maxCaveSystemRadius / 2) + maxCaveSystemRadius / 4; + boolean allowSteepCave = random.nextInt(6) == 0; + for (; currentCaveSystemRadius < maxCaveSystemRadius; currentCaveSystemRadius++) { + + //caveRadius grows as we go out of the center + double caveRadiusHorizontal = MIN_HORIZONTAL_SIZE + (double) (sin((float) currentCaveSystemRadius * 3.141593F / (float) maxCaveSystemRadius) * maxHorizontalSize * 1.0f); + double caveRadiusVertical = caveRadiusHorizontal * verticalCaveSizeMultiplier; + + //from sin(alpha)=y/r and cos(alpha)=x/r ==> x = r*cos(alpha) and y = r*sin(alpha) + //always moves by one block in some direction + //x is horizontal radius, y is vertical + float horizontalDirectionSize = cos(directionAngleVertical); + float directionY = sin(directionAngleVertical); + //y is directionZ and is is directionX + currentBlockX += cos(directionAngleHorizontal) * horizontalDirectionSize; + currentBlockY += directionY; + currentBlockZ += sin(directionAngleHorizontal) * horizontalDirectionSize; + if (allowSteepCave) { + directionAngleVertical *= 0.92F; + } else { + directionAngleVertical *= 0.7F; + } + directionAngleVertical += directionVerticalChange * 0.1F; + directionAngleHorizontal += directionHorizontalChange * 0.1F; + + directionVerticalChange *= 0.9F; + directionHorizontalChange *= 0.75F; + directionVerticalChange += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F; + directionHorizontalChange += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4F; + + if (!noSplitBranch && currentCaveSystemRadius == splitDistance && maxHorizontalSize > 1.0F) { + generateBranch(generatedChunkX, generatedChunkZ, data, currentBlockX, currentBlockY, currentBlockZ, + random.nextFloat() * 0.5F + 0.5F, directionAngleHorizontal - 1.570796F, + directionAngleVertical / 3F, currentCaveSystemRadius, maxCaveSystemRadius, 1.0D); + generateBranch(generatedChunkX, generatedChunkZ, data, currentBlockX, currentBlockY, currentBlockZ, + random.nextFloat() * 0.5F + 0.5F, directionAngleHorizontal + 1.570796F, + directionAngleVertical / 3F, currentCaveSystemRadius, maxCaveSystemRadius, 1.0D); + return; + } + if (!noSplitBranch && random.nextInt(4) == 0) { + continue; + } + double chunkCenterToCurrentX = currentBlockX - generatedChunkCenterX; + double chunkCenterToCurrentZ = currentBlockZ - generatedChunkCenterZ; + + if (isCurrentChunkUnreachable(chunkCenterToCurrentX, chunkCenterToCurrentZ, maxCaveSystemRadius, currentCaveSystemRadius, maxHorizontalSize)) { + return; + } + //is cave out of bounds of current chunk? + if (currentBlockX < generatedChunkCenterX - 16D - caveRadiusHorizontal * 2D || + currentBlockZ < generatedChunkCenterZ - 16D - caveRadiusHorizontal * 2D || + currentBlockX > generatedChunkCenterX + 16D + caveRadiusHorizontal * 2D || + currentBlockZ > generatedChunkCenterZ + 16D + caveRadiusHorizontal * 2D) { + continue; + } + int startX = floor(currentBlockX - caveRadiusHorizontal) - generatedChunkX * 16 - 1; + int endX = (floor(currentBlockX + caveRadiusHorizontal) - generatedChunkX * 16) + 1; + int startY = floor(currentBlockY - caveRadiusVertical) - 1; + int endY = floor(currentBlockY + caveRadiusVertical) + 1; + int startZ = floor(currentBlockZ - caveRadiusHorizontal) - generatedChunkZ * 16 - 1; + int endZ = (floor(currentBlockZ + caveRadiusHorizontal) - generatedChunkZ * 16) + 1; + if (startX < 0) { + startX = 0; + } + if (endX > 16) { + endX = 16; + } + if (startY < 1) { + startY = 1; + } + if (endY > 120) { + endY = 120; + } + if (startZ < 0) { + startZ = 0; + } + if (endZ > 16) { + endZ = 16; + } + + if (findWater(data, startX, endX, startY, endY, startZ, endZ)) { + continue; + } + for (int localX = startX; localX < endX; localX++) { + double xDistanceScaled = ((double)(localX + generatedChunkX * 16) + 0.5D - currentBlockX) / caveRadiusHorizontal; + for (int localZ = startZ; localZ < endZ; localZ++) { + double zDistanceScaled = ((double)(localZ + generatedChunkZ * 16) + 0.5D - currentBlockZ) / caveRadiusHorizontal; + boolean hitGrassSurface = false; + if (xDistanceScaled * xDistanceScaled + zDistanceScaled * zDistanceScaled >= 1.0D) { + continue; + } + + for (int localY = endY; localY >= startY; localY--) { + double yDistanceScaled = (((double)localY + 0.5D) - currentBlockY) / caveRadiusVertical; + //yDistanceScaled > -0.7 ==> flattened floor + if (yDistanceScaled > -0.7D && + xDistanceScaled * xDistanceScaled + yDistanceScaled * yDistanceScaled + zDistanceScaled * zDistanceScaled < 1.0D) { + Material previousBlock = data.getType(localX, localY + 1, localZ); + if (previousBlock == Material.GRASS_BLOCK) { + hitGrassSurface = true; + } + if (previousBlock == Material.STONE + || previousBlock == Material.DIRT + || previousBlock == Material.GRASS_BLOCK) { + if (localY < 10) { + data.setBlock(localX, localY + 1, localZ, Material.LAVA); + } else { + data.setBlock(localX, localY + 1, localZ, Material.AIR); + if (hitGrassSurface && data.getType(localX, localY, localZ) == Material.DIRT) { + data.setBlock(localX, localY , localZ, Material.GRASS_BLOCK); + } + } + } + } + + } + } + } + + //why? + if (noSplitBranch) { + break; + } + } + + } + + //returns true of this distance can't be reached even after all remaining iterations + private static boolean isCurrentChunkUnreachable(double distanceToOriginX, double distanceToOriginZ, int maxCaveSystemRadius, int currentCaveSystemRadius, float maxHorizontalSize) { + double blocksLeft = maxCaveSystemRadius - currentCaveSystemRadius; + //even if the exact block can't be reached, the chunk may be reachable by center of the cave + //and cave size must be also included + double bufferDistance = maxHorizontalSize + 2.0F + 16F; + return (distanceToOriginX * distanceToOriginX + distanceToOriginZ * distanceToOriginZ) - blocksLeft * blocksLeft > bufferDistance * bufferDistance; + } + + private boolean findWater(ChunkGenerator.ChunkData data, int startX, int endX, int startY, int endY, int startZ, int endZ) { + for (int xPos = startX; xPos < endX; xPos++) { + for (int zPos = startZ; zPos < endZ; zPos++) { + for (int yPos = endY + 1; yPos >= startY - 1; yPos--) { + if (yPos < 0 || yPos >= 128) { + continue; + } + if (data.getType(xPos, yPos, zPos) == Material.WATER) { + return true; + } + if (yPos != startY - 1 && xPos != startX && xPos != endX - 1 + && zPos != startZ && zPos != endZ - 1) { + yPos = startY; + } + } + + } + } + return false; + } + + @Override + protected void generate(World world, int structureOriginChunkX, int structureOriginChunkZ, int generatedChunkX, int generatedChunkZ, ChunkGenerator.ChunkData data) { + int attempts = rand.nextInt(rand.nextInt(rand.nextInt(40) + 1) + 1); + if (rand.nextInt(15) != 0) { + attempts = 0; + } + for (int i = 0; i < attempts; i++) { + double structureOriginBlockX = structureOriginChunkX * 16 + rand.nextInt(16); + double structureOriginBlockY = rand.nextInt(rand.nextInt(36) + 8); //120->36 + double structureOriginBlockZ = structureOriginChunkZ * 16 + rand.nextInt(16); + int branches = 1; + if (rand.nextInt(4) == 0) { + generateDefaultBranch(generatedChunkX, generatedChunkZ, data, structureOriginBlockX, structureOriginBlockY, structureOriginBlockZ); + branches += rand.nextInt(4); + } + for (int branch = 0; branch < branches; branch++) { + float directionAndgeHorizontal = rand.nextFloat() * 3.141593F * 2.0F; + float directionAngleVertical = ((rand.nextFloat() - 0.5F) * 2.0F) / 8F; + float maxHorizontalSize = rand.nextFloat() * 2.0F + rand.nextFloat(); + generateBranch(generatedChunkX, generatedChunkZ, data, structureOriginBlockX, structureOriginBlockY, structureOriginBlockZ, maxHorizontalSize, directionAndgeHorizontal, directionAngleVertical, 0, 0, 1.0D); + } + } + } +} diff --git a/src/ops/zhehe/Util/NordicJsonSchematic.java b/src/ops/zhehe/Util/NordicJsonSchematic.java new file mode 100644 index 0000000..205f73a --- /dev/null +++ b/src/ops/zhehe/Util/NordicJsonSchematic.java @@ -0,0 +1,84 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ops.zhehe.Util; + +import com.google.gson.Gson; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; + +/** + * + * @author Zhehe + */ +public class NordicJsonSchematic { + public static class IBlock { + int[] pos = new int[3]; + int state = 0; + } + public IBlock[] blocks = new IBlock[0]; + public int[] size = new int[3]; + public String author = ""; + public String[] palette = new String[0]; + private transient BlockData[] bd = new BlockData[0]; + + private NordicJsonSchematic() { + + } + + public NordicJsonSchematic(InputStream stream) { + try { + load(stream); + } catch (IOException ex) { + this.blocks = null; + } + } + + public Block place(World world, Chunk chunk) { + if(blocks == null) return null; + int x = 2; + int z = 2; + int y = 48; + if(x + size[0] >= 15 && z + size[2] >= 15 && y + size[1] >= 100) return null; + Block res = null; + for(IBlock block : blocks) { + int bx = x + block.pos[0]; + int by = y + block.pos[1]; + int bz = z + block.pos[2]; + chunk.getBlock(bx, by, bz).setBlockData(bd[block.state], true); + if(bd[block.state].getMaterial() == Material.CHEST) res = chunk.getBlock(bx, by, bz); + } + return res; + } + + private void load(InputStream stream) throws IOException { + InputStreamReader isr = new InputStreamReader(stream); + BufferedReader reader = new BufferedReader(isr); + String line; + StringBuilder json = new StringBuilder(); + while( (line=reader.readLine())!=null) { + json.append(line); + } + + NordicJsonSchematic tmp = (new Gson()).fromJson(json.toString(), NordicJsonSchematic.class); + this.blocks = tmp.blocks; + this.author = tmp.author; + this.size = tmp.size; + this.palette = tmp.palette; + + this.bd = new BlockData[palette.length]; + for(int i = 0; i < bd.length; i++) { + bd[i] = Bukkit.createBlockData(palette[i]); + } + } +} diff --git a/src/plugin.yml b/src/plugin.yml index 4f35da1..d8a31ca 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,11 +1,11 @@ name: NordicReload main: eu.over9000.nordic.Nordic -version: 0.2.0 +version: 0.8.0 load: STARTUP loadbefore: [Multiverse-Core, dimension-door, multiworld] author: zhehe api-version: 1.13 -description: Custom Worldgenerator +description: Nordic like world generator commands: nordic: aliases: [n,nord, nrd]