From 2db311759fb31d694345bcde63348fe467cf9136 Mon Sep 17 00:00:00 2001 From: dfsek Date: Tue, 15 Sep 2020 02:00:18 -0700 Subject: [PATCH] Implement ores, begin work on caves. --- pom.xml | 2 +- .../com/dfsek/terra/TerraChunkGenerator.java | 12 +- .../java/com/dfsek/terra/TerraCommand.java | 31 ++++- src/main/java/com/dfsek/terra/TerraTree.java | 72 ++++++++++ .../com/dfsek/terra/UserDefinedCarver.java | 44 +++++++ .../java/com/dfsek/terra/biome/BiomeZone.java | 6 +- .../dfsek/terra/biome/UserDefinedBiome.java | 17 ++- .../terra/biome/UserDefinedDecorator.java | 25 +++- .../com/dfsek/terra/config/BiomeConfig.java | 56 +++++++- .../dfsek/terra/config/BiomeGridConfig.java | 17 ++- .../com/dfsek/terra/config/ConfigUtil.java | 123 ++++++++++++++++-- .../com/dfsek/terra/config/FaunaConfig.java | 100 ++++++++++++++ .../com/dfsek/terra/config/OreConfig.java | 89 +++++++++++++ .../dfsek/terra/config/StructureConfig.java | 41 ++++++ .../com/dfsek/terra/config/WorldConfig.java | 21 +-- .../dfsek/terra/population/CavePopulator.java | 16 +++ .../terra/population/FaunaPopulator.java | 9 +- .../dfsek/terra/population/OrePopulator.java | 34 +++++ .../dfsek/terra/population/TreePopulator.java | 5 - .../terra/structure/MultiPartStructure.java | 4 + src/main/resources/config.yml | 1 - .../trees/dark_oak_large/l_darkoak_0.nbt | Bin 0 -> 5013 bytes .../trees/dark_oak_large/l_darkoak_1.nbt | Bin 0 -> 2818 bytes .../trees/dark_oak_large/l_darkoak_2.nbt | Bin 0 -> 2134 bytes .../trees/dark_oak_large/l_darkoak_3.nbt | Bin 0 -> 1913 bytes .../trees/dark_oak_large/l_darkoak_4.nbt | Bin 0 -> 2245 bytes src/main/resources/trees/dead/dead_0.nbt | Bin 0 -> 516 bytes src/main/resources/trees/dead/dead_1.nbt | Bin 0 -> 1259 bytes src/main/resources/trees/dead/dead_2.nbt | Bin 0 -> 645 bytes src/main/resources/trees/dead/dead_3.nbt | Bin 0 -> 511 bytes .../trees/jungle_large/l_jungle_0.nbt | Bin 0 -> 2019 bytes .../trees/jungle_medium/m_jungle_0.nbt | Bin 0 -> 1061 bytes .../trees/jungle_medium/m_jungle_1.nbt | Bin 0 -> 1023 bytes .../resources/trees/oak_large/l_oak_0.nbt | Bin 0 -> 5479 bytes .../resources/trees/oak_large/l_oak_1.nbt | Bin 0 -> 6890 bytes .../resources/trees/oak_medium/m_oak_0.nbt | Bin 0 -> 1696 bytes .../resources/trees/oak_medium/m_oak_1.nbt | Bin 0 -> 1510 bytes .../resources/trees/oak_medium/m_oak_2.nbt | Bin 0 -> 1159 bytes .../resources/trees/oak_medium/m_oak_3.nbt | Bin 0 -> 2579 bytes .../resources/trees/oak_medium/m_oak_4.nbt | Bin 0 -> 6890 bytes .../resources/trees/oak_small/s_oak_0.nbt | Bin 0 -> 2579 bytes .../trees/spruce_large/l_spruce_0.nbt | Bin 0 -> 3744 bytes .../trees/spruce_large/l_spruce_1.nbt | Bin 0 -> 1288 bytes .../trees/spruce_medium/m_spruce_0.nbt | Bin 0 -> 1011 bytes .../trees/spruce_medium/m_spruce_1.nbt | Bin 0 -> 719 bytes .../trees/spruce_medium/m_spruce_2.nbt | Bin 0 -> 865 bytes .../trees/spruce_medium/m_spruce_3.nbt | Bin 0 -> 898 bytes .../trees/spruce_medium/m_spruce_4.nbt | Bin 0 -> 965 bytes .../trees/spruce_small/s_spruce_0.nbt | Bin 0 -> 688 bytes .../trees/spruce_small/s_spruce_1.nbt | Bin 0 -> 526 bytes .../trees/spruce_small/s_spruce_2.nbt | Bin 0 -> 388 bytes .../trees/spruce_small/s_spruce_3.nbt | Bin 0 -> 396 bytes src/main/resources/world.yml | 18 --- 53 files changed, 670 insertions(+), 73 deletions(-) create mode 100644 src/main/java/com/dfsek/terra/TerraTree.java create mode 100644 src/main/java/com/dfsek/terra/UserDefinedCarver.java create mode 100644 src/main/java/com/dfsek/terra/config/FaunaConfig.java create mode 100644 src/main/java/com/dfsek/terra/config/OreConfig.java create mode 100644 src/main/java/com/dfsek/terra/config/StructureConfig.java create mode 100644 src/main/java/com/dfsek/terra/population/CavePopulator.java create mode 100644 src/main/java/com/dfsek/terra/population/OrePopulator.java create mode 100644 src/main/java/com/dfsek/terra/structure/MultiPartStructure.java create mode 100644 src/main/resources/trees/dark_oak_large/l_darkoak_0.nbt create mode 100644 src/main/resources/trees/dark_oak_large/l_darkoak_1.nbt create mode 100644 src/main/resources/trees/dark_oak_large/l_darkoak_2.nbt create mode 100644 src/main/resources/trees/dark_oak_large/l_darkoak_3.nbt create mode 100644 src/main/resources/trees/dark_oak_large/l_darkoak_4.nbt create mode 100644 src/main/resources/trees/dead/dead_0.nbt create mode 100644 src/main/resources/trees/dead/dead_1.nbt create mode 100644 src/main/resources/trees/dead/dead_2.nbt create mode 100644 src/main/resources/trees/dead/dead_3.nbt create mode 100644 src/main/resources/trees/jungle_large/l_jungle_0.nbt create mode 100644 src/main/resources/trees/jungle_medium/m_jungle_0.nbt create mode 100644 src/main/resources/trees/jungle_medium/m_jungle_1.nbt create mode 100644 src/main/resources/trees/oak_large/l_oak_0.nbt create mode 100644 src/main/resources/trees/oak_large/l_oak_1.nbt create mode 100644 src/main/resources/trees/oak_medium/m_oak_0.nbt create mode 100644 src/main/resources/trees/oak_medium/m_oak_1.nbt create mode 100644 src/main/resources/trees/oak_medium/m_oak_2.nbt create mode 100644 src/main/resources/trees/oak_medium/m_oak_3.nbt create mode 100644 src/main/resources/trees/oak_medium/m_oak_4.nbt create mode 100644 src/main/resources/trees/oak_small/s_oak_0.nbt create mode 100644 src/main/resources/trees/spruce_large/l_spruce_0.nbt create mode 100644 src/main/resources/trees/spruce_large/l_spruce_1.nbt create mode 100644 src/main/resources/trees/spruce_medium/m_spruce_0.nbt create mode 100644 src/main/resources/trees/spruce_medium/m_spruce_1.nbt create mode 100644 src/main/resources/trees/spruce_medium/m_spruce_2.nbt create mode 100644 src/main/resources/trees/spruce_medium/m_spruce_3.nbt create mode 100644 src/main/resources/trees/spruce_medium/m_spruce_4.nbt create mode 100644 src/main/resources/trees/spruce_small/s_spruce_0.nbt create mode 100644 src/main/resources/trees/spruce_small/s_spruce_1.nbt create mode 100644 src/main/resources/trees/spruce_small/s_spruce_2.nbt create mode 100644 src/main/resources/trees/spruce_small/s_spruce_3.nbt diff --git a/pom.xml b/pom.xml index 9c6b5c5fc..0ff8088a0 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ org.polydev gaea - 1.5.7 + 1.5.15 diff --git a/src/main/java/com/dfsek/terra/TerraChunkGenerator.java b/src/main/java/com/dfsek/terra/TerraChunkGenerator.java index 3efcbfe71..66461b2f5 100644 --- a/src/main/java/com/dfsek/terra/TerraChunkGenerator.java +++ b/src/main/java/com/dfsek/terra/TerraChunkGenerator.java @@ -3,6 +3,7 @@ package com.dfsek.terra; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.config.WorldConfig; import com.dfsek.terra.population.FaunaPopulator; +import com.dfsek.terra.population.OrePopulator; import com.dfsek.terra.population.TreePopulator; import org.bukkit.Material; import org.bukkit.World; @@ -23,7 +24,9 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { private final PopulationManager popMan = new PopulationManager(); public TerraChunkGenerator() { super(InterpolationType.TRILINEAR); - popMan.attach(new TreePopulator(popMan)); + popMan.attach(new TreePopulator()); + popMan.attach(new FaunaPopulator()); + popMan.attach(new OrePopulator()); } @Override @@ -62,6 +65,11 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { @Override public @NotNull List getDefaultPopulators(@NotNull World world) { - return Arrays.asList(popMan, new FaunaPopulator()); + return Collections.singletonList(popMan); + } + + @Override + public boolean shouldGenerateStructures() { + return true; } } diff --git a/src/main/java/com/dfsek/terra/TerraCommand.java b/src/main/java/com/dfsek/terra/TerraCommand.java index c5d97ca7e..599aef028 100644 --- a/src/main/java/com/dfsek/terra/TerraCommand.java +++ b/src/main/java/com/dfsek/terra/TerraCommand.java @@ -3,12 +3,17 @@ package com.dfsek.terra; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.config.ConfigUtil; +import com.dfsek.terra.config.OreConfig; +import org.bukkit.block.Block; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.polydev.gaea.profiler.WorldProfiler; +import org.polydev.gaea.structures.NMSStructure; + +import java.util.Random; public class TerraCommand implements CommandExecutor { @Override @@ -21,6 +26,7 @@ public class TerraCommand implements CommandExecutor { case "biome": if(!(sender instanceof Player)) return false; sender.sendMessage("You are in " + ((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation())).getConfig().getFriendlyName()); + break; case "profile": if(! (sender instanceof Player)) { sender.sendMessage("Command is for players only."); @@ -46,7 +52,30 @@ public class TerraCommand implements CommandExecutor { return true; } } else sender.sendMessage("World is not a Terra world!"); - } + break; + case "get_data": + if(! (sender instanceof Player)) { + sender.sendMessage("Command is for players only."); + return true; + } + Block b = ((Player) sender).getTargetBlockExact(25); + sender.sendMessage(b.getBlockData().getAsString()); + //NMSStructure villageBase = new NMSStructure(((Player) sender).getLocation(), NMSStructure.getAsTag(Class.forName("net.minecraft.server.v1_16_R2.AbstractDragonController").getResourceAsStream("/data/minecraft/structures/village/plains/town_centers/plains_fountain_01.nbt"))); + //villageBase.paste(); + break; + case "ore": + if(! (sender instanceof Player)) { + sender.sendMessage("Command is for players only."); + return true; + } + Block bl = ((Player) sender).getTargetBlockExact(25); + OreConfig ore = ConfigUtil.getOre(args[1]); + if(ore == null) { + sender.sendMessage("Unable to find Ore"); + return true; + } + ore.doVein(bl.getLocation(), new Random()); + } return true; } } diff --git a/src/main/java/com/dfsek/terra/TerraTree.java b/src/main/java/com/dfsek/terra/TerraTree.java new file mode 100644 index 000000000..2805057dd --- /dev/null +++ b/src/main/java/com/dfsek/terra/TerraTree.java @@ -0,0 +1,72 @@ +package com.dfsek.terra; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.plugin.java.JavaPlugin; +import org.polydev.gaea.structures.NMSStructure; +import org.polydev.gaea.tree.Tree; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public enum TerraTree implements Tree { + SPRUCE_SMALL("/trees/spruce_small/s_spruce_", 4, Arrays.asList(Material.PODZOL, Material.GRASS_BLOCK, Material.DIRT)), + SPRUCE_MEDIUM("/trees/spruce_medium/m_spruce_", 5, Arrays.asList(Material.PODZOL, Material.GRASS_BLOCK, Material.DIRT)), + SPRUCE_LARGE("/trees/spruce_large/l_spruce_", 2, Arrays.asList(Material.PODZOL, Material.GRASS_BLOCK, Material.DIRT)), + OAK_SMALL("/trees/oak_small/s_oak_", 1, Arrays.asList(Material.GRASS_BLOCK, Material.DIRT)), + OAK_MEDIUM("/trees/oak_medium/m_oak_", 5, Arrays.asList(Material.GRASS_BLOCK, Material.DIRT)), + OAK_LARGE("/trees/oak_large/l_oak_", 2, Arrays.asList(Material.GRASS_BLOCK, Material.DIRT)), + JUNGLE_MEDIUM("/trees/jungle_medium/m_jungle_", 2, Arrays.asList(Material.GRASS_BLOCK, Material.DIRT)), + JUNGLE_LARGE("/trees/jungle_large/l_jungle_", 1, Arrays.asList(Material.GRASS_BLOCK, Material.DIRT)), + DEAD("/trees/dead/dead_", 4, Arrays.asList(Material.PODZOL, Material.GRASS_BLOCK, Material.DIRT, Material.COARSE_DIRT, Material.SAND, Material.RED_SAND)), + DARK_OAK_LARGE("/trees/dark_oak_large/l_darkoak_", 5, Arrays.asList(Material.PODZOL, Material.GRASS_BLOCK, Material.DIRT, Material.COARSE_DIRT, Material.SAND, Material.RED_SAND)); + + private final String filePath; + private final int permutations; + private final List validSpawns; + + private final Map loadedStructures = new HashMap<>(); + TerraTree(String directory, int number, List validSpawns) { + this.filePath = directory; + this.permutations = number; + this.validSpawns = validSpawns; + for(int i = 0; i < number; i++) { + Bukkit.getLogger().info("[Terra] Loading tree " + directory + i + " to memory."); + loadedStructures.put(directory+i, NMSStructure.getAsTag(TerraTree.class.getResourceAsStream(directory + i + ".nbt"))); + } + } + + private NMSStructure getInstance(Location origin, Random random) { + return new NMSStructure(origin, loadedStructures.get(filePath + random.nextInt(permutations))); + } + + @Override + public void plant(Location location, Random random, boolean b, JavaPlugin javaPlugin) { + if(!validSpawns.contains(location.clone().subtract(0, 1, 0).getBlock().getType())) return; + NMSStructure temp = getInstance(location, random); + int[] size = temp.getDimensions(); + switch(random.nextInt(4)) { + case 0: + temp.setOrigin(new Location(location.getWorld(), (int) (location.getBlockX()- (size[0]/2f)), location.getBlockY()-1, (int) (location.getBlockZ()- (size[2]/2f)))); + break; + case 1: + temp.setRotation(90); + temp.setOrigin(new Location(location.getWorld(), (int) (location.getBlockX()+ (size[0]/2f)), location.getBlockY()-1, (int) (location.getBlockZ()- (size[2]/2f)))); + break; + case 2: + temp.setRotation(180); + temp.setOrigin(new Location(location.getWorld(), (int) (location.getBlockX()+ (size[0]/2f)), location.getBlockY()-1, (int) (location.getBlockZ()+ (size[2]/2f)))); + break; + case 3: + temp.setRotation(270); + temp.setOrigin(new Location(location.getWorld(), (int) (location.getBlockX()- (size[0]/2f)), location.getBlockY()-1, (int) (location.getBlockZ()+ (size[2]/2f)))); + break; + } + temp.paste(); + //location.getBlock().setType(Material.GOLD_BLOCK); + } +} diff --git a/src/main/java/com/dfsek/terra/UserDefinedCarver.java b/src/main/java/com/dfsek/terra/UserDefinedCarver.java new file mode 100644 index 000000000..c20333fe4 --- /dev/null +++ b/src/main/java/com/dfsek/terra/UserDefinedCarver.java @@ -0,0 +1,44 @@ +package com.dfsek.terra; + +import com.dfsek.terra.config.BiomeConfig; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.util.Vector; +import org.polydev.gaea.world.carving.Carver; +import org.polydev.gaea.world.carving.Worm; + +import java.util.Random; + +public class UserDefinedCarver extends Carver { + private final int chance; + private final int minLength; + private final int maxLength; + public UserDefinedCarver(ConfigurationSection config) { + super(config.getInt("y.min"), config.getInt("y.max")); + this.chance = config.getInt("chance"); + minLength = config.getInt("length.min"); + maxLength = config.getInt("length.max"); + + } + + @Override + public Worm getWorm(long l, Vector vector) { + return null; + } + + @Override + public boolean isChunkCarved(Random random) { + return random.nextInt(100) < chance; + } + + private static class UserDefinedWorm extends Worm { + + public UserDefinedWorm(int length, Random r, Vector origin) { + super(length, r, origin); + } + + @Override + public void step() { + + } + } +} diff --git a/src/main/java/com/dfsek/terra/biome/BiomeZone.java b/src/main/java/com/dfsek/terra/biome/BiomeZone.java index 2a5ec3e5d..aa0399c2c 100644 --- a/src/main/java/com/dfsek/terra/biome/BiomeZone.java +++ b/src/main/java/com/dfsek/terra/biome/BiomeZone.java @@ -16,7 +16,7 @@ public class BiomeZone { private static final double[] normalMap = new double[] {-0.35662081837654114D, -0.30661869049072266D, -0.27095329761505127D, -0.24149227142333984D, -0.21537694334983826D, -0.19166918098926544D, -0.16956785321235657D, -0.14864568412303925D, -0.12845154106616974D, -0.10894706845283508D, -0.08996972441673279D, -0.0715663805603981D, -0.053535036742687225D, -0.03580872714519501D, -0.01817353256046772D, -7.577221258543432E-4D, 0.016616813838481903D, 0.03416096046566963D, 0.05187138542532921D, 0.06989025324583054D, 0.08827653527259827D, 0.10723070055246353D, 0.12675245106220245D, 0.14694781601428986D, 0.16793397068977356D, 0.18999846279621124D, 0.2138010412454605D, 0.24002985656261444D, 0.2696261405944824D, 0.30540621280670166D, 0.35551881790161133D, 0.653269350528717D}; - public BiomeZone(World w, float freq) { + private BiomeZone(World w, float freq) { this.w = w; this.noise = new FastNoise((int) w.getSeed()+2); noise.setNoiseType(FastNoise.NoiseType.SimplexFractal); @@ -31,11 +31,11 @@ public class BiomeZone { this.grids = grids; } - public BiomeGrid getGrid(int x, int z) { + protected BiomeGrid getGrid(int x, int z) { return grids[normalize(noise.getSimplexFractal(x, z))]; } - public static BiomeZone fromWorld(World w) { + protected static BiomeZone fromWorld(World w) { if(zones.containsKey(w)) return zones.get(w); else return new BiomeZone(w, WorldConfig.fromWorld(w).zoneFreq); } diff --git a/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java b/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java index 0a5dda37e..df4069c3f 100644 --- a/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java +++ b/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java @@ -4,6 +4,7 @@ import com.dfsek.terra.config.BiomeConfig; import com.dfsek.terra.config.ConfigUtil; import org.bukkit.Bukkit; import org.bukkit.block.data.BlockData; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.polydev.gaea.biome.Biome; import org.polydev.gaea.biome.BiomeTerrain; @@ -26,7 +27,7 @@ public class UserDefinedBiome implements Biome { private final UserDefinedGenerator gen; private final BiomeConfig config; private final UserDefinedDecorator decorator; - public UserDefinedBiome(BiomeConfig config) throws ParseException { + public UserDefinedBiome(BiomeConfig config) throws ParseException, InvalidConfigurationException { this.config = config; TreeMap paletteMap = new TreeMap<>(); for(Map e : config.getMapList("palette")) { @@ -34,14 +35,20 @@ public class UserDefinedBiome implements Biome { try { if(((String) entry.getKey()).startsWith("BLOCK:")) { try { - paletteMap.put((Integer) entry.getValue(), new BlockPalette().addBlockData(new ProbabilityCollection().add(Bukkit.createBlockData((String) entry.getKey()), 1), 1)); + paletteMap.put((Integer) entry.getValue(), new BlockPalette().addBlockData(new ProbabilityCollection().add(Bukkit.createBlockData(((String) entry.getKey()).substring(6)), 1), 1)); } catch(IllegalArgumentException ex) { - Bukkit.getLogger().severe("SEVERE configuration error for BlockPalettes in biome" + config.getFriendlyName() + ", ID: " + config.getBiomeID() + ". BlockData " + entry.getKey() + " is invalid!"); + throw new InvalidConfigurationException("SEVERE configuration error for BlockPalettes in biome " + config.getFriendlyName() + ", ID: " + config.getBiomeID() + ". BlockData " + entry.getKey() + " is invalid!"); + } + } + else { + try { + paletteMap.put((Integer) entry.getValue(), ConfigUtil.getPalette((String) entry.getKey()).getPalette()); + } catch(NullPointerException ex) { + throw new InvalidConfigurationException("SEVERE configuration error for BlockPalettes in biome " + config.getFriendlyName() + ", ID: " + config.getBiomeID() + "\n\nPalette " + entry.getKey() + " cannot be found!"); } } - else paletteMap.put((Integer) entry.getValue(), ConfigUtil.getPalette((String) entry.getKey()).getPalette()); } catch(ClassCastException ex) { - Bukkit.getLogger().severe("SEVERE configuration error for BlockPalettes in biome" + config.getFriendlyName() + ", ID: " + config.getBiomeID()); + throw new InvalidConfigurationException("SEVERE configuration error for BlockPalettes in biome" + config.getFriendlyName() + ", ID: " + config.getBiomeID()); } } } diff --git a/src/main/java/com/dfsek/terra/biome/UserDefinedDecorator.java b/src/main/java/com/dfsek/terra/biome/UserDefinedDecorator.java index d70669d83..090f3a21e 100644 --- a/src/main/java/com/dfsek/terra/biome/UserDefinedDecorator.java +++ b/src/main/java/com/dfsek/terra/biome/UserDefinedDecorator.java @@ -1,11 +1,17 @@ package com.dfsek.terra.biome; +import com.dfsek.terra.TerraTree; import com.dfsek.terra.config.BiomeConfig; +import com.dfsek.terra.config.ConfigUtil; +import org.bukkit.Bukkit; import org.bukkit.block.Biome; +import org.bukkit.configuration.InvalidConfigurationException; import org.polydev.gaea.biome.Decorator; import org.polydev.gaea.math.ProbabilityCollection; import org.polydev.gaea.tree.Tree; +import org.polydev.gaea.tree.TreeType; import org.polydev.gaea.world.Fauna; +import org.polydev.gaea.world.FaunaType; import java.util.Map; @@ -20,12 +26,27 @@ public class UserDefinedDecorator extends Decorator { public UserDefinedDecorator(BiomeConfig config) { if(config.contains("fauna")) { for(Map.Entry e : config.getConfigurationSection("fauna").getValues(false).entrySet()) { - fauna.add(Fauna.valueOf(e.getKey()), (Integer) e.getValue()); + try { + Bukkit.getLogger().info("[Terra] Adding " + e.getKey() + " to biome's fauna list with weight " + e.getValue()); + fauna.add(FaunaType.valueOf(e.getKey()), (Integer) e.getValue()); + } catch(IllegalArgumentException ex) { + try { + Bukkit.getLogger().info("[Terra] Is custom fauna: true"); + Fauna faunaCustom = ConfigUtil.getFauna(e.getKey()); + fauna.add(faunaCustom, (Integer) e.getValue()); + } catch(NullPointerException ex2) { + throw new IllegalArgumentException("SEVERE configuration error for fauna in biome " + config.getFriendlyName() + ", ID " + config.getBiomeID() + "\n\nFauna with ID " + e.getKey() + " cannot be found!"); + } + } } } if(config.contains("trees")) { for(Map.Entry e : config.getConfigurationSection("trees").getValues(false).entrySet()) { - trees.add(Tree.valueOf(e.getKey()), (Integer) e.getValue()); + if(e.getKey().startsWith("TERRA:")) { + trees.add(TerraTree.valueOf(e.getKey().substring(6)), (Integer) e.getValue()); + } else { + trees.add(TreeType.valueOf(e.getKey()), (Integer) e.getValue()); + } } } faunaChance = config.getInt("fauna-chance", 0); diff --git a/src/main/java/com/dfsek/terra/config/BiomeConfig.java b/src/main/java/com/dfsek/terra/config/BiomeConfig.java index dfad80417..bfbfd6eb5 100644 --- a/src/main/java/com/dfsek/terra/config/BiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/BiomeConfig.java @@ -2,6 +2,7 @@ package com.dfsek.terra.config; import com.dfsek.terra.biome.UserDefinedBiome; import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; @@ -9,6 +10,11 @@ import org.polydev.gaea.math.parsii.tokenizer.ParseException; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; public class BiomeConfig extends YamlConfiguration { private UserDefinedBiome biome; @@ -16,6 +22,8 @@ public class BiomeConfig extends YamlConfiguration { private String friendlyName; private org.bukkit.block.Biome vanillaBiome; private boolean isEnabled = false; + private final Map ores = new HashMap<>(); + private final Map oreHeights = new HashMap<>(); public BiomeConfig(File file) throws InvalidConfigurationException, IOException { super(); @@ -27,18 +35,26 @@ public class BiomeConfig extends YamlConfiguration { public void load(@NotNull File file) throws InvalidConfigurationException, IOException { isEnabled = false; super.load(file); + if(!contains("id")) throw new InvalidConfigurationException("Biome ID unspecified!"); + this.biomeID = getString("id"); + if(!contains("name")) throw new InvalidConfigurationException("Biome Name unspecified!"); + this.friendlyName = getString("name"); if(!contains("noise-equation")) throw new InvalidConfigurationException("No noise equation included in biome!"); try { this.biome = new UserDefinedBiome(this); } catch(ParseException e) { e.printStackTrace(); - Bukkit.getLogger().severe("Unable to parse noise equation!"); + throw new IllegalArgumentException("Unable to parse noise equation!"); } - if(!contains("id")) throw new InvalidConfigurationException("Biome ID unspecified!"); - this.biomeID = getString("id"); - if(!contains("name")) throw new InvalidConfigurationException("Biome Name unspecified!"); - this.friendlyName = getString("name"); - if(!contains("vanilla")) throw new InvalidConfigurationException("Vanila Biome unspecified!"); + if(contains("ores")) { + ores.clear(); + for(Map.Entry m : getConfigurationSection("ores").getValues(false).entrySet()) { + ores.put(ConfigUtil.getOre(m.getKey()), new MaxMin(((ConfigurationSection) m.getValue()).getInt("min"), ((ConfigurationSection) m.getValue()).getInt("max"))); + oreHeights.put(ConfigUtil.getOre(m.getKey()), new MaxMin(((ConfigurationSection) m.getValue()).getInt("min-height"), ((ConfigurationSection) m.getValue()).getInt("max-height"))); + } + } + + if(!contains("vanilla")) throw new InvalidConfigurationException("Vanilla Biome unspecified!"); if(!contains("palette")) throw new InvalidConfigurationException("Palette unspecified!"); try { this.vanillaBiome = org.bukkit.block.Biome.valueOf(getString("vanilla")); @@ -48,6 +64,10 @@ public class BiomeConfig extends YamlConfiguration { isEnabled = true; } + public MaxMin getOreHeight(OreConfig c) { + return oreHeights.get(c); + } + public boolean isEnabled() { return isEnabled; } @@ -67,4 +87,28 @@ public class BiomeConfig extends YamlConfiguration { public org.bukkit.block.Biome getVanillaBiome() { return vanillaBiome; } + + public Map getOres() { + return ores; + } + + public static class MaxMin { + private final int min; + private final int max; + public MaxMin(int min, int max) { + this.max = max; + this.min = min; + } + + public int getMax() { + return max; + } + + public int getMin() { + return min; + } + public int get(Random r) { + return r.nextInt((max-min)+1)+min; + } + } } diff --git a/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java b/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java index e47db1f0b..f98b161ad 100644 --- a/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java +++ b/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java @@ -17,7 +17,7 @@ public class BiomeGridConfig extends YamlConfiguration { private String gridID; private String friendlyName; private boolean isEnabled = false; - private World world; + private final World world; private final UserDefinedBiome[][] gridRaw = new UserDefinedBiome[16][16]; public BiomeGridConfig(File file, World w) throws IOException, InvalidConfigurationException { @@ -29,20 +29,25 @@ public class BiomeGridConfig extends YamlConfiguration { public void load(@NotNull File file) throws IOException, InvalidConfigurationException { isEnabled = false; super.load(file); + if(!contains("id")) throw new InvalidConfigurationException("Grid ID unspecified!"); + this.gridID = getString("id"); + if(!contains("name")) throw new InvalidConfigurationException("Grid Name unspecified!"); + this.friendlyName = getString("name"); if(!contains("grid")) throw new InvalidConfigurationException("Grid not found!"); try { for(int x = 0; x < 16; x++) { for(int z = 0; z < 16; z++) { - gridRaw[x][z] = ConfigUtil.getBiome(((List>) getList("grid")).get(x).get(z)).getBiome(); + try { + gridRaw[x][z] = ConfigUtil.getBiome(((List>) getList("grid")).get(x).get(z)).getBiome(); + } catch(NullPointerException e) { + throw new InvalidConfigurationException("SEVERE configuration error for BiomeGrid " + getFriendlyName() + ", ID: " + getGridID() + "\n\nNo such biome " + ((List>) getList("grid")).get(x).get(z)); + } } } } catch(ClassCastException e) { throw new InvalidConfigurationException("Malformed grid!"); } - if(!contains("id")) throw new InvalidConfigurationException("Grid ID unspecified!"); - this.gridID = getString("id"); - if(!contains("name")) throw new InvalidConfigurationException("Grid Name unspecified!"); - this.friendlyName = getString("name"); + this.grid = new UserDefinedGrid(world, 1f/512, 1f/1024, this);// TODO: custom frequency isEnabled = true; } diff --git a/src/main/java/com/dfsek/terra/config/ConfigUtil.java b/src/main/java/com/dfsek/terra/config/ConfigUtil.java index 42413effd..a0196edb0 100644 --- a/src/main/java/com/dfsek/terra/config/ConfigUtil.java +++ b/src/main/java/com/dfsek/terra/config/ConfigUtil.java @@ -1,5 +1,6 @@ package com.dfsek.terra.config; +import com.dfsek.terra.Terra; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; import org.bukkit.Bukkit; @@ -13,21 +14,49 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.logging.Logger; +import java.util.stream.Collectors; import java.util.stream.Stream; public class ConfigUtil { private static final Map biomes = new HashMap<>(); - + private static final Map ores = new HashMap<>(); private static final Map palettes = new HashMap<>(); + private static final Map faunaConfig = new HashMap<>(); public static void loadConfig(JavaPlugin main) { Logger logger = main.getLogger(); logger.info("Loading config values"); - try (Stream paths = Files.walk(Paths.get(main.getDataFolder() + File.separator + "palettes"))) { + loadOres(main); + + loadPalettes(main); + + loadFauna(main); + + loadBiomes(main); + + + + main.getLogger().info("|--------------------------------------------------|"); + main.getLogger().info("Loaded " + biomes.size() + " biomes."); + main.getLogger().info("Loaded " + palettes.size() + " palettes."); + main.getLogger().info("Loaded " + faunaConfig.size() + " fauna objects."); + main.getLogger().info("|--------------------------------------------------|"); + + WorldConfig.reloadAll(); + } + + private static void loadPalettes(JavaPlugin main) { + Logger logger = main.getLogger(); + palettes.clear(); + File paletteFolder = new File(main.getDataFolder() + File.separator + "palettes"); + paletteFolder.mkdirs(); + try (Stream paths = Files.walk(paletteFolder.toPath())) { paths .filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml")) .forEach(path -> { @@ -37,15 +66,53 @@ public class ConfigUtil { palettes.put(grid.getPaletteID(), grid); logger.info("Friendly name: " + grid.getFriendlyName()); logger.info("ID: " + grid.getPaletteID()); - } catch(IOException | InvalidConfigurationException e) { + } catch(IOException e) { e.printStackTrace(); + } catch(InvalidConfigurationException | IllegalArgumentException e) { + logger.severe("Configuration error for BlockPalette. "); + logger.severe(e.getMessage()); + logger.severe("Correct this before proceeding!"); } }); } catch(IOException e) { e.printStackTrace(); } + } - try (Stream paths = Files.walk(Paths.get(main.getDataFolder() + File.separator + "biomes"))) { + private static void loadFauna(JavaPlugin main) { + Logger logger = main.getLogger(); + faunaConfig.clear(); + File faunaFolder = new File(main.getDataFolder() + File.separator + "fauna"); + faunaFolder.mkdirs(); + try (Stream paths = Files.walk(faunaFolder.toPath())) { + paths + .filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml")) + .forEach(path -> { + try { + logger.info("Loading fauna from " + path.toString()); + FaunaConfig fauna = new FaunaConfig(path.toFile()); + faunaConfig.put(fauna.getID(), fauna); + logger.info("Friendly name: " + fauna.getFriendlyName()); + logger.info("ID: " + fauna.getID()); + } catch(IOException e) { + e.printStackTrace(); + } catch(InvalidConfigurationException | IllegalArgumentException e) { + logger.severe("Configuration error for Fauna. "); + logger.severe(e.getMessage()); + logger.severe("Correct this before proceeding!"); + } + }); + } catch(IOException e) { + e.printStackTrace(); + } + } + + private static void loadBiomes(JavaPlugin main) { + Logger logger = main.getLogger(); + biomes.clear(); + File biomeFolder = new File(main.getDataFolder() + File.separator + "biomes"); + biomeFolder.mkdirs(); + try (Stream paths = Files.walk(biomeFolder.toPath())) { paths .filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml")) .forEach(path -> { @@ -56,18 +123,44 @@ public class ConfigUtil { logger.info("Friendly name: " + biome.getFriendlyName()); logger.info("ID: " + biome.getBiomeID()); logger.info("Noise equation: " + biome.get("noise-equation")); - } catch(IOException | InvalidConfigurationException e) { + } catch(IOException e) { e.printStackTrace(); + } catch(InvalidConfigurationException | IllegalArgumentException e) { + logger.severe("Configuration error for Biome. "); + logger.severe(e.getMessage()); + logger.severe("Correct this before proceeding!"); } }); } catch(IOException e) { e.printStackTrace(); } + } - - - - WorldConfig.reloadAll(); + private static void loadOres(JavaPlugin main) { + Logger logger = main.getLogger(); + ores.clear(); + File oreFolder = new File(main.getDataFolder() + File.separator + "ores"); + oreFolder.mkdirs(); + try (Stream paths = Files.walk(oreFolder.toPath())) { + paths + .filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml")) + .forEach(path -> { + logger.info("Loading ore from " + path.toString()); + try { + OreConfig ore = new OreConfig(path.toFile()); + ores.put(ore.getID(), ore); + logger.info("ID: " + ore.getID()); + } catch(IOException e) { + e.printStackTrace(); + } catch(InvalidConfigurationException | IllegalArgumentException e) { + logger.severe("Configuration error for Ore. "); + logger.severe(e.getMessage()); + logger.severe("Correct this before proceeding!"); + } + }); + } catch(IOException e) { + e.printStackTrace(); + } } public static BiomeConfig getBiome(String id) { @@ -77,4 +170,16 @@ public class ConfigUtil { public static PaletteConfig getPalette(String id) { return palettes.get(id); } + + public static FaunaConfig getFauna(String id) { + return faunaConfig.get(id); + } + + public static OreConfig getOre(String id) { + return ores.get(id); + } + + public static > List getElements(List st, Class clazz) { + return st.stream().map((s) -> E.valueOf(clazz, s)).collect(Collectors.toList()); + } } diff --git a/src/main/java/com/dfsek/terra/config/FaunaConfig.java b/src/main/java/com/dfsek/terra/config/FaunaConfig.java new file mode 100644 index 000000000..67b3d3644 --- /dev/null +++ b/src/main/java/com/dfsek/terra/config/FaunaConfig.java @@ -0,0 +1,100 @@ +package com.dfsek.terra.config; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.math.ProbabilityCollection; +import org.polydev.gaea.world.BlockPalette; +import org.polydev.gaea.world.Fauna; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +public class FaunaConfig extends YamlConfiguration implements Fauna { + private BlockPalette faunaPalette = new BlockPalette(); + private String id; + private String friendlyName; + + List spawnable; + public FaunaConfig(File file) throws IOException, InvalidConfigurationException { + super(); + load(file); + } + + @Override + public void load(@NotNull File file) throws FileNotFoundException, IOException, InvalidConfigurationException { + super.load(file); + if(!contains("blocks")) throw new InvalidConfigurationException("No blocks defined in custom fauna!"); + if(!contains("id")) throw new InvalidConfigurationException("Fauna ID unspecified!"); + if(!contains("name")) throw new InvalidConfigurationException("Fauna name unspecified!"); + if(!contains("spawnable")) throw new InvalidConfigurationException("Fauna spawnable blocks unspecified!"); + + try { + spawnable = ConfigUtil.getElements(getStringList("spawnable"), Material.class); + Bukkit.getLogger().info("[Terra] Added " + spawnable.size() + " items to spawnable list."); + } catch(IllegalArgumentException e) { + throw new InvalidConfigurationException("Invalid material ID in spawnable list: " + e.getMessage()); + } + + faunaPalette = new BlockPalette(); + for(Map m : getMapList("blocks")) { + try { + ProbabilityCollection layer = new ProbabilityCollection<>(); + for(Map.Entry type : ((Map) m.get("materials")).entrySet()) { + layer.add(Bukkit.createBlockData(type.getKey()), type.getValue()); + Bukkit.getLogger().info("[Terra] Added " + type.getKey() + " with probability " + type.getValue()); + } + Bukkit.getLogger().info("[Terra] Added above materials for " + m.get("layers") + " layers."); + faunaPalette.addBlockData(layer, (Integer) m.get("layers")); + } catch(ClassCastException e) { + e.printStackTrace(); + } + } + if(!contains("id")) throw new InvalidConfigurationException("Grid ID unspecified!"); + this.id = getString("id"); + if(!contains("name")) throw new InvalidConfigurationException("Grid Name unspecified!"); + this.friendlyName = getString("name"); + } + + public String getFriendlyName() { + return friendlyName; + } + + public String getID() { + return id; + } + + @Override + public Block getHighestValidSpawnAt(Chunk chunk, int x, int z) { + int y; + for(y = chunk.getWorld().getMaxHeight() - 1; (!spawnable.contains(chunk.getBlock(x, y, z).getType())) && y > 0; y--); + if(y <= 0) return null; + return chunk.getBlock(x, y, z); + } + + @Override + public boolean plant(Location location) { + int size = faunaPalette.getSize(); + for(int i = 0; i < size; i++) { + if(!location.clone().add(0, i+1, 0).getBlock().isEmpty()) return false; + } + for(int i = 0; i < size; i++) { + location.clone().add(0, i+1, 0).getBlock().setBlockData(faunaPalette.getBlockData(size-(i+1), new Random()), false); + } + return true; + } + +} diff --git a/src/main/java/com/dfsek/terra/config/OreConfig.java b/src/main/java/com/dfsek/terra/config/OreConfig.java new file mode 100644 index 000000000..ff0679212 --- /dev/null +++ b/src/main/java/com/dfsek/terra/config/OreConfig.java @@ -0,0 +1,89 @@ +package com.dfsek.terra.config; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.math.FastNoise; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.Random; + +public class OreConfig extends YamlConfiguration { + private BlockData oreData; + private int min; + private int max; + private double deform; + private double deformFrequency; + private String id; + private String friendlyName; + private int h; + List replaceable; + public OreConfig(File file) throws IOException, InvalidConfigurationException { + this.load(file); + } + + @Override + public void load(@NotNull File file) throws IOException, InvalidConfigurationException { + super.load(file); + if(!contains("material")) throw new InvalidConfigurationException("Ore material not found!"); + if(!contains("deform")) throw new InvalidConfigurationException("Ore vein deformation not found!"); + if(!contains("id")) throw new InvalidConfigurationException("Ore ID not found!"); + if(!contains("replace")) throw new InvalidConfigurationException("Ore replaceable materials not found!"); + min = getInt("radius.min", 1); + max = getInt("radius.max", 1); + h = 2; + deform = getDouble("deform"); + deformFrequency = getDouble("deform-frequency"); + this.id = getString("id"); + + try { + replaceable = ConfigUtil.getElements(getStringList("replace"), Material.class); + Bukkit.getLogger().info("[Terra] Added " + replaceable.size() + " items to replaceable list."); + } catch(IllegalArgumentException e) { + throw new InvalidConfigurationException("Invalid material ID in replace list: " + e.getMessage()); + } + + try { + oreData = Bukkit.createBlockData(Objects.requireNonNull(getString("material"))); + } catch(NullPointerException | IllegalArgumentException e) { + throw new InvalidConfigurationException("Invalid ore material: " + getString("material")); + } + } + private int randomInRange(Random r) { + return r.nextInt(max-min+1)+min; + } + public void doVein(Location l, Random r) { + FastNoise ore = new FastNoise(r.nextInt()); + ore.setNoiseType(FastNoise.NoiseType.SimplexFractal); + ore.setFrequency((float) deformFrequency); + int rad = randomInRange(r); + for(int x = -rad; x <= rad; x++) { + for(int y = -rad; y <= rad; y++) { + for(int z = -rad; z <= rad; z++) { + if(l.clone().add(x, y, z).distance(l) < (rad + 0.5) * ((ore.getSimplexFractal(x, y, z)+1)*deform)) { + Block b = l.clone().add(x, y, z).getBlock(); + if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0) b.setBlockData(oreData); + } + } + } + } + } + + public String getID() { + return id; + } + + public String getFriendlyName() { + return friendlyName; + } +} diff --git a/src/main/java/com/dfsek/terra/config/StructureConfig.java b/src/main/java/com/dfsek/terra/config/StructureConfig.java new file mode 100644 index 000000000..e6fb4f4f2 --- /dev/null +++ b/src/main/java/com/dfsek/terra/config/StructureConfig.java @@ -0,0 +1,41 @@ +package com.dfsek.terra.config; + +import com.dfsek.terra.Terra; +import org.bukkit.Location; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.structures.NMSStructure; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class StructureConfig extends YamlConfiguration { + private String id; + private String name; + private Object structure; + private int offset; + public StructureConfig(File file) throws IOException, InvalidConfigurationException { + this.load(file); + } + + @Override + public void load(@NotNull File file) throws IOException, InvalidConfigurationException { + super.load(file); + if(!contains("id")) throw new InvalidConfigurationException("Structure ID unspecified!"); + this.id = getString("id"); + if(!contains("name")) throw new InvalidConfigurationException("Biome Name unspecified!"); + this.name = getString("name"); + this.offset = getInt("offset", 0); + try { + structure = NMSStructure.getAsTag(new FileInputStream(new File(Terra.getInstance().getDataFolder() + File.separator + "structures" + File.separator + "nbt" + File.separator + getString("file")))); + } catch(FileNotFoundException e) { + throw new InvalidConfigurationException("Unable to locate structure file Terra/structures/nbt/" + getString("file")); + } + } + public NMSStructure getInstance(Location origin) { + return new NMSStructure(origin, structure); + } +} diff --git a/src/main/java/com/dfsek/terra/config/WorldConfig.java b/src/main/java/com/dfsek/terra/config/WorldConfig.java index b6dab4143..ed6cda4c7 100644 --- a/src/main/java/com/dfsek/terra/config/WorldConfig.java +++ b/src/main/java/com/dfsek/terra/config/WorldConfig.java @@ -3,6 +3,7 @@ package com.dfsek.terra.config; import com.dfsek.terra.Terra; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedGrid; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -52,7 +53,7 @@ public class WorldConfig { long start = System.nanoTime(); main.getLogger().info("Loading world configuration values for " + w + "..."); FileConfiguration config = new YamlConfiguration(); - try { + try { // Load/create world config file File configFile = new File(main.getDataFolder() + File.separator + "worlds", w.getName() + ".yml"); if(! configFile.exists()) { configFile.getParentFile().mkdirs(); @@ -65,12 +66,16 @@ public class WorldConfig { main.getLogger().severe("Unable to load configuration for world " + w + "."); } + // Get values from config. seaLevel = config.getInt("sea-level", 63); zoneFreq = 1f/config.getInt("frequencies.zone", 1536); freq1 = 1f/config.getInt("frequencies.grid-1", 256); freq2 = 1f/config.getInt("frequencies.grid-2", 512); - try (Stream paths = Files.walk(Paths.get(main.getDataFolder() + File.separator + "grids"))) { + // Load BiomeGrids. + File biomeGridFolder = new File(main.getDataFolder() + File.separator + "grids"); + biomeGridFolder.mkdirs(); + try (Stream paths = Files.walk(biomeGridFolder.toPath())) { paths .filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml")) .forEach(path -> { @@ -80,17 +85,18 @@ public class WorldConfig { biomeGrids.put(grid.getGridID(), grid); main.getLogger().info("Friendly name: " + grid.getFriendlyName()); main.getLogger().info("ID: " + grid.getGridID()); - } catch(IOException | InvalidConfigurationException e) { + } catch(IOException e) { e.printStackTrace(); + } catch(InvalidConfigurationException | IllegalArgumentException e) { + Bukkit.getLogger().severe("[Terra] Configuration error for BiomeGrid. "); + Bukkit.getLogger().severe("[Terra] " + e.getMessage()); + Bukkit.getLogger().severe("[Terra] Correct this before proceeding!"); } }); } catch(IOException e) { e.printStackTrace(); } - - - for(int i = 0; i < 32; i++) { String partName = config.getStringList("grids").get(i); if(partName.startsWith("BIOME:")) { @@ -106,11 +112,8 @@ public class WorldConfig { } else definedGrids[i] = biomeGrids.get(partName).getGrid(); } - configs.put(w, this); - - main.getLogger().info("World load complete. Time elapsed: " + ((double) (System.nanoTime() - start)) / 1000000 + "ms"); } } diff --git a/src/main/java/com/dfsek/terra/population/CavePopulator.java b/src/main/java/com/dfsek/terra/population/CavePopulator.java new file mode 100644 index 000000000..c0924f090 --- /dev/null +++ b/src/main/java/com/dfsek/terra/population/CavePopulator.java @@ -0,0 +1,16 @@ +package com.dfsek.terra.population; + +import org.bukkit.Chunk; +import org.bukkit.World; +import org.bukkit.generator.BlockPopulator; +import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.world.carving.Carver; + +import java.util.Random; + +public class CavePopulator extends BlockPopulator { + @Override + public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { + + } +} diff --git a/src/main/java/com/dfsek/terra/population/FaunaPopulator.java b/src/main/java/com/dfsek/terra/population/FaunaPopulator.java index 1770fe96e..53bc71ac7 100644 --- a/src/main/java/com/dfsek/terra/population/FaunaPopulator.java +++ b/src/main/java/com/dfsek/terra/population/FaunaPopulator.java @@ -1,20 +1,19 @@ package com.dfsek.terra.population; -import com.dfsek.terra.Terra; import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.biome.TerraBiomeGrid; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.generator.BlockPopulator; import org.jetbrains.annotations.NotNull; import org.polydev.gaea.biome.Biome; +import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.world.Fauna; import java.util.Random; -public class FaunaPopulator extends BlockPopulator { +public class FaunaPopulator extends GaeaBlockPopulator { @Override public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { ProfileFuture fauna = TerraProfiler.fromWorld(world).measure("FaunaTime"); @@ -23,9 +22,9 @@ public class FaunaPopulator extends BlockPopulator { Biome biome = TerraBiomeGrid.fromWorld(world).getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z); if(biome.getDecorator().getFaunaChance() <= 0 || random.nextInt(100) > biome.getDecorator().getFaunaChance()) continue; - Fauna item = biome.getDecorator().getFauna().get(random); - Block highest = item.getHighestValidSpawnAt(chunk, x, z); try { + Fauna item = biome.getDecorator().getFauna().get(random); + Block highest = item.getHighestValidSpawnAt(chunk, x, z); if(highest != null) item.plant(highest.getLocation()); } catch(NullPointerException ignored) {} } diff --git a/src/main/java/com/dfsek/terra/population/OrePopulator.java b/src/main/java/com/dfsek/terra/population/OrePopulator.java new file mode 100644 index 000000000..219bb5d31 --- /dev/null +++ b/src/main/java/com/dfsek/terra/population/OrePopulator.java @@ -0,0 +1,34 @@ +package com.dfsek.terra.population; + +import com.dfsek.terra.biome.BiomeZone; +import com.dfsek.terra.biome.TerraBiomeGrid; +import com.dfsek.terra.biome.UserDefinedBiome; +import com.dfsek.terra.config.BiomeConfig; +import com.dfsek.terra.config.OreConfig; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.generator.BlockPopulator; +import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.biome.Biome; +import org.polydev.gaea.population.GaeaBlockPopulator; + +import java.util.Map; +import java.util.Random; + +public class OrePopulator extends GaeaBlockPopulator { + @Override + public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { + Location l = chunk.getBlock(8, 0, 0).getLocation(); + Biome b = TerraBiomeGrid.fromWorld(world).getBiome(l.getBlockX(), l.getBlockZ()); + for(Map.Entry e : ((UserDefinedBiome) b).getConfig().getOres().entrySet()) { + int num = e.getValue().get(random); + for(int i = 0; i < num; i++) { + int x = random.nextInt(16); + int z = random.nextInt(16); + int y = ((UserDefinedBiome) b).getConfig().getOreHeight(e.getKey()).get(random); + e.getKey().doVein(chunk.getBlock(x, y, z).getLocation(), random); + } + } + } +} diff --git a/src/main/java/com/dfsek/terra/population/TreePopulator.java b/src/main/java/com/dfsek/terra/population/TreePopulator.java index ab8020c3c..3e871a78c 100644 --- a/src/main/java/com/dfsek/terra/population/TreePopulator.java +++ b/src/main/java/com/dfsek/terra/population/TreePopulator.java @@ -17,11 +17,6 @@ import org.polydev.gaea.util.WorldUtil; import java.util.Random; public class TreePopulator extends GaeaBlockPopulator { - - public TreePopulator(PopulationManager manager) { - super(manager); - } - @Override public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { ProfileFuture tree = TerraProfiler.fromWorld(world).measure("TreeGenTime"); diff --git a/src/main/java/com/dfsek/terra/structure/MultiPartStructure.java b/src/main/java/com/dfsek/terra/structure/MultiPartStructure.java new file mode 100644 index 000000000..d609071b3 --- /dev/null +++ b/src/main/java/com/dfsek/terra/structure/MultiPartStructure.java @@ -0,0 +1,4 @@ +package com.dfsek.terra.structure; + +public class MultiPartStructure { +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c66974d9d..e69de29bb 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1 +0,0 @@ -noise-equation: "((-((y/96)^2))+1) + (t/2)" \ No newline at end of file diff --git a/src/main/resources/trees/dark_oak_large/l_darkoak_0.nbt b/src/main/resources/trees/dark_oak_large/l_darkoak_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..4c1d6c1110f2b182ee0a940345576ee7458341cd GIT binary patch literal 5013 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 Tlz6o_EFheE_s>l>8yNf@PJ!h% literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/dark_oak_large/l_darkoak_1.nbt b/src/main/resources/trees/dark_oak_large/l_darkoak_1.nbt new file mode 100644 index 0000000000000000000000000000000000000000..abc53fa34ef951666d281c2596cb259a7fb8b59d GIT binary patch literal 2818 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 Lm;;lAX=(ir7Z=1x literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/dark_oak_large/l_darkoak_2.nbt b/src/main/resources/trees/dark_oak_large/l_darkoak_2.nbt new file mode 100644 index 0000000000000000000000000000000000000000..258d62cd91d652901df863770a4c9f0d1b6d4852 GIT binary patch literal 2134 zcmV-c2&wlUiwFP!000000KJ@BZ`(!?g;ydeUPUWKf&Px(fj;-S=u=+<)lmT>iEUU) zZ~wCYsFupp632&U)@cv}LIC5_%$eEQ-Pt9bE~Pe=$D2P7MM~-XdGYwUdi;FSrsi;a zx;fn(j_Lfa&0q$j8H^h*Fr%?kXT((t zUllPu@?_=(7&jI}#+ZVsjh?O0!}DTw@gL9Al6-MoYhg#NnQVuB6&b#&iHT~p%&0N; zwZugAoa-y9=Q610IzuxUr@0q)HloH#svoW~FmBve(|AOCN=0_q*IL+FVxl^%GU||h zaUB*Jn#+lCwNXuY3?-wU_m9p22L*cr_WCn+(le zMm=}Jm)b9KYIT#zxV@kd4BIIuCaSSqrVG}?T&B-pqFQB!^V4MH8H~$eJ27sJYBPLw zg5kN`2|cRch(7~S{XCe_#8pj9m%+Go1B_cYstnDW3}2fJUts33^BJTTu`e;sS35Cf1{1A^ zk>)Nvofm37jOwQswW{`a_O--RW}bqH*40S!kYQ&KcGS5t8u#tQL~D4YXA}(U8HHxG z&YziiztIwNB{VNFZZFsgJ3OYVsa{JH*Lq@#493kJFmCREiOw=D<(bDFjJwmrTwNJE zU|d{9hGsC){>7S?m@C7S6SFqs1;&jj7*`u$+_?!%w8urUgLz^4gi6!~&mA!HImmrW zB{Xwf8kpXdo{iUMo`Yaq ze!#dhKA0=xtIxL@Ptyz;1q)y(s5L-N|r%)blvbkGfmtnpb`A<#|8`am zv>8li#sbWcp~u~4ZbS~%^Gc4LHE%>*>iK(AV;iAa-AD0!S3Ne5h3c_c^Agi#`07o5 zz|7Z{t>}AsEYverj-AH~Ow`Xuv4e56{TQ^#fLv?oGHDQTqGnn4Y zK`<_MFz)=`rKfv}>eZt)6HIh=i1Gub&CoN?5BDu#=IhwFz_|M;FgxR`7y04X!MOZ@ zna@FWcHlY4{RSAfFN5ha?DS@B0W+HM8bp57`68NMV9E?%u7?EEm^_1VXEZRK$j-V*g>=b-?M>n zv4h!}@xt6#nK=l?J<}{iTV5TS z?*>zvxdX;MTL1z_fS zxbFqi8ao(|=v_6|!@dfkN8P~=!MKBIO#KuhF4j|uxKtlCP(3f%arIng#8nE-s{gs1 zXUu+4iMUvECE{XVm559ANE{dU#$cj*QI37d*I?$(M%1BtXMp2Ucb=?S-Dk39buW5Z z%Q7^(XC+{wUV`INeGB_if9uM=IEP?%Mo%Ngi|sVR7mr0N>?|?vJ##QozrlJ`-@>u0 zeK}e)!MObtjJvz&gl6@QBJ1HC_Ck-k*Wz_U-LtV~^-P?7acvC3j@k#eq(|+im-ooc znpp@&t>Ns8_ewDC{W>t6u~SWq+bb)fS*@9u{w6qEv1YZ7ZIgeNRA=O{7QWOPb$KTs zSX-ho1>?@beMVfD_mPu-Ce==iTUWb@xgtCD{r=72bUIv~4|S>g@!{_N@NoVw8Jbk? zf4@1V)gO-{${+S`59zbFH@AoDhy5?7?_TX6UcbECzkd1K-QBB1Uu<68Jo>o3KBU#R zP3j(he|-GK;r5iu)5E*NzxF=;&)(V8o5TLs!_gS~!Wo;1JKjIMyFUC+d(Rd3`3Dwf z?LAkV9ftQ1_vMEa_tnP~_a64FzUKz}%||o#9+7_iG41JKi`0L=Kka`yf9vk{ap9`d M-yPMn#Y08_0G5wbApigX literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/dark_oak_large/l_darkoak_3.nbt b/src/main/resources/trees/dark_oak_large/l_darkoak_3.nbt new file mode 100644 index 0000000000000000000000000000000000000000..d4f8299a250e89e005fc1f11229adb099c9ea8d9 GIT binary patch literal 1913 zcmV-<2Zs0`iwFP!000000KJ>rY8*!phI@C;$6bd&o+D?-b*@9Ma%(p72837J zmY*)wKfk%Zd41|r+Wg(6;@$np{-{g;{eBR z0yb{~x;$oy;nvY*j2CB5P9KnC&!wEr3gh{;{96YY&*mtj?3pYlf>~lyg03y`9hqW< z@#0)U9ip5vU{6VOVZPeTs9dx}7t5C?rwhm#GcyRAr_A&sJ`<6{^1d*mldmd}(<+eD z3UbPFu`rdBiz<*Ww3+3?lQU-KGS1}+#6`#69#oP`6&WS8DLbtj8VQD zqik*ia=I%RrEAE{AmTg{hSk`@sI@$0##_rR#JMJG8JT8q*kB$8(~jD7|g}{ zv)So0JE&*YA9hZyHkp~k+G#W6)fn20YuT7y#IPmyU<{4f37fn8Y(#vF**Z1v`EE=Z z(4~4mW2S(dowL54?%pEK#%!JSg??cj8l(DfV^p7DjPl)>Ibe^fje+=%a*Qd&IyFYE zWn;WK0M^DD(+3!}j~S!RWn-p5d}a~nk;Hk8xr|}I!i>V6k=Ts7CK4aqqf)M+O01nt zX4KwmOe5CmHZyA9*b;l#TmtQ3ch4xJ?icUR-2mgwF3@+(moe%bG{!pzJ)0|{3)gZ* zbYV^_qKn;AFg^o0m!IZwqE;IsXIx=M5ocr6dN*bk@iFFd@5Nrd%}gQUV~pyfj2VPI z#*6_u-kFQJU_Ai(#m;xnFJo%qS4V7Kvu6%4J7II5pCszg7!@C5RNjs8`VEZF8q)=A z_U;#0KWl!eTo^NpI1icGh}tkl^=!rzB0k1=?@GKq(-<{JGREskyf}{}KCG9(_^>{~ z^L-@tu-P)67t;!(W`oA4JJC$!u(>G8!J6L%#LDjZw8x1>#c?U6`*rGpcW?iLN!K z3@}ZA>BKrUM$LAbfM3Sc0p`*kyzdy(3!58a^Sr{SJ6cO}!FnXj#hM&7r!_|1iHvE* zx-g~-*fR#?c(W#qA+E2E#BhyKF*HW)8^)-;*O*?^m@(>3ZOoc#(3WYpzmvPrU0`S`^G?gXEP%79rI<3^4%D(uk&i&7}FwRpzmoci3GDh`v#;AFeF{5B+5@*&!dOeac%6DVby_= zK%9+H-zU5va*)~N8dCeuHZy81Z;2c>_Zy)O(Jy0KQL9$>Y93{bI&%x6i_PNDcbqjD zbLl(w0LG{}TS@#{v!@N{Qu8rmF6#$paTW0k;b7t9MDp%p&hSi8J;;#(4cI z#)r)+(RcLAm?2<~>ive~@AJl}Z*q)L=a(^R4H~2FM8L z-<^)c9@I6FT%hk0u?J%~1?(|K<-!=XXU+j#Gm*pQnVw%eqH9f#*VCdsYmE9{Vo&Tr zoA<q$@!`xXmhi1pJFUF?1Cl=K~~3*^EWwI_7M<~7Fa6Q1tgPM@$a zlc>W!Git8h6TjH33H@UIhF6CJi8DL9(Rb{z$G{piM&08^qKnN*yggwG*fRy}nXa(M zo5^6_*BG_W8>8;##;D$S4*0brF=X!$(PpeeW7K*#o0P6HGwPmejCu!D5nXH#M_ugR zJtzN6nIRYK9*1(+eFyzwdnU?Z-$HnD#(?i5@r%tW(VjI%y^EZQF5JgKM}J0b`7 zggudiHP&WX-h2EViDC2Z@aA|vAD_On=~MsX!~MJC!}8x}+f*L@xILxKpN|U49}aJi z>9e=DcgLHD!!PIWUL77@zq~)Ze);?T{i_6j*uJ`b)NyxnOq_(lItAiW literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/dark_oak_large/l_darkoak_4.nbt b/src/main/resources/trees/dark_oak_large/l_darkoak_4.nbt new file mode 100644 index 0000000000000000000000000000000000000000..364e675a7d1e63286ca3a4f6d8ea9f18cd7474bc GIT binary patch literal 2245 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 G5C8!6n*rYd literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/dead/dead_1.nbt b/src/main/resources/trees/dead/dead_1.nbt new file mode 100644 index 0000000000000000000000000000000000000000..a481b1834b0c4c6deb17a28b74e0872c76ddac24 GIT binary patch literal 1259 zcmVwFa?Z4#mEgx(!&HP6RumK{9ZX zUtiLm>k5i|?ir(T2ndGkkLTRikRw{wn8L)<{#zdzW7gL%%WJp(EKJ@X=KZ|yC$k=f zN&mSUu5Kr5Oz?YQqWfWzldO3+3F$;sdDnh3sbZSDUCUn-ALn8N($UP)-*Sspit0KHg z`AINZUJ;R(=2a11>oqDSVrCgFub9Y7)5(`tqQoN%(kTd?g3z&qjwN(TGOv_mwA?kF z!b1o3)Dm8n@LG?|;Cp567<8``Myp|_e$eDhyg*84+_vcx8lFPUsZwrOo^!M=;uF zJx!=rkS-%4=ivbs-Fzu`R)b(pQ2(c?pB^iXDUENjw-d^TMFD zlM*^9p;Hny6b99>atzwrRD@SeFk7O|!l3$G5IQ@8xg_c%bwu@fzIG4{$}9F@&}<}x zPD1EZMDD_9v#~N6!62`ehZt0ue}f@z65 z?<8(zooY1{2JJU4J-pD21+GTu`XdZl%fg_~Ai|($1tAfSFxuWvi&^F)CK%MOh=?a9 zn1skZA#_qA=9KWVj)@2c)zA|0lpYLP?~Mnet#@sHc0}&R`CTgOVr9^}2ne0fF{odu zV^DpBL9>w&Ozy#G&vLcAtYbogVRW>4UKup24N>Qo&}j*sEfMnt!5HU9$~au)nXO~)le9eS4+gx67g&ZW=k-! z)6)Lmv@(WZ0)o+Ib!E^VsUWlk#M z-xBpn9fxKkBbeNS(dK7m(7r_&^tnkG)C*zIo}_e)_Pqj)sR^ca44V0kW6;{!x|eos z(Ry*=!JvK#gZi~2nAmBd+!M#3IZOzhl+ei?qs`&Upl5mo;Z+bimS7skXwTUgFLS~K zFEGdZsPN3%S&!pqdeNDgUytLp6Q7BBJ&xCM@&a=S7;BzBhaAU~zQ7#cbF(wojo_p{ z`I+2Lbxw0{%=h1mJI!5~26)xx`|qlqdI@vvRh-EyI`Og#lihcB{XF-N|3k9I{xuHw z{kVRWH8*khWj~qV>k?G_XZNW$zkb>u`m3?KncrP^v3X&X#ad{_yj34^t^rv^v-oKskzUdEF{j1HN z-~RvZqV?L`AOH3v&0+4WyAbt%M7JM*Ohw*$8r&IgH4Hy_7E$tVJ&Uiad}PW$y1Dzi VAE*6rSgviE`4^sv1XHpv000Q~WM%*W literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/dead/dead_2.nbt b/src/main/resources/trees/dead/dead_2.nbt new file mode 100644 index 0000000000000000000000000000000000000000..fa72bfacaae9d95e746fc7b1c42140fd26f3d1e5 GIT binary patch literal 645 zcmV;00($))iwFP!000000L_?BZ__{!#mDxp|E9nVJ_~2gh!fY!B%9VsYDc!K0B1fp zHr=VBs?2-gM5H~q{q1|R^Tu)OTBH&;bw5KUBJ0{L>tFpn8ywF66~Bs2-%_2_5xA^W%uKJ7Rv2j=Msq1ZPJ&p3q4n zhtB>-i(pWnSufNdq~i%4Wl*2jRT)f9=t$(O9x7w?Fu8(3&lJSy*--AN9!Kcpaalc7 z24%6X+F%O8t026p$h-lWu38zvSp7-0CXfZvaYQ|i(D9K;3C8luBZD$6K&HwxAk%`# z9o173Iwhe~5jxcsIyVG^X0-&FDr04uLTHY3FfDc zjP)F>2_1=kXf`U4X%ZPBm;}rZ^74_f`kY4w%}+(-j&y3GW@XU-j5W|vE%f&o(s6{2 zGS;jrV}1X4LZ^s~HHXTeENY_94ar#dPDU^;GU(aefGm7utR9w;vF<@-tb4E~`lF2X z{A$P^Za}8WSYD1`d}Pq9uFPBFeamHD$t&~o@|{Ea7p5>6-OnF)?RdBy+QaR67t?|taE;h)W)FaHPk fxZ_ImOqx&a+~Ou0OYUe0T}c z+?P#X>g4a^8|k)v+EaPsUrcW>j?i%@bb`Tn!pjq0d9EsZ5)7IP>9`X*R?qEGHL)ucX-BC=21CikXG7N=5vu9=iJrBg}NM|U8 z?iR*tB)l?X-K)x=du$|nX8RezIYrFnKa9UmPif!N`f>pD8mC`eGX-E~8Kxpkc>_}urUG`f z<_g%+jKpv0nHhE}z#z?uiNsFrv{N|r6b@gOof_EDdW2~VrgYdTl^v}o0y{Z|=@F(S zOykhg06R!e<%p|t=+Sm^jK@xA=t=qLjWtZn-0)R9^wdgEj$wLQhn*JK(Xn^HPL5%A zdWU9V*c#3OgZ634$HK^IbmTM|zTyqOmPSsaqc)lYM#ISxS49k1xu+us0tQ@hg9n5B8SWY*< zj@B~(JLsH{)@Ws%Hxjcpa@q#I-)rCt<@C~{9Sl25bihuIVP^?p*z6XD)kg1NmS7DF zP-BVd9SqC+3iv{`YWZ3_Gz)W`_Y%~z_JwNR(!2q_w4T8cmoV2gUnyn_)>+#ThVAz) zh)dh4raD_2dpR*1qpv20UF$V~L324V?7FE14BE?=vy`!SE_;kHbHJcEn3(JNUT2sE zsa0WEzJy^lznU0!Zdn0eXrF33Xb*O(R<#~sSnO+{C+CapL1ETLPtf_&c7(C|h85Sw z5!VL9rSr7`apml6h@Jt&o@1;&X60R&g~JZZ*B1Cf{ZRYTYbXrM#m*7e&JouR_|kTy z2eDpPO-y0*@WimbTHWA_^?6|i}JE3SX2B0}- z=Xwnz=yh5T>Z{iJY=JMWXXl7(=g=&B!@6gFxo<`GsW5C-3bP@;s)@0BZ(>;As3&Gd z?9{*)y3S2Z>9A8d7#4e+m_TwG9dShvSB_zEMG#j`^Uk=w(3*8z!d%ywKF_y~yw9gE z>+_2n80$Q*?V#(*#IW8noBY)z7s9ZfDa?l0DS$8Zd@wN$@l^mlIbZB-Bg~HYl6tQu<^H73k;{pdL;46BU>Xx4EFGY~s%`2QY6&$iN+%}Qa|eeCpE273-B=6dfm z8HUw{FswF&v1ablSi@psSiTCN8O>9zIcJB>xB|qLW7v6B7&e=PVLiN@n1bX>nCmq} zGgrr+v(q~CShHKNPtJ}tyY>2@*_{|`#wEs@-FlsKcGzqZhSi}ktPX`?XDwkov0L-q zTAv!krE5$WRvW@tGuPS|!dP=z$DXruZ(LUvsl9}2_zp)jltg|TM0 zwNHiFI()HOZ9we0#)PSfuLi`G^TlRU1LDfrVb^Fa(5&NXfgbIv1$xkPMr)mgVLhR9 z#5JE7c5V@dJr`a$?4+|qx~Fj6d-eS~VJZi6y@vV>SxgMurv=cXb6NmBIfm7ejCGB#_2lfZo+%95gEi2D z=CZD_9K)W~)<6%M1y)WY(1Yg1e|VTmn6)C#;S2i8nB;HW~-h0tUUWWyRGw?4xip$Xincj`9gbeP`=Q) zWiZxI81@cB1@z7n z5$HjCXHa_wUBg=I+yKovJJuf54C>E17ibS!xe$i+jn1(zI!9c>uy9OXZ zjvZY)SUDAj#ojpLYCv4*I>pk{0zGKITl=B~nsaun-eTpVbJSP|;zHL%I)Zp)s8+QvREKxUj;^r=Fz7zgol%D^U{YMo z`~A~+I*ph2!u!yF_i}hYzNG&`qYc&m_s3(H{c-+r_3i%M7`E>opT~!n{ZFT_5Bs-2 z{B}6J3D$4!|NYG`AD(}H8sX2{H;-pk&ktjmecFcp{P*Me599MGRHv5@<3HB!{;S|= z-2XZriLuXK)7a;)Y3!@lH1@@78vF8gV`Z3svp?;>Pro`mpR2zKe*@PZKT)Vf008Ra B_0s?V literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/jungle_medium/m_jungle_0.nbt b/src/main/resources/trees/jungle_medium/m_jungle_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..de21c7cac3f9174c4eeab59be41381f6dbed8b18 GIT binary patch literal 1061 zcmV+=1ls!_iwFP!000000IiwZZqq;zhS%|~4{Il(2p)u!khta=am8(AT2qClNtKx6 ztMW3~Xa~aR_smpEB@4Cs{Leq9bsVB|we!c#&pvm~P1kC?F2-wJyQ<#}n_<%*-Sktt z;^TIIb$g8CFTZM+-|vrf6aAFA3&)`w`gF%BlRbc`1ZDwrGN3bEg%T@M{49XZVumRN zCQF>AGhIRP!*w{58<<7IG-e%oi+o&XkFfW`h_huZr?FFj6dH zq&jEGlQbK|NcE`_;|+|K7x%-NIx)F{@dif9ofs*1N3}LE+N^R0^{Z0qQzl01#dNt7 zCZA!l6UNUlxxmzkStz~WI;a1gw#c_yYc=&Vkd0?Y=_o!5{UX}^eBDD$l4 zMT~SN5EBeK(##XnD7(Y!%$Ww%5bX}HA=({neu&8pI?*b?80~Z$5w7-E8~IZ~OhV({8)?ciXwl8e?N|Y=y!wj!{JN+SLz9i-gjU7qagO|oMJD|DfarDVlU4r f_Uhqcxoh5bL-%32Yrh*8w{*V&67tE3lOX^A_w^T; literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/jungle_medium/m_jungle_1.nbt b/src/main/resources/trees/jungle_medium/m_jungle_1.nbt new file mode 100644 index 0000000000000000000000000000000000000000..3b4f5124ae3f2efbc5481105d4a115f3d4c168ff GIT binary patch literal 1023 zcmVs0e|bH2^EZE@aku+1zbTrBSM5v~r+ymJI}p<_OsCN49--4R%u1oNQs^w}suX^- z3|DJ;tf1o);}uL$FkG#W7^h%3KbhgyUMI#LF%{Sg$#YcH>J&_Vq`h#8KHslT=#NwM zS@M$^sn5&Tis^G^j`zYA7)`CnFb$|h{WJ=lR^g{r=tPB1ROoaH9h>sO?P+GDtV%jQ zJzSqN;}pyZ!-T|e84JJ<%~$|_N{m<3;(C}FZcppP7-4qk+R^OLwU=sfYtIa~_RL6g zs$F|0%(Aranc?<5Gh7ZEh38h0`BtG56+Mg!9h-6{oe4py!|jDn%n8%y%$y%F4$MUm z_98Q$(Ww(7eeMJy8@0kulbGW<^#!J4JU75ksg_gdNLi(xLxHhOtt$11%SL9-7#*w7 z$;?W@oH9MMzz=1dqE=?s3g(Q-SZ2-{KVDHQGbak>RKakby~1+tY(HgGi_qHJCX&pXrD8~?Yjkj(CpA!Xf9~25_2x( zkgmPNNST+`9u$2JpjJtTJAdlLv_cN=^D5+LVH(CyX1IGoW~6%p^@H-$3YpIg*PqOA zbCKtn+b;+Fp!1pfDKXL+PWwYWdxdAO@a%zSlvP>_-N&T;szH9J&O=({94<@{@*IVX zRiGBia}+XffghA->Zhc`-G5wSxITMOtHf}9&P=P&;j-Zso&)exVp_&?4Rp{QKw4L3 zBBRrQTJ-E)UY+4*IWyeaE1*+iq}l0&9@@lk^JRgbk`A{n3;dw7m)1ge0BP-B;n@Qn zbO(@n7(frvnJMjQP^>EeKj`mB9mzAA9qO6pxdxumd`bIW1J5NtQK8cbb4op<-@Bz8 zF0-=|)}9$o$0jB+eq3U>9y&!W2Wp|ulojbA_2a?X(PshmjOL4aE-~D`d*B((m*hDp zJO|(z%@_4t(&>aeOZ#2}KWKKO9yXvB%EnsAs!xn`PoO&Jp0E~j7!o7h6R01w7t{~x zvu0f$^3+|G61W^=rN``w#uiU|!s8cEjbN z|1!P%cDMVw9WH+C_g99zt-adJ6?T_{sb00Fn}0seKNxnC@zddM_^0;#zuLaPzSs`^ t_hDqjUOuJR>!%cZ^ORz5A1~(2>U}@;pO$y+cXN0f^A~jqQ(oU70076^{HXu{ literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/oak_large/l_oak_0.nbt b/src/main/resources/trees/oak_large/l_oak_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..b4537e95b42a7363fa2d37c07db0d75cc75807d3 GIT binary patch literal 5479 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/oak_medium/m_oak_0.nbt b/src/main/resources/trees/oak_medium/m_oak_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..59d06f42f82ba07f6603cbc1e746256b26df96c7 GIT binary patch literal 1696 zcmV;R24DFfiwFP!000000Ii!_Z{#)%h2`-@mTb=!MgK_eK%e_u^r^4KH0uI`&1Qnk z^!nca-Ek@gQ{w250TRG3i!bCMMNzbz%^{@FosWO7Z3tm|KDj>o>+>#!aecTPFUR#9 zwx1M+U+zzLAI>?1=ARVW$J1GUDTV)jVjKGN<#1WcZy;tQOnwEE3}1~yPvh`q*~tz& zD3bKHZk18>Xo+?G3X7 zIoz1;hG{E|mFLcpL(5JoOz&WIoY&8~feM z>`8tWU`Ow-rmTn66E-Fqy(Ox((990l(K*}!J2fT|M(T{!&&xSS`bO)}+yc#dy;`7I zGhJbB`$nuVEG}WJ-fQK#dxd7!H+m2k>d()!FR344*m)t0bzWGS2aspfSGDFE5|=Q^!AvAB zVc6_9IW!BCiJl4gs@Y-Z&g{^}`t!y#M2|46_X@+-OBm};Z(~^B$PPWiurpVff#gsa zwqE%anpv-#KwRj&(0N9EUdLWz*t@4N1Bpu*>ul2bsrg!nuh|jT?9ePsBx@neMB-W; zIb49A8gm=F?!9}5=1}&}tuKA12os5~2H2@FOph?udu0mz9Nand?0_#c10+?e+D;36 z>9~Yp@6@eBk1(vyw?H$xXVW=E@19odePOJ7_2=&{#=GA0cLj%?OxAq>deFR~^`Q4S zt*2&(%?ZM=IuwSz7YMVE*kfVXyOl8PEQk)x5ooU2Vec0s(2Qmqy{0ugEG}WJcWS++ zXpXY>yD-VYWQQ+S8^U<yM^;)3W z&+3QS5m$D^l|fuJhTX3U!)jF+_Kq(Mn_DJOKWOf?`n)jKysGzd%?_&#Vc5AW%tT_J z!MdY)RmW9h*u1eg>@VWP8{}^+fX3)2QjbU??FsxSl!dUl6+Ewex^FJVT9 zFLwVd4Er7@4C{vxHO3f)-#1+H6{!@D}}LU+Kt&0Un8guG)GxE6o$ruj3Go;RQ&6hPp>RLrJq+Sa&|5$kzhRr|1SaY53t2JM&uL@($b=H0t zhRuG$usf>^>RIm#Vc7e!Fl;6fhQ%(7HP`95(9EXeLbIQ)pPC&uO9*4lb=J8o46C0R z)HC`C$>?zF6N7hV|#gvA=||?kaU$x^L_qwYmp((CnvUM|XOYk)IAQ=f4{5IWB_#`>>n#I<+mc{x`|-{=a%-kbVYFzh?pP?(*Av3lmL zVn_G$T95AY!mu750i*4Vj@X4+2$O&>RAbx2{;qogjMgj+>tn*PbLVBAFlu7~`H7E* z`}J~JpXY-d@{doa$MtFZFK%P#4u2lcq512YxbBC;$2ENV@%XUbJsp0%e0Ms0`1z01 z>3vYYGrm7w%|G0&q4{zQ`TFnY>p!dym(X3Fep_EmefED-_v_*J^-PR?@s`HEeM@6s qy`{0w-_qFEZ)xnC*BfiY^!?#-_-XsC)5EnsWB3;kJ%p-WIRF48fp|0k literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/oak_medium/m_oak_1.nbt b/src/main/resources/trees/oak_medium/m_oak_1.nbt new file mode 100644 index 0000000000000000000000000000000000000000..94f614301dcdfe1a0695e81d87720f55293738cd GIT binary patch literal 1510 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

9vyYZ(zE8}9r zMp6W&ZC19>wE)OpPO-DmKm6E_LP~Do3EFwhR#*}+-SEQ0v*p_u z^$nt=H)UBz&v`xv>%P|a-^&44))N=DVn$Pfr1HtjpwSZQCYRRbfax3J?NXaM`dx^_ z!I)8VkhEcP_xNqywvYr&x}uGTwHNEa0YbQwt?_sfEZJUKcTnP7dM|ddMR3Z^ut(h( zWoqHAUIqiV^wuzA36@wgK-F9g&y~a-u5A;TexBV2snOBy6cU2kHeOU7C`4hysv9>u zg&c8zS+-to=v65NQ!!E8xm7Eex*M8rk0C{KK9s^t3aOxv6&;SAleFTHY2x!VTAfTLWwgqIiq z%x4aH5A0F5i@wVr)75!)xT(1?v)+W8k1CQIev@<qOtybvDxx1|0|`PW$^ab2=+mDZ4Y7-k+d2u=kW9&`xQWzw!bS80Nca6D{g z7sTEgwX;niZ0TH2`~%|XD>v%)de2A5zFWeHM(vEqsfz0=s64;SZ6tM+7x(X2v_;wn-g%&I6LHuH zLoXag&f?q#G!Z`rY^4l^17S-JiZ5CPi3(3;jLbNzQWiy1&u1ei}32&~omeQZ5l> zIWoS@^7T8+s9)xzg?IZ-fZVfpScWgL;Lsj+&3)$4R1%VaEWhUGP8c7!b+6Nt0NC(8 zhJJdt0mpuJpWA@*GzgtPA0}hy&s+_{j^LcRq657Oj*5HMbj|c!Ay9FP9Q9VgZ$f>U zht0*9bj=%EoF$xUMbte8_Mu~t-S-mO-+_lm5&PN>y=+${VD!D;^UHv$_%=jN@Z0^+ zT_h1v7H}qr@v(2=2`Ry;_>of>Td)7eZ7rY~BiTQ4eVyhTDI8xf*Q`TEn7S4E9lHjk zEJ*L?gFcSLz#hM_87v|ljQ-*ybr*$1u!IfXnBhGwJp8(NyF?EbvmWQNe+-deX`gGY zGM}amc^oJTotbHYa?ad!ntxQZ0iJO@PwYF9f34BlHgN}CJaOxz;NTdUHcnC-mlqA} zs|1pXSs6~1IbfO#G;R-Q@Z%q(K6U;)dQ&!t&js;k=|tTYpbB|Pw-pC!?bd`jzYnV7 z15`;Kn3i0!^g{=4rv*`Gu{MdeXdOf-nfdd@{Avy@Em^kcLJ;Yfvn1`G~9DW}|_M;5FvXDNlqkpVgNnH#MuK-7J6Kl z4pcq50y1_$^N|$NRK2r_mDtLwa3c260IFv;_@teeq4XSh(7~I$z^);}ScpA9Y#2d2 z5PJ>iM$#wgLUA6lG!s%@nr}}Kry*QCchRuLpD)X%^#>tv+k7MTfgM7X!ei z-$x%yEoM>>$a+<)gA0(qTZ~MP3z8oDuNNShWp7F}$`!>oz(8Nfe^bnwj~&RRO|fkd zj_oD+KvgIPu_Fg(#mOTDRdE0n-Nw`ISS!_J(>1*Nb1-n>16t!cIX6CcUDKSGs1*v_Pp?P~kCNq4V{u1iA@8_uHp!wYw18jJ%I`AHt}VxOh+T3vw*=Rcdo?z;OkNQ=%Z~ zQ&}`+)4b*s)jo0L4L|L@^Xd8Z<$S=RO`tW8N$`p?3CAGRAbb8ueV{15@?tTe<=*y*of?Gf5 z(|<`pI;=mvwKl0{dT?2u*<2f0J=xc{TJoSPR6Y2X+!Z%iVa{Nlu{LL(PhL@K>4{qH zqQ+@NAF4!;67UtzjPr82-#?aay;iRz%%K-Y6~D3T%D7BshN;u=P13k}P^lyT;+6Bg zZnaSNajx;LN1kyS2?G)uB<7JYJ+pg~FsLW&Vvp-C3VkQ?wOu{_zC9(%$Bazz)9`1P zj9<|+RxcV?3eAiQ7n_z-R=#4`{??@NVn*qIpPSRJ==f-Lygbsw^pb5J9bbt}N!EMn inG4$E4Xbk(1I_6@)m{0@{r;btEmiB@n_xv-So{a$3`*Vr literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/oak_medium/m_oak_4.nbt b/src/main/resources/trees/oak_medium/m_oak_4.nbt new file mode 100644 index 0000000000000000000000000000000000000000..c8749942cfaa59c730fc38d5e385230857dc1ab1 GIT binary patch literal 6890 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/oak_small/s_oak_0.nbt b/src/main/resources/trees/oak_small/s_oak_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..78f2fe422d0d2c31033698b253324ce33ade58c1 GIT binary patch literal 2579 zcmZ8i3se(l8bz(Bk&UP1yC14$qfYGVuplI&2s-E(%%{r)pE=YPz6_q+FV zy1v=s-PK$knc{rJhR7GGPwjMe?lAxA`MMYTk~K=kMmC%bNGy~ETD^MIHCrQ3+IVxS z#LenX1YB3}iTut@oAf#1naav$8S`1i-O4dMA1vyS$F48Qxr&F1)J9=bDDjm8h4SG)$YaD=}iunUvB)l*(M3W&C7W2=Jg}D$tzO zUcP=%14ZzU%@kw4vWI>VhR!@@as3n*+RtsQBuZ-VjLS6IR4Mqv8cSATw=%>ikr>4g z2XWoe(Xt0Y+@kUjmDS)@Tv}&DTKx&uT%T#Y^j?m`;hmmGYOOaC7p}Vu2p^Ap(Fz^p zeqz4X^g4nNY{WT;#)CqjF!oQb-uswMC{a@ox0D}^EO*%V2F&^(-o{_glGG))$PB

9vyYZ(zE8}9r zMp6W&ZC19>wE)OpPO-DmKm6E_LP~Do3EFwhR#*}+-SEQ0v*p_u z^$nt=H)UBz&v`xv>%P|a-^&44))N=DVn$Pfr1HtjpwSZQCYRRbfax3J?NXaM`dx^_ z!I)8VkhEcP_xNqywvYr&x}uGTwHNEa0YbQwt?_sfEZJUKcTnP7dM|ddMR3Z^ut(h( zWoqHAUIqiV^wuzA36@wgK-F9g&y~a-u5A;TexBV2snOBy6cU2kHeOU7C`4hysv9>u zg&c8zS+-to=v65NQ!!E8xm7Eex*M8rk0C{KK9s^t3aOxv6&;SAleFTHY2x!VTAfTLWwgqIiq z%x4aH5A0F5i@wVr)75!)xT(1?v)+W8k1CQIev@<qOtybvDxx1|0|`PW$^ab2=+mDZ4Y7-k+d2u=kW9&`xQWzw!bS80Nca6D{g z7sTEgwX;niZ0TH2`~%|XD>v%)de2A5zFWeHM(vEqsfz0=s64;SZ6tM+7x(X2v_;wn-g%&I6LHuH zLoXag&f?q#G!Z`rY^4l^17S-JiZ5CPi3(3;jLbNzQWiy1&u1ei}32&~omeQZ5l> zIWoS@^7T8+s9)xzg?IZ-fZVfpScWgL;Lsj+&3)$4R1%VaEWhUGP8c7!b+6Nt0NC(8 zhJJdt0mpuJpWA@*GzgtPA0}hy&s+_{j^LcRq657Oj*5HMbj|c!Ay9FP9Q9VgZ$f>U zht0*9bj=%EoF$xUMbte8_Mu~t-S-mO-+_lm5&PN>y=+${VD!D;^UHv$_%=jN@Z0^+ zT_h1v7H}qr@v(2=2`Ry;_>of>Td)7eZ7rY~BiTQ4eVyhTDI8xf*Q`TEn7S4E9lHjk zEJ*L?gFcSLz#hM_87v|ljQ-*ybr*$1u!IfXnBhGwJp8(NyF?EbvmWQNe+-deX`gGY zGM}amc^oJTotbHYa?ad!ntxQZ0iJO@PwYF9f34BlHgN}CJaOxz;NTdUHcnC-mlqA} zs|1pXSs6~1IbfO#G;R-Q@Z%q(K6U;)dQ&!t&js;k=|tTYpbB|Pw-pC!?bd`jzYnV7 z15`;Kn3i0!^g{=4rv*`Gu{MdeXdOf-nfdd@{Avy@Em^kcLJ;Yfvn1`G~9DW}|_M;5FvXDNlqkpVgNnH#MuK-7J6Kl z4pcq50y1_$^N|$NRK2r_mDtLwa3c260IFv;_@teeq4XSh(7~I$z^);}ScpA9Y#2d2 z5PJ>iM$#wgLUA6lG!s%@nr}}Kry*QCchRuLpD)X%^#>tv+k7MTfgM7X!ei z-$x%yEoM>>$a+<)gA0(qTZ~MP3z8oDuNNShWp7F}$`!>oz(8Nfe^bnwj~&RRO|fkd zj_oD+KvgIPu_Fg(#mOTDRdE0n-Nw`ISS!_J(>1*Nb1-n>16t!cIX6CcUDKSGs1*v_Pp?P~kCNq4V{u1iA@8_uHp!wYw18jJ%I`AHt}VxOh+T3vw*=Rcdo?z;OkNQ=%Z~ zQ&}`+)4b*s)jo0L4L|L@^Xd8Z<$S=RO`tW8N$`p?3CAGRAbb8ueV{15@?tTe<=*y*of?Gf5 z(|<`pI;=mvwKl0{dT?2u*<2f0J=xc{TJoSPR6Y2X+!Z%iVa{Nlu{LL(PhL@K>4{qH zqQ+@NAF4!;67UtzjPr82-#?aay;iRz%%K-Y6~D3T%D7BshN;u=P13k}P^lyT;+6Bg zZnaSNajx;LN1kyS2?G)uB<7JYJ+pg~FsLW&Vvp-C3VkQ?wOu{_zC9(%$Bazz)9`1P zj9<|+RxcV?3eAiQ7n_z-R=#4`{??@NVn*qIpPSRJ==f-Lygbsw^pb5J9bbt}N!EMn inG4$E4Xbk(1I_6@)m{0@{r;btEmiB@n_xv-So{a$3`*Vr literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_large/l_spruce_0.nbt b/src/main/resources/trees/spruce_large/l_spruce_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..64202febe26a220eda01ec1019a43b6eb076fab9 GIT binary patch literal 3744 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_medium/m_spruce_0.nbt b/src/main/resources/trees/spruce_medium/m_spruce_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..8f790be167402a19786fe05a462f97a7b6e7ef40 GIT binary patch literal 1011 zcmV9QS3#) z=kg`kB1TbB?P{ToB6Y6%?Z~JZAh4Isb z>f`l(^R-(JfBb4fJnXyarWpQw${2Fjulx3N$9YXLU1v3gQFD${8a3&xCPGblstGe( zCDDUiCDD_Nn&`kuGkPM?gItm5!8u2w$HGZ7nx~pPqd7U|Jk`w2d8(P4b0U3NICFE( z4j*Qs2e~rQW8utswK(}BIBHaON}*?}QQ1K~EIX)&dA@XH2Q^zbb32`C@=RZm^u;`n zeX;CdUo3;zmxZG;h<&kqseMf~DuZfYiS%XR%NP&Q8`7; z%<~caY}Kfos$C?~mxZIAmCA>i=wbOnJr>TKS1W>J)g+O@6m$lY=)E8~EQ3k(UJ@>r z9pqveL@o+S9a)El7pHUCX1?sVI=5mo7^GQSx^Rt>ycI-V9 z9OhN*i}?_7*gH`b^!Z!~&E=^^`4G7*9Oc8x;ls+|L)6U9Ow`OghMJjIQL}}kysGA$ zh-M2%`B}|5JN%OgmxZI=yB7|xE(F(9qt4ZZ!_TOP`4IImKcgPzL*!!qK`!P)jqsMB8$7+XvYKMQ2i}|O9eOWciW2lFD4E3;` zs@@afvT)QHg*a@^jbj&$V;2qhup;w8E;eW6VsmaBb8cYoET^jXMD$o(>bblWdZrq+ zi=|^1OGhq{i|qor*e;OE!cpg{>OB!XY!|BcOmNtoSB_n*gr0b+QRfeGSvYDJD@QI= zUx{!rk6k$CbK%5MUPUf8ALL^5K`u5Qr8zk?k9}P_=5y(o&!uBN$i?P^Tx>qb#d`N> zzH;Q^%Apx?nC2^oX5?a?SDF*yV!OB}xTYF4pL>EU5gf*K-%;}bYS=sDL#P?wsTYU! zb=&vtc%CknVfpU3KeWg3-~M$->+jnx6hDR^A?fYuY_`VyyXm@=`{qeT_3-;t+uy*~e?Ply2Q7*yzlt046h@VKu+QIEvn$`l!| z$W$4oWV|R-taWeuG6`m@W0}6F4kj2WA4BGq(kVAg$>c-pNijC#g^U;Ny@)j_7@Mgl zGP&Lj<3)80RVbhZQrgtb~h{!B1T&0L1Go)jbHEcIm>9d51GikxdRA(dgv%g=M_Be5esISg^Io+Q)bSeQjv3*#T8+wj#-)9JEUQBxLE`ycV=3~ zE2WdmFfvkxQeUX(3mGqN7Mh%|Nj+79$>~@|C&ftfx)%CEWj!}SUy;e_Aj5DvPZZ2k z!qm(;7Ow5PM6)pU*&Y2n`>?Ot4!Td{aQ0*Pxu^kjKl%xZp9_c|-JOT$cm2ulM)!4o zzjx!|c5sK=@58VMa$~da7mw4`(JtyxcLjXeq0vn)dx4b&p~fEEr)##e*hp(8>HJ5008K| BWf1@X literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_medium/m_spruce_2.nbt b/src/main/resources/trees/spruce_medium/m_spruce_2.nbt new file mode 100644 index 0000000000000000000000000000000000000000..379f29beb59f1c0ea1d2ee8f09a49913ba09e808 GIT binary patch literal 865 zcmV-n1D^aJiwFP!000000Iiu@Z__{!h1Ywro%9C0@H@B(iD#Y>PrODZU8JaO9K|lT zpTw`kPIpll&dy9xEcv1BmosPP?5^E*Y0Sd-Ve>OOW6XTF)BS9^7YozI?YJ2?aWM0> zF!kr#etk16r!RgjjNA1?{*W^dS8yf_V>ib1iDSkm#w!?&PR%eup;M*1IbtgFZ(o(d z&q0gP@sH5q`pQhp)C!7PwW9YXF_vKtKPR3oVQjh`qho=N16f$&xx}=LAD3NuIWe9y!}axtRWQd{gaUJ1t1d7NQ_E+Lsg)V& zjG~@POwH5^iunZKnf4xl=Ta?h&H;F)wQAspdai+=l1^Zl2GpYK*`!%}VLelZ*2+u} z)~Y9Yp>^nmHRgby62r|WGu$5Z3O^qBLF<|NLF-5At5#%DB`xlGni(n6AoOm54$6Y+ z(D^u^Q)0LodWDXEgbuftL%OBsmo%R$<;tC7nUS6;R0m~RD>9|E(B7dsC@-pm)<$jQ zeOeoNpGv)Z;2GsEdG-p=L6K1aX<&HpGL8M z8X*f0dPl!sNPT(W2jxz6(D~d7S!71qr&OoJSZ2-^)G9Gt7MYRuGWCNpmHaq`9}jAw zwIR*7_P6(NSV%z5%wwdQ__)gr+!L|vrkUa1 zu`}a^Old7NXX?4cNLf(NB^~LxO#PG?>A7YoYl_eOX0c^L1(XbG1s0^xi^s(0nchKUU#qzOD#^&KAlb&sW3`(s`n& z^^`F4Go{&ew{aZfeC9Swv;4U4cX2=eTc9<*`@R`W^<#Po@gKUoXrA9~wsF1hzKrj# zyZz0o?`~G#`u^IG54P8vsm694P4%`l%jx^W^o_V3jUV^-5$O%P{rx(wZe#Z~4vgNL r6YIS`vEHi_>%BO!-pl{ebLQ-QH+G-q5BA&X3Ei0Ad5p;HTp9oXMDe&f literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_medium/m_spruce_3.nbt b/src/main/resources/trees/spruce_medium/m_spruce_3.nbt new file mode 100644 index 0000000000000000000000000000000000000000..c08bcf6360d51f353925ee8e088e21f2f182b3e1 GIT binary patch literal 898 zcmV-|1AY7-iwFP!000000IgZuYTG~%9a+08S#~bH(eLOT`kd#|r@jW&*@8)88B6Ky zm->^H5^WH}(af|su!Pu0XU^Q$aYeKw*KU8uoQQ_A?9Yq-6iX`OuG@Co*b?2p5x(9u zo9njf|M;_{eBZR`Ax95Cc}~9V>Mo8?OflYo8F(@Uvlx$`U^0eDI1(^!#7MS+fu{gG z98-=MCt$LqdxBX2-|w*o%##hW=gSEddDe#EdWmdHRf2H=P*;A zVg};`9tUi39tUipI^?$Ic)Xy;8~iE^xuB6ts?}`7NHvx)lC6b-Ct;vGuKl9%_#4Iqs>FE2j#R-a_WE{6ld-ino%6X`@I;C zw3~()mP)=7CKvQ1jJ9`5()*q3L3atxGl$Xol>3EpS}Hm92EV+)FAwz0+0y!y=K}Sh zmiLSvJ|Js7xForkbHIb9*#lr zIVZVKz0uYag(qPwJkm_?fCtT%rwqgAyaO1d`I&*|Il~M)x7gP=vFqZnOUjC>&xd9o z55rdnCAs?Nwx#S>f4Op>>f1;!Z@0U+In>{}k5~2K`m(97FMl-66|o1)t8H&%w~3T} zD5>gSZ~GVGt|QkS?jquA_lLVpyu69^_t*-2?~cs(_Q-s1j?DM|$b7Gl%=hZQ_;OlZ Y)Ls2$c(B>^H<^O|0x6S@RL~j#0DuzDGynhq literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_medium/m_spruce_4.nbt b/src/main/resources/trees/spruce_medium/m_spruce_4.nbt new file mode 100644 index 0000000000000000000000000000000000000000..7e7b76c6fa076e1b43e8a07348be98d4fa31bccc GIT binary patch literal 965 zcmV;$13LU4iwFP!000000IiwZPTN2bhR5E69S10FFZvukOTF%O)vMk{ZrDl@5J$1; z>E-%rjbXQnM*q$%Rgf$Me3|*@xSP-sEy#|W-@y>k{45U7^ZEON+OVBA()Gy-EIV+t5sz-W4^LPm<+Mn=*@ zF^}~TQ)L)az<7bF=OT}s_~4s*=0uO`Fz0zHiomo3nf7;WA)%?{LpYj(g_&W==z z#CRcgUr;X(^l)EQj9sSu?UQLV>meI zXRaCTXRZg$ms4t*dPv*hnlB4tN4uBDh2}!j>_85=uf#~_y906YdO4tn*WDM?G%-?5 zeSv0Qpt&jN`3Cqxz3P=bCq_Ci5~J;Tuk?=rdeENddeENddeENddUA|*7H~bN=eeGo z9qIn#3i9KC9`4H*)YJpb=)T%82JNUunTy0o`^P+jk#>uXjI<9Eqt%_qh2G0>2HpL% zxaRz{1#{6V{cM08G&`-*8;Oy6!vZ}hhg=Vu9j+&5N4r03`EfuGs+X1@2lSw`K&xp@ z4~tjWsKiKTw~dT;rf@x| zpShl#9c>0XRxfl%;+j#3R1EMyrLU*#pfyKMi1by%HnkaDL91W;9=CB=0dB8SPBrzR>J&U+Db>_l5GzeWBUm zzED4FaruI{d_i1u?B_}?Tx2RGu5%?n9@s&eH9hll!5GvV7fL@{U^K9n{$vZPK+Ro&5(0fmA2j%CIF(^NmiZ2K3ptvrTy8A*sPZh>TM!SOSv>UD(h63Tw&sKQ|*)zYdo@`>DST^x}524eNdXZTfK4@2^)wf4%xK z3|GWn*j{Z8KDO&X)%%vZ!|%t#FT!>rJMHfRvN!Jbck8ga3H|pl3ijTd*xtJn+k1Or nd#_Jy@70Ozz5FkGhL#`ussA#+aM&JhI}QB>yEj9!pdA1Jiy76a^`pEoR-o~q?IrZKck9Bx~utqlK!^R#Qii(LmVYtt!zH+ z4%@F|H~;gi6+Irt<)KpkUZqMkPW=?`pE%c~t4Q~mrT|TGe~UwN?o(zo=R7J8nNfqx zi$+&`)GAYhgBn?OeWnQ+&Dx$9jc1k`Ss+hNW95ZBxWj_*pifD7a+<>E2J*0O zAP>vkI=hltIUlP(o=nxz4R!j2GfhSEQb#wChjjyaSU1$s4dlsbtZpC=>jv`Ve1g#p zYd=bOSbwbj1V=XlnZ>#hU>3_gIC2k;+;JAmG&pic9+nsKu-uV{Wq~}nA0<32cWXaN zcyd0$$Q@^~{#d!Et8#RsGWN4*to~Gv{vc1zXKgB|NMf z)((~Mux=m^es2k6R?cUwKZ_=;%u3hBn6+rEu5KJX#96F|I4kF4^>E|pAu_WbA~WkD zGP7=2`%yA0=VN`2S^EiuC#SJ;uVK$Qjn$3X(T&>Zb4hqu?#RP(M;?}Y?a19ayOLS# z?2S`neFtb9XUAFW>^O^^9cQt#Tjx^8xr#r8_I_H&ep<(Va2D=Ii4Qxwhq*H}<-NvY zMjw`G=g8FJNz7Nq*%yt+$I1(R*tyV$oy)^>4I0LS8kWViaV~YvdgRbN22J{Wu8;jL zPE$--ZaV4SpAN@(NXM5Y5iTu@4^?x%g*Hh>I z+_xn5!xRRU^nDeA)MT|ahY^S=BaFz<5kJro5k_X{_?n9huOg%7lumK*J7x-?^Oa); zld9P>GDD||FfwEmVbp;U5r%?iged|WVao8EnA5Mij+hekE?8e;hDqhj`s0Y1Mnv4vaj0~HM47nG| zkb9vFxfjYXr{&Q}y_oJI0{*J7-YMXBj$w7~}U~z1JIKt??dJ zN8Q6X?9J#ur5lp^t)HlPcj3!By*2c2+waVB)KB(irN{MR(CfwPFsz6TY*xMV*ewke z*9~><`Q#qBZ*-D&d^SjL+Kb%7 literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_small/s_spruce_2.nbt b/src/main/resources/trees/spruce_small/s_spruce_2.nbt new file mode 100644 index 0000000000000000000000000000000000000000..d46806e0f699838ec8f8ef13d79a7fa7ba998a6b GIT binary patch literal 388 zcmV-~0ek)*iwFP!000000IinWYJ@Nlh9^#34}E|>M6Y^)La%#Wdez${byE;sBPQF^ z(>I}7mSHxAvO*B_&-ec`Mq>?7fwb+nMgRyS_oEKy3Q9e=*0tI~I4an@_NM7ayNGWb0*gxosi^gM&p;EG19aA4LQa|F?dg_WR@5lyy?NS?piA{^h`-C(tPu&C znAf7g6;7Fury`p0jVeafYv**>8a6f5&yyMT6t<2Mr21?vh%XP9Pin8>a^DWRnbezm z*r}=88r5w-jM)L1SngWyF*F*)eF?R{Zv6$nCxLX+L32DiPKQQsd#&F6u63GscV^!0 inR(Y|=H2{@hj8(zoO%fp&ES6v3itt-`9ml$2mk;Q^0$Tn literal 0 HcmV?d00001 diff --git a/src/main/resources/trees/spruce_small/s_spruce_3.nbt b/src/main/resources/trees/spruce_small/s_spruce_3.nbt new file mode 100644 index 0000000000000000000000000000000000000000..e82f68dab04b7fd5ab831c458195eb3a122e864d GIT binary patch literal 396 zcmV;70dxKziwFP!000000IikVYJ@NlhDQ^R`v852UiCzw*S#*i>g|%cQxIJvCfn1~ zH=%2hVKh<FE(;L7 zHshuken%`IF;-bT@1RT+VBpM6nTXM$4AuF|w4gIGVu6A494#=>$gW_fnd2E|nny6T zhrD9Oi+dM-mVy3+GRu|yk%ZxDm&A*!o$7FPQ61_vGE03HD>8eXguIJ6CX_h|WEPAU zmznBN#`ifTdFGg@j$|^Yfjlwe#r21J&FP4RJYr>C8DY4(D8uzRBeiq?PDbkD{?nZ3 zBr{AXb56Xdj$m{+uVMvL5+-#_)~gn+MgJ@-p?n^6kAputa**n?HV}Qe0P;y45iX8( zht;6o?889~&0ec!|Dp8($j1CoJCCkHi0*SJ-MVoL?o0w{hZAyorXNlf?psvv?$nys qyV_XqdSkttjrDFf*1P+co`Bt>vg*Ze)Sdg1GWY>L$y#E72mk;~%)r+G literal 0 HcmV?d00001 diff --git a/src/main/resources/world.yml b/src/main/resources/world.yml index c4e9337fc..e69de29bb 100644 --- a/src/main/resources/world.yml +++ b/src/main/resources/world.yml @@ -1,18 +0,0 @@ -grids: - DEFAULT: - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"] - - ["TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "TEST"]