diff --git a/lib/Tectonic-0.1.0.jar b/lib/Tectonic-0.1.0.jar index abcd04c58..cfd1c45a6 100644 Binary files a/lib/Tectonic-0.1.0.jar and b/lib/Tectonic-0.1.0.jar differ diff --git a/src/main/java/com/dfsek/terra/config/base/ConfigPack.java b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java index f4be5e8bc..08ba46ba8 100644 --- a/src/main/java/com/dfsek/terra/config/base/ConfigPack.java +++ b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java @@ -11,22 +11,26 @@ import com.dfsek.terra.config.exception.FileMissingException; import com.dfsek.terra.config.factories.BiomeFactory; import com.dfsek.terra.config.factories.BiomeGridFactory; import com.dfsek.terra.config.factories.CarverFactory; +import com.dfsek.terra.config.factories.FloraFactory; import com.dfsek.terra.config.factories.PaletteFactory; import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.loaders.NoiseBuilderLoader; import com.dfsek.terra.config.templates.BiomeGridTemplate; import com.dfsek.terra.config.templates.BiomeTemplate; import com.dfsek.terra.config.templates.CarverTemplate; +import com.dfsek.terra.config.templates.FloraTemplate; import com.dfsek.terra.config.templates.PaletteTemplate; import com.dfsek.terra.config.templates.StructureTemplate; import com.dfsek.terra.generation.config.NoiseBuilder; import com.dfsek.terra.registry.BiomeGridRegistry; import com.dfsek.terra.registry.BiomeRegistry; import com.dfsek.terra.registry.CarverRegistry; +import com.dfsek.terra.registry.FloraRegistry; import com.dfsek.terra.registry.PaletteRegistry; import com.dfsek.terra.registry.StructureRegistry; import com.dfsek.terra.util.ConfigUtil; import org.polydev.gaea.biome.Biome; +import org.polydev.gaea.world.Flora; import org.polydev.gaea.world.palette.Palette; import parsii.eval.Scope; @@ -50,6 +54,7 @@ public class ConfigPack { private final StructureRegistry structureRegistry = new StructureRegistry(); private final CarverRegistry carverRegistry = new CarverRegistry(); private final PaletteRegistry paletteRegistry = new PaletteRegistry(); + private final FloraRegistry floraRegistry = new FloraRegistry(); private final Scope varScope; @@ -77,7 +82,8 @@ public class ConfigPack { abstractConfigLoader .registerLoader(Palette.class, paletteRegistry) .registerLoader(Biome.class, biomeRegistry) - .registerLoader(UserDefinedCarver.class, carverRegistry); + .registerLoader(UserDefinedCarver.class, carverRegistry) + .registerLoader(Flora.class, floraRegistry); ConfigUtil.registerAllLoaders(abstractConfigLoader); List paletteTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "palettes").toPath()), PaletteTemplate::new); @@ -87,6 +93,13 @@ public class ConfigPack { Debug.info("Loaded palette " + palette.getID()); }); + List floraTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "flora").toPath()), FloraTemplate::new); + FloraFactory floraFactory = new FloraFactory(); + floraTemplates.forEach(flora -> { + floraRegistry.add(flora.getID(), floraFactory.build(flora)); + Debug.info("Loaded flora " + flora.getID()); + }); + List structureTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "structures/single").toPath()), StructureTemplate::new); structureTemplates.forEach(structure -> { structureRegistry.add(structure.getID(), structure); @@ -105,6 +118,8 @@ public class ConfigPack { biomeTemplates.forEach(biome -> { biomeRegistry.add(biome.getID(), biomeFactory.build(biome)); Debug.info("Loaded biome " + biome.getID()); + Debug.info("Flora: " + biome.getFlora()); + Debug.info("Carvers: " + biome.getCarvers()); }); List biomeGridTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "grids").toPath()), BiomeGridTemplate::new); diff --git a/src/main/java/com/dfsek/terra/config/factories/FloraFactory.java b/src/main/java/com/dfsek/terra/config/factories/FloraFactory.java new file mode 100644 index 000000000..88e43e16c --- /dev/null +++ b/src/main/java/com/dfsek/terra/config/factories/FloraFactory.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.config.factories; + +import com.dfsek.terra.biome.palette.PaletteLayer; +import com.dfsek.terra.config.templates.FloraTemplate; +import com.dfsek.terra.generation.items.flora.TerraFlora; +import org.bukkit.block.data.BlockData; +import org.polydev.gaea.util.FastRandom; +import org.polydev.gaea.world.palette.Palette; +import org.polydev.gaea.world.palette.RandomPalette; + +public class FloraFactory implements TerraFactory { + @Override + public TerraFlora build(FloraTemplate config) { + Palette palette = new RandomPalette<>(new FastRandom(2403)); + for(PaletteLayer layer : config.getFloraPalette()) { + palette.add(layer.getLayer(), layer.getSize()); + } + return new TerraFlora(palette, config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable()); + } +} diff --git a/src/main/java/com/dfsek/terra/config/loaders/FloraLayerLoader.java b/src/main/java/com/dfsek/terra/config/loaders/FloraLayerLoader.java new file mode 100644 index 000000000..b79650e89 --- /dev/null +++ b/src/main/java/com/dfsek/terra/config/loaders/FloraLayerLoader.java @@ -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.flora.FloraLayer; +import org.polydev.gaea.math.FastNoiseLite; +import org.polydev.gaea.math.ProbabilityCollection; +import org.polydev.gaea.math.Range; +import org.polydev.gaea.world.Flora; + +import java.lang.reflect.Type; +import java.util.Map; + +@SuppressWarnings("unchecked") +public class FloraLayerLoader implements TypeLoader { + @Override + public FloraLayer load(Type type, Object o, ConfigLoader configLoader) throws LoadException { + Map map = (Map) o; + int density = (Integer) map.get("density"); + Range range = (Range) configLoader.loadType(Range.class, map.get("y")); + if(range == null) throw new LoadException("Flora range unspecified"); + ProbabilityCollection items = (ProbabilityCollection) configLoader.loadType(Types.FLORA_PROBABILITY_COLLECTION_TYPE, map.get("items")); + + if(map.containsKey("simplex-frequency")) { + FastNoiseLite noiseLite = new FastNoiseLite(); + noiseLite.setFrequency((Double) map.get("simplex-frequency")); + return new FloraLayer(density, range, items, noiseLite); + } + + return new FloraLayer(density, range, items, null); + } +} diff --git a/src/main/java/com/dfsek/terra/config/loaders/Types.java b/src/main/java/com/dfsek/terra/config/loaders/Types.java index da85047fe..b1ce95e9d 100644 --- a/src/main/java/com/dfsek/terra/config/loaders/Types.java +++ b/src/main/java/com/dfsek/terra/config/loaders/Types.java @@ -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.world.Flora; import org.polydev.gaea.world.palette.Palette; import java.lang.reflect.Type; @@ -17,18 +18,21 @@ public final class Types { public static final Type MATERIAL_PROBABILITY_COLLECTION_TYPE; 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; static { MATERIAL_SET_TYPE = getType("materialSet"); MATERIAL_PROBABILITY_COLLECTION_TYPE = getType("materialProbabilityCollection"); BLOCK_DATA_PALETTE_TYPE = getType("blockDataPalette"); BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = getType("blockDataProbabilityCollection"); + FLORA_PROBABILITY_COLLECTION_TYPE = getType("floraProbabilityCollection"); } private Set materialSet; private Palette blockDataPalette; private ProbabilityCollection materialProbabilityCollection; private ProbabilityCollection blockDataProbabilityCollection; + private ProbabilityCollection floraProbabilityCollection; private static Type getType(String dummyFieldName) { try { diff --git a/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java b/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java index 1e5a8a111..c3f2e7bf8 100644 --- a/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java +++ b/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java @@ -8,6 +8,7 @@ import com.dfsek.terra.biome.palette.PaletteHolder; import com.dfsek.terra.biome.palette.SinglePalette; import com.dfsek.terra.carving.UserDefinedCarver; 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.structure.TerraStructure; import org.bukkit.Material; @@ -51,9 +52,9 @@ public class BiomeTemplate implements ConfigTemplate { @Value("noise-equation") @Abstractable private String noiseEquation; - @Value("ores") - @Abstractable - @Default + //@Value("ores") + //@Abstractable + //@Default private List ores = new GlueList<>(); @Value("ocean.level") @Abstractable @@ -76,6 +77,11 @@ public class BiomeTemplate implements ConfigTemplate { @Abstractable private String elevationEquation = null; + @Value("flora") + @Abstractable + @Default + private List flora = new GlueList<>(); + @Value("slabs.enable") @Abstractable @Default @@ -100,6 +106,10 @@ public class BiomeTemplate implements ConfigTemplate { return slabThreshold; } + public List getFlora() { + return flora; + } + public boolean doSlabs() { return doSlabs; } diff --git a/src/main/java/com/dfsek/terra/config/templates/FloraTemplate.java b/src/main/java/com/dfsek/terra/config/templates/FloraTemplate.java index 06390e7ac..4f8e37019 100644 --- a/src/main/java/com/dfsek/terra/config/templates/FloraTemplate.java +++ b/src/main/java/com/dfsek/terra/config/templates/FloraTemplate.java @@ -4,11 +4,11 @@ import com.dfsek.tectonic.annotations.Abstractable; import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.config.ConfigTemplate; -import com.dfsek.terra.biome.palette.PaletteHolder; +import com.dfsek.terra.biome.palette.PaletteLayer; import com.google.common.collect.Sets; import org.bukkit.Material; -import org.bukkit.block.data.BlockData; +import java.util.List; import java.util.Set; @SuppressWarnings({"FieldMayBeFinal", "unused"}) @@ -18,16 +18,21 @@ public class FloraTemplate implements ConfigTemplate { @Value("spawnable") @Abstractable - private Set spawnable; + private Set spawnable; @Value("replaceable") @Abstractable @Default - private Set replaceable = Sets.newHashSet(Material.AIR.createBlockData()); + private Set replaceable = Sets.newHashSet(Material.AIR); + + @Value("irrigable") + @Abstractable + @Default + private Set irrigable = null; @Value("layers") @Abstractable - private PaletteHolder floraPalette; + private List palette; @Value("physics") @Abstractable @@ -39,20 +44,24 @@ public class FloraTemplate implements ConfigTemplate { @Default private boolean ceiling = false; - public Set getReplaceable() { + public Set getReplaceable() { return replaceable; } - public Set getSpawnable() { + public Set getSpawnable() { return spawnable; } + public Set getIrrigable() { + return irrigable; + } + public String getID() { return id; } - public PaletteHolder getFloraPalette() { - return floraPalette; + public List getFloraPalette() { + return palette; } public boolean doPhysics() { diff --git a/src/main/java/com/dfsek/terra/generation/items/flora/FloraLayer.java b/src/main/java/com/dfsek/terra/generation/items/flora/FloraLayer.java new file mode 100644 index 000000000..13fbedd49 --- /dev/null +++ b/src/main/java/com/dfsek/terra/generation/items/flora/FloraLayer.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.generation.items.flora; + +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 org.polydev.gaea.world.Flora; + +import java.util.Random; + +public class FloraLayer { + private final double density; + private final Range level; + private final ProbabilityCollection layer; + private final FastNoiseLite noise; + + public FloraLayer(double density, Range level, ProbabilityCollection layer, FastNoiseLite noise) { + this.density = density; + this.level = level; + this.layer = layer; + this.noise = noise; + } + + public double getDensity() { + return density; + } + + public void plant(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())); + } +} diff --git a/src/main/java/com/dfsek/terra/generation/items/TerraFlora.java b/src/main/java/com/dfsek/terra/generation/items/flora/TerraFlora.java similarity index 98% rename from src/main/java/com/dfsek/terra/generation/items/TerraFlora.java rename to src/main/java/com/dfsek/terra/generation/items/flora/TerraFlora.java index b77b3313e..dbbd087f2 100644 --- a/src/main/java/com/dfsek/terra/generation/items/TerraFlora.java +++ b/src/main/java/com/dfsek/terra/generation/items/flora/TerraFlora.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.generation.items; +package com.dfsek.terra.generation.items.flora; import net.jafama.FastMath; import org.bukkit.Chunk; diff --git a/src/main/java/com/dfsek/terra/population/FloraPopulator.java b/src/main/java/com/dfsek/terra/population/FloraPopulator.java index c4b6e500f..b5412b67e 100644 --- a/src/main/java/com/dfsek/terra/population/FloraPopulator.java +++ b/src/main/java/com/dfsek/terra/population/FloraPopulator.java @@ -4,7 +4,7 @@ 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.config.templates.BiomeTemplate; +import com.dfsek.terra.procgen.math.Vector2; import org.bukkit.Chunk; import org.bukkit.World; import org.jetbrains.annotations.NotNull; @@ -24,29 +24,14 @@ public class FloraPopulator extends GaeaBlockPopulator { try(ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("FloraTime")) { TerraWorld tw = TerraWorld.getWorld(world); if(!tw.isSafe()) return; - int originX = chunk.getX() << 4; - int originZ = chunk.getZ() << 4; TerraBiomeGrid grid = tw.getGrid(); for(int x = 0; x < 16; x++) { for(int z = 0; z < 16; z++) { UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE); - if(biome.getDecorator().getFloraChance() <= 0) continue; - try { - BiomeTemplate c = biome.getConfig(); - /* - for(int i = 0; i < 0; i++) { - Flora item; - if(f.isFloraSimplex()) - item = biome.getDecorator().getFlora().get(f.getFloraNoise(), originX + x, originZ + z); - else item = biome.getDecorator().getFlora().get(random); - for(Block highest : item.getValidSpawnsAt(chunk, x, z, c.getFloraHeights(item))) { - if(random.nextInt(100) < biome.getDecorator().getFloraChance()) - item.plant(highest.getLocation()); - } - } - */ - } catch(NullPointerException ignore) { - } + Vector2 l = new Vector2(x, z); + biome.getConfig().getFlora().forEach(layer -> { + if(layer.getDensity() >= random.nextDouble() * 100D) layer.plant(chunk, l, random); + }); } } } diff --git a/src/main/java/com/dfsek/terra/util/ConfigUtil.java b/src/main/java/com/dfsek/terra/util/ConfigUtil.java index 4d985df7a..0889ac73f 100644 --- a/src/main/java/com/dfsek/terra/util/ConfigUtil.java +++ b/src/main/java/com/dfsek/terra/util/ConfigUtil.java @@ -5,6 +5,7 @@ import com.dfsek.terra.biome.palette.PaletteHolder; import com.dfsek.terra.biome.palette.PaletteLayer; import com.dfsek.terra.carving.CarverPalette; import com.dfsek.terra.config.loaders.BlockDataLoader; +import com.dfsek.terra.config.loaders.FloraLayerLoader; import com.dfsek.terra.config.loaders.GridSpawnLoader; import com.dfsek.terra.config.loaders.MaterialLoader; import com.dfsek.terra.config.loaders.PaletteHolderLoader; @@ -13,6 +14,7 @@ import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.RangeLoader; import com.dfsek.terra.config.loaders.VanillaBiomeLoader; import com.dfsek.terra.config.loaders.base.CarverPaletteLoader; +import com.dfsek.terra.generation.items.flora.FloraLayer; import com.dfsek.terra.procgen.GridSpawn; import org.bukkit.Material; import org.bukkit.block.Biome; @@ -63,6 +65,7 @@ public final class ConfigUtil { .registerLoader(PaletteLayer.class, new PaletteLayerLoader()) .registerLoader(Biome.class, new VanillaBiomeLoader()) .registerLoader(BlockData.class, new BlockDataLoader()) - .registerLoader(Material.class, new MaterialLoader()); + .registerLoader(Material.class, new MaterialLoader()) + .registerLoader(FloraLayer.class, new FloraLayerLoader()); } }