Implement ores, begin work on caves.

This commit is contained in:
dfsek
2020-09-15 02:00:18 -07:00
parent 0eddcf429c
commit 2db311759f
53 changed files with 670 additions and 73 deletions

View File

@@ -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<BlockPopulator> getDefaultPopulators(@NotNull World world) {
return Arrays.asList(popMan, new FaunaPopulator());
return Collections.singletonList(popMan);
}
@Override
public boolean shouldGenerateStructures() {
return true;
}
}

View File

@@ -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;
}
}

View File

@@ -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<Material> validSpawns;
private final Map<String, Object> loadedStructures = new HashMap<>();
TerraTree(String directory, int number, List<Material> 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);
}
}

View File

@@ -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() {
}
}
}

View File

@@ -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);
}

View File

@@ -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<Integer, BlockPalette> 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<BlockData>().add(Bukkit.createBlockData((String) entry.getKey()), 1), 1));
paletteMap.put((Integer) entry.getValue(), new BlockPalette().addBlockData(new ProbabilityCollection<BlockData>().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());
}
}
}

View File

@@ -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<String, Object> 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<String, Object> 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);

View File

@@ -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<OreConfig, MaxMin> ores = new HashMap<>();
private final Map<OreConfig, MaxMin> 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<String, Object> 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<OreConfig, MaxMin> 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;
}
}
}

View File

@@ -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<List<String>>) getList("grid")).get(x).get(z)).getBiome();
try {
gridRaw[x][z] = ConfigUtil.getBiome(((List<List<String>>) 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<List<String>>) 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;
}

View File

@@ -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<String, BiomeConfig> biomes = new HashMap<>();
private static final Map<String, OreConfig> ores = new HashMap<>();
private static final Map<String, PaletteConfig> palettes = new HashMap<>();
private static final Map<String, FaunaConfig> faunaConfig = new HashMap<>();
public static void loadConfig(JavaPlugin main) {
Logger logger = main.getLogger();
logger.info("Loading config values");
try (Stream<Path> 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<Path> 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<Path> 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<Path> 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<Path> 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<Path> 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 <E extends Enum<E>> List<E> getElements(List<String> st, Class<E> clazz) {
return st.stream().map((s) -> E.valueOf(clazz, s)).collect(Collectors.toList());
}
}

View File

@@ -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<Material> 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<BlockData> layer = new ProbabilityCollection<>();
for(Map.Entry<String, Integer> type : ((Map<String, Integer>) 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;
}
}

View File

@@ -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<Material> 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;
}
}

View File

@@ -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);
}
}

View File

@@ -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<Path> 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<Path> 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");
}
}

View File

@@ -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) {
}
}

View File

@@ -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) {}
}

View File

@@ -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<OreConfig, BiomeConfig.MaxMin> 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);
}
}
}
}

View File

@@ -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");

View File

@@ -0,0 +1,4 @@
package com.dfsek.terra.structure;
public class MultiPartStructure {
}