This commit is contained in:
dfsek
2020-11-30 12:26:46 -07:00
parent ce97732da7
commit 3eaab219f1
20 changed files with 222 additions and 58 deletions

View File

@@ -35,7 +35,7 @@ val versionObj = Version("2", "0", "0", true)
version = versionObj
dependencies {
val gaeaVersion = "1.14.3"
val gaeaVersion = "1.14.4"
compileOnly(name = "Gaea-${gaeaVersion}", group = "")
testImplementation(name = "Gaea-${gaeaVersion}", group = "")

Binary file not shown.

BIN
lib/Gaea-1.14.4.jar Normal file

Binary file not shown.

View File

@@ -15,10 +15,12 @@ import com.dfsek.terra.config.factories.FloraFactory;
import com.dfsek.terra.config.factories.OreFactory;
import com.dfsek.terra.config.factories.PaletteFactory;
import com.dfsek.terra.config.factories.TerraFactory;
import com.dfsek.terra.config.factories.TreeFactory;
import com.dfsek.terra.config.files.FolderLoader;
import com.dfsek.terra.config.files.Loader;
import com.dfsek.terra.config.files.ZIPLoader;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.loaders.StructureLoader;
import com.dfsek.terra.config.templates.AbstractableTemplate;
import com.dfsek.terra.config.templates.BiomeGridTemplate;
import com.dfsek.terra.config.templates.BiomeTemplate;
@@ -27,6 +29,7 @@ import com.dfsek.terra.config.templates.FloraTemplate;
import com.dfsek.terra.config.templates.OreTemplate;
import com.dfsek.terra.config.templates.PaletteTemplate;
import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.config.templates.TreeTemplate;
import com.dfsek.terra.generation.items.ores.Ore;
import com.dfsek.terra.registry.BiomeGridRegistry;
import com.dfsek.terra.registry.BiomeRegistry;
@@ -36,8 +39,11 @@ import com.dfsek.terra.registry.OreRegistry;
import com.dfsek.terra.registry.PaletteRegistry;
import com.dfsek.terra.registry.StructureRegistry;
import com.dfsek.terra.registry.TerraRegistry;
import com.dfsek.terra.registry.TreeRegistry;
import com.dfsek.terra.structure.Structure;
import com.dfsek.terra.util.ConfigUtil;
import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.tree.Tree;
import org.polydev.gaea.world.Flora;
import org.polydev.gaea.world.palette.Palette;
import parsii.eval.Scope;
@@ -69,9 +75,10 @@ public class ConfigPack {
private final PaletteRegistry paletteRegistry = new PaletteRegistry();
private final FloraRegistry floraRegistry = new FloraRegistry();
private final OreRegistry oreRegistry = new OreRegistry();
private final TreeRegistry treeRegistry = new TreeRegistry();
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
private final ConfigLoader loader = new ConfigLoader();
private final ConfigLoader selfLoader = new ConfigLoader();
private final Scope varScope = new Scope();
{
@@ -80,9 +87,10 @@ public class ConfigPack {
.registerLoader(Biome.class, biomeRegistry)
.registerLoader(UserDefinedCarver.class, carverRegistry)
.registerLoader(Flora.class, floraRegistry)
.registerLoader(Ore.class, oreRegistry);
.registerLoader(Ore.class, oreRegistry)
.registerLoader(Tree.class, treeRegistry);
ConfigUtil.registerAllLoaders(abstractConfigLoader);
ConfigUtil.registerAllLoaders(loader);
ConfigUtil.registerAllLoaders(selfLoader);
}
public ConfigPack(File folder) throws ConfigException {
@@ -91,7 +99,7 @@ public class ConfigPack {
File pack = new File(folder, "pack.yml");
try {
loader.load(template, new FileInputStream(pack));
selfLoader.load(template, new FileInputStream(pack));
} catch(FileNotFoundException e) {
throw new FileMissingException("No pack.yml file found in " + folder.getAbsolutePath(), e);
}
@@ -117,7 +125,7 @@ public class ConfigPack {
}
if(stream == null) throw new FileMissingException("No pack.yml file found in " + file.getName());
loader.load(template, stream);
selfLoader.load(template, stream);
load(new ZIPLoader(file));
LangUtil.log("config-pack.loaded", Level.INFO, template.getID(), String.valueOf((System.nanoTime() - l) / 1000000D));
@@ -127,11 +135,13 @@ public class ConfigPack {
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
varScope.create(var.getKey()).setValue(var.getValue());
}
abstractConfigLoader.registerLoader(Structure.class, new StructureLoader(loader));
loader
.open("palettes").then(streams -> buildAll(new PaletteFactory(), paletteRegistry, abstractConfigLoader.load(streams, PaletteTemplate::new))).close()
.open("ores").then(streams -> buildAll(new OreFactory(), oreRegistry, abstractConfigLoader.load(streams, OreTemplate::new))).close()
.open("flora").then(streams -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.load(streams, FloraTemplate::new))).close()
.open("carving").then(streams -> buildAll(new CarverFactory(this), carverRegistry, abstractConfigLoader.load(streams, CarverTemplate::new))).close()
.open("structures/trees").then(streams -> buildAll(new TreeFactory(), treeRegistry, abstractConfigLoader.load(streams, TreeTemplate::new))).close()
.open("biomes").then(streams -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.load(streams, () -> new BiomeTemplate(this)))).close()
.open("grids").then(streams -> buildAll(new BiomeGridFactory(), biomeGridRegistry, abstractConfigLoader.load(streams, BiomeGridTemplate::new))).close();
}

View File

@@ -0,0 +1,13 @@
package com.dfsek.terra.config.factories;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.terra.config.templates.TreeTemplate;
import com.dfsek.terra.generation.items.TerraTree;
import org.polydev.gaea.tree.Tree;
public class TreeFactory implements TerraFactory<TreeTemplate, Tree> {
@Override
public Tree build(TreeTemplate config) throws LoadException {
return new TerraTree(config.getSpawnable(), config.getyOffset(), config.getStructures());
}
}

View File

@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
@@ -18,6 +19,11 @@ public class FolderLoader extends Loader {
this.path = path;
}
@Override
public InputStream get(String singleFile) throws IOException {
return new FileInputStream(new File(path.toFile(), singleFile));
}
@Override
protected void load(String directory) {
File newPath = new File(path.toFile(), directory);

View File

@@ -20,6 +20,14 @@ public abstract class Loader {
return this;
}
/**
* Get a single file from this Loader.
*
* @param singleFile File to get
* @return InputStream from file.
*/
public abstract InputStream get(String singleFile) throws IOException;
/**
* Open a subdirectory.
*

View File

@@ -1,6 +1,7 @@
package com.dfsek.terra.config.files;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -12,6 +13,16 @@ public class ZIPLoader extends Loader {
this.file = file;
}
@Override
public InputStream get(String singleFile) throws IOException {
Enumeration<? extends ZipEntry> entries = file.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if(!entry.isDirectory() && entry.getName().equals(singleFile)) return file.getInputStream(entry);
}
throw new IllegalArgumentException("No such file: " + singleFile);
}
@Override
protected void load(String directory) {
Enumeration<? extends ZipEntry> entries = file.entries();

View File

@@ -17,7 +17,7 @@ public class FloraLayerLoader implements TypeLoader<FloraLayer> {
@Override
public FloraLayer load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) o;
int density = (Integer) map.get("density");
double density = ((Number) map.get("density")).doubleValue();
Range range = (Range) configLoader.loadType(Range.class, map.get("y"));
if(range == null) throw new LoadException("Flora range unspecified");
ProbabilityCollection<Flora> items = (ProbabilityCollection<Flora>) configLoader.loadType(Types.FLORA_PROBABILITY_COLLECTION_TYPE, map.get("items"));

View File

@@ -0,0 +1,28 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.config.files.Loader;
import com.dfsek.terra.structure.Structure;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
public class StructureLoader implements TypeLoader<Structure> {
private final Loader loader;
public StructureLoader(Loader loader) {
this.loader = loader;
}
@Override
public Structure load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
try(InputStream stream = loader.get("structures/data/" + o + ".tstructure")) {
return Structure.fromStream(stream);
} catch(IOException | ClassNotFoundException e) {
throw new LoadException("Unable to load structure", e);
}
}
}

View File

@@ -0,0 +1,33 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.generation.items.tree.TreeLayer;
import org.polydev.gaea.math.FastNoiseLite;
import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.tree.Tree;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class TreeLayerLoader implements TypeLoader<TreeLayer> {
@Override
public TreeLayer load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) o;
double density = ((Number) map.get("density")).doubleValue();
Range range = (Range) configLoader.loadType(Range.class, map.get("y"));
if(range == null) throw new LoadException("Tree range unspecified");
ProbabilityCollection<Tree> items = (ProbabilityCollection<Tree>) configLoader.loadType(Types.TREE_PROBABILITY_COLLECTION_TYPE, map.get("items"));
if(map.containsKey("simplex-frequency")) {
FastNoiseLite noiseLite = new FastNoiseLite();
noiseLite.setFrequency((Double) map.get("simplex-frequency"));
return new TreeLayer(density, range, items, noiseLite);
}
return new TreeLayer(density, range, items, null);
}
}

View File

@@ -3,6 +3,7 @@ package com.dfsek.terra.config.loaders;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.tree.Tree;
import org.polydev.gaea.world.Flora;
import org.polydev.gaea.world.palette.Palette;
@@ -19,6 +20,7 @@ public final class Types {
public static final Type BLOCK_DATA_PALETTE_TYPE;
public static final Type BLOCK_DATA_PROBABILITY_COLLECTION_TYPE;
public static final Type FLORA_PROBABILITY_COLLECTION_TYPE;
public static final Type TREE_PROBABILITY_COLLECTION_TYPE;
static {
MATERIAL_SET_TYPE = getType("materialSet");
@@ -26,6 +28,7 @@ public final class Types {
BLOCK_DATA_PALETTE_TYPE = getType("blockDataPalette");
BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = getType("blockDataProbabilityCollection");
FLORA_PROBABILITY_COLLECTION_TYPE = getType("floraProbabilityCollection");
TREE_PROBABILITY_COLLECTION_TYPE = getType("treeProbabilityCollection");
}
private Set<Material> materialSet;
@@ -33,6 +36,7 @@ public final class Types {
private ProbabilityCollection<Material> materialProbabilityCollection;
private ProbabilityCollection<BlockData> blockDataProbabilityCollection;
private ProbabilityCollection<Flora> floraProbabilityCollection;
private ProbabilityCollection<Tree> treeProbabilityCollection;
private static Type getType(String dummyFieldName) {
try {

View File

@@ -12,6 +12,7 @@ import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.generation.items.flora.FloraLayer;
import com.dfsek.terra.generation.items.ores.Ore;
import com.dfsek.terra.generation.items.ores.OreConfig;
import com.dfsek.terra.generation.items.tree.TreeLayer;
import com.dfsek.terra.math.BlankFunction;
import com.dfsek.terra.structure.TerraStructure;
import org.bukkit.Material;
@@ -81,6 +82,11 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Default
private List<FloraLayer> flora = new GlueList<>();
@Value("trees")
@Abstractable
@Default
private List<TreeLayer> trees = new GlueList<>();
@Value("slabs.enable")
@Abstractable
@Default
@@ -158,6 +164,10 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
return palette;
}
public List<TreeLayer> getTrees() {
return trees;
}
public PaletteHolder getSlantPalette() {
return slantPalette;
}

View File

@@ -0,0 +1,41 @@
package com.dfsek.terra.generation.items;
import com.dfsek.terra.procgen.math.Vector2;
import org.bukkit.Chunk;
import org.polydev.gaea.math.FastNoiseLite;
import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.Range;
import java.util.Random;
public abstract class PlaceableLayer<T> {
protected final double density;
protected final Range level;
protected final ProbabilityCollection<T> layer;
protected final FastNoiseLite noise;
public PlaceableLayer(double density, Range level, ProbabilityCollection<T> layer, FastNoiseLite noise) {
this.density = density;
this.level = level;
this.layer = layer;
this.noise = noise;
}
public FastNoiseLite getNoise() {
return noise;
}
public double getDensity() {
return density;
}
public Range getLevel() {
return level;
}
public ProbabilityCollection<T> getLayer() {
return layer;
}
public abstract void place(Chunk chunk, Vector2 coords, Random random);
}

View File

@@ -17,13 +17,11 @@ import java.util.Set;
public class TerraTree implements Tree {
private final Set<Material> spawnable;
private final String id;
private final int yOffset;
private final ProbabilityCollection<Structure> structure;
public TerraTree(Set<Material> spawnable, String id, int yOffset, ProbabilityCollection<Structure> structure) {
public TerraTree(Set<Material> spawnable, int yOffset, ProbabilityCollection<Structure> structure) {
this.spawnable = spawnable;
this.id = id;
this.yOffset = yOffset;
this.structure = structure;
}
@@ -40,6 +38,11 @@ public class TerraTree implements Tree {
return true;
}
@Override
public Set<Material> getSpawnable() {
return spawnable;
}
public boolean plantBlockCheck(Location location, Random random) {
location.subtract(0, 1, 0);
Location mut = location.clone().subtract(0, yOffset, 0);

View File

@@ -1,5 +1,6 @@
package com.dfsek.terra.generation.items.flora;
import com.dfsek.terra.generation.items.PlaceableLayer;
import com.dfsek.terra.procgen.math.Vector2;
import org.bukkit.Chunk;
import org.polydev.gaea.math.FastNoiseLite;
@@ -9,24 +10,17 @@ import org.polydev.gaea.world.Flora;
import java.util.Random;
public class FloraLayer {
private final double density;
private final Range level;
private final ProbabilityCollection<Flora> layer;
private final FastNoiseLite noise;
public class FloraLayer extends PlaceableLayer<Flora> {
public FloraLayer(double density, Range level, ProbabilityCollection<Flora> layer, FastNoiseLite noise) {
this.density = density;
this.level = level;
this.layer = layer;
this.noise = noise;
super(density, level, layer, noise);
}
public double getDensity() {
return density;
}
public void plant(Chunk chunk, Vector2 coords, Random random) {
public void place(Chunk chunk, Vector2 coords, Random random) {
Flora item = noise == null ? layer.get(random) : layer.get(noise, (chunk.getX() << 4) + coords.getX(), (chunk.getZ() << 4) + coords.getZ());
item.getValidSpawnsAt(chunk, (int) coords.getX(), (int) coords.getZ(), level).forEach(block -> item.plant(block.getLocation()));
}

View File

@@ -0,0 +1,31 @@
package com.dfsek.terra.generation.items.tree;
import com.dfsek.terra.Terra;
import com.dfsek.terra.generation.items.PlaceableLayer;
import com.dfsek.terra.procgen.math.Vector2;
import org.bukkit.Chunk;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.polydev.gaea.math.FastNoiseLite;
import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.tree.Tree;
import java.util.Random;
public class TreeLayer extends PlaceableLayer<Tree> {
public TreeLayer(double density, Range level, ProbabilityCollection<Tree> layer, FastNoiseLite noise) {
super(density, level, layer, noise);
}
@Override
public void place(Chunk chunk, Vector2 coords, Random random) {
Tree item = layer.get(random);
Block current = chunk.getBlock((int) coords.getX(), level.getMax(), (int) coords.getZ());
for(int ignored : level) {
current = current.getRelative(BlockFace.DOWN);
if(item.getSpawnable().contains(current.getType())) item.plant(current.getLocation(), random, Terra.getInstance());
}
}
}

View File

@@ -30,7 +30,7 @@ public class FloraPopulator extends GaeaBlockPopulator {
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
Vector2 l = new Vector2(x, z);
biome.getConfig().getFlora().forEach(layer -> {
if(layer.getDensity() >= random.nextDouble() * 100D) layer.plant(chunk, l, random);
if(layer.getDensity() >= random.nextDouble() * 100D) layer.place(chunk, l, random);
});
}
}

View File

@@ -4,49 +4,20 @@ import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
import com.dfsek.terra.generation.items.tree.TreeLayer;
import com.dfsek.terra.procgen.math.Vector2;
import net.jafama.FastMath;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.util.GlueList;
import java.util.List;
import java.util.Random;
public class TreePopulator extends GaeaBlockPopulator {
/*
private static void doTrees(@NotNull UserDefinedBiome biome, TerraWorld world, @NotNull Random random, @NotNull Chunk chunk, int x, int z) {
for(Block block : getValidTreeSpawnsAt(chunk, x, z, new Range(0, 254))) {
Tree tree = biome.getDecorator().getTrees().get(random);
Range range = biome.getConfig().getTreeRange(tree);
if(!range.isInRange(block.getY())) continue;
try {
Location l = block.getLocation();
TreeGenerateEvent event = new TreeGenerateEvent(world, l, tree);
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled()) tree.plant(l, random, Terra.getInstance());
} catch(NullPointerException ignore) {
}
}
}
*/
// TODO: implementation
public static List<Block> getValidTreeSpawnsAt(Chunk chunk, int x, int z, Range check) {
List<Block> blocks = new GlueList<>();
for(int y : check) {
if(chunk.getBlock(x, y, z).getType().isSolid() && chunk.getBlock(x, y + 1, z).isPassable()) {
blocks.add(chunk.getBlock(x, y + 1, z));
}
}
return blocks;
}
private static int offset(Random r, int i) {
return FastMath.min(FastMath.max(i + r.nextInt(3) - 1, 0), 15);
@@ -62,11 +33,9 @@ public class TreePopulator extends GaeaBlockPopulator {
for(int x = 0; x < 16; x += 2) {
for(int z = 0; z < 16; z += 2) {
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
int treeChance = biome.getDecorator().getTreeDensity();
if(random.nextInt(1000) < treeChance) {
int xt = offset(random, x);
int zt = offset(random, z);
//doTrees(biome, tw, random, chunk, xt, zt); TODO: implementation
for(TreeLayer layer : biome.getConfig().getTrees()) {
if(layer.getDensity() >= random.nextDouble() * 100)
layer.place(chunk, new Vector2(offset(random, x), offset(random, z)), random);
}
}
}

View File

@@ -15,12 +15,14 @@ import com.dfsek.terra.config.loaders.PaletteHolderLoader;
import com.dfsek.terra.config.loaders.PaletteLayerLoader;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.RangeLoader;
import com.dfsek.terra.config.loaders.TreeLayerLoader;
import com.dfsek.terra.config.loaders.VanillaBiomeLoader;
import com.dfsek.terra.config.loaders.base.CarverPaletteLoader;
import com.dfsek.terra.generation.config.NoiseBuilder;
import com.dfsek.terra.generation.items.flora.FloraLayer;
import com.dfsek.terra.generation.items.ores.Ore;
import com.dfsek.terra.generation.items.ores.OreConfig;
import com.dfsek.terra.generation.items.tree.TreeLayer;
import com.dfsek.terra.procgen.GridSpawn;
import org.bukkit.Material;
import org.bukkit.block.Biome;
@@ -47,6 +49,7 @@ public final class ConfigUtil {
.registerLoader(FloraLayer.class, new FloraLayerLoader())
.registerLoader(Ore.Type.class, new OreTypeLoader())
.registerLoader(OreConfig.class, new OreConfigLoader())
.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader());
.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader())
.registerLoader(TreeLayer.class, new TreeLayerLoader());
}
}