From 34e78ab55e229b69352955b3aacdb8c2bce86b44 Mon Sep 17 00:00:00 2001 From: dfsek Date: Wed, 14 Jul 2021 14:49:58 -0700 Subject: [PATCH] implement tree populator --- .../terra/addons/tree/BiomeTreeTemplate.java | 19 ++++++++++++ .../dfsek/terra/addons/tree/TreeAddon.java | 25 +++++++++++++++- .../terra/addons/tree/TreePopulator.java | 11 +++---- .../terra/addons/tree/tree/TreeLayer.java | 10 +++---- .../addons/tree/tree/TreeLayerTemplate.java | 29 +++++++++++++++++++ .../script/functions/CheckFunction.java | 6 ++-- .../terra/registry/master/AddonRegistry.java | 6 ++-- 7 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/BiomeTreeTemplate.java create mode 100644 common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayerTemplate.java diff --git a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/BiomeTreeTemplate.java b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/BiomeTreeTemplate.java new file mode 100644 index 000000000..dc34e10be --- /dev/null +++ b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/BiomeTreeTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.tree; + +import com.dfsek.tectonic.annotations.Default; +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.config.ConfigTemplate; +import com.dfsek.terra.addons.tree.tree.TreeLayer; + +import java.util.Collections; +import java.util.List; + +public class BiomeTreeTemplate implements ConfigTemplate { + @Value("trees") + @Default + private List trees = Collections.emptyList(); + + public List getTrees() { + return trees; + } +} diff --git a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreeAddon.java b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreeAddon.java index dd1403e0a..9a5af3dbc 100644 --- a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreeAddon.java +++ b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreeAddon.java @@ -1,16 +1,26 @@ package com.dfsek.terra.addons.tree; +import com.dfsek.terra.addons.tree.tree.TreeLayer; +import com.dfsek.terra.addons.tree.tree.TreeLayerTemplate; import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.addon.TerraAddon; import com.dfsek.terra.api.addon.annotations.Addon; import com.dfsek.terra.api.addon.annotations.Author; import com.dfsek.terra.api.addon.annotations.Version; import com.dfsek.terra.api.event.EventListener; +import com.dfsek.terra.api.event.events.config.ConfigLoadEvent; import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent; import com.dfsek.terra.api.injection.annotations.Inject; import com.dfsek.terra.api.registry.exception.DuplicateEntryException; +import com.dfsek.terra.api.util.seeded.BiomeBuilder; +import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.generator.GenerationStageProvider; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + @Addon("config-tree") @Author("Terra") @Version("1.0.0") @@ -18,13 +28,26 @@ public class TreeAddon extends TerraAddon implements EventListener { @Inject private TerraPlugin main; + private final Map> trees = new HashMap<>(); + @Override public void initialize() { main.getEventManager().registerListener(this, this); + main.applyLoader(TreeLayer.class, TreeLayerTemplate::new); } public void onPackLoad(ConfigPackPreLoadEvent event) throws DuplicateEntryException { event.getPack().registerConfigType(new TreeConfigType(event.getPack()), "TREE", 2); - event.getPack().getOrCreateRegistry(GenerationStageProvider.class).register("TREE", pack -> new TreePopulator(main)); + event.getPack().getOrCreateRegistry(GenerationStageProvider.class).register("TREE", pack -> new TreePopulator(main, this)); + } + + public void onBiomeLoad(ConfigLoadEvent event) { + if(BiomeBuilder.class.isAssignableFrom(event.getType().getTypeClass())) { + trees.put(event.getConfiguration().getID(), event.load(new BiomeTreeTemplate()).getTrees()); + } + } + + public List getTrees(TerraBiome biome) { + return trees.getOrDefault(biome.getID(), Collections.emptyList()); } } diff --git a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreePopulator.java b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreePopulator.java index b02ea6d8f..63580a2c7 100644 --- a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreePopulator.java +++ b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/TreePopulator.java @@ -1,8 +1,10 @@ package com.dfsek.terra.addons.tree; +import com.dfsek.terra.addons.tree.tree.TreeLayer; import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.util.PopulationUtil; +import com.dfsek.terra.api.vector.Vector2; import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World; @@ -16,9 +18,11 @@ import java.util.Random; public class TreePopulator implements TerraGenerationStage { private final TerraPlugin main; + private final TreeAddon addon; - public TreePopulator(TerraPlugin main) { + public TreePopulator(TerraPlugin main, TreeAddon addon) { this.main = main; + this.addon = addon; } private static int offset(Random r, int i) { @@ -36,14 +40,11 @@ public class TreePopulator implements TerraGenerationStage { Random random = PopulationUtil.getRandom(chunk); for(int x = 0; x < 16; x += 2) { for(int z = 0; z < 16; z += 2) { - /* - UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z); - for(TreeLayer layer : biome.getConfig().getTrees()) { + for(TreeLayer layer : addon.getTrees(provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z))) { if(layer.getDensity() >= random.nextDouble() * 100) { layer.place(chunk, new Vector2(offset(random, x), offset(random, z))); } } - */ } } } diff --git a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayer.java b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayer.java index 34d2e1bf1..a45e0246e 100644 --- a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayer.java +++ b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayer.java @@ -42,13 +42,13 @@ public class TreeLayer { public void place(Chunk chunk, Vector2 coords) { Tree item = layer.get(noise, coords.getX(), coords.getZ()); BlockState current; - int i = 0; - for(int ignored : level) { - current = chunk.getBlock((int) coords.getX(), level.getMax() - i, (int) coords.getZ()); + int cx = (chunk.getX()) << 4; + int cz = (chunk.getZ()) << 4; + for(int y : level) { + current = chunk.getBlock((int) coords.getX(), y, (int) coords.getZ()); if(item.getSpawnable().contains(current.getBlockType())) { - item.plant(new Vector3((int) coords.getX(), level.getMax() - i, (int) coords.getZ()), chunk.getWorld(), PopulationUtil.getRandom(chunk, coords.hashCode())); + item.plant(new Vector3((int) coords.getX() + cx, y+1, (int) coords.getZ() + cz), chunk.getWorld(), PopulationUtil.getRandom(chunk, coords.hashCode())); } - i--; } } } diff --git a/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayerTemplate.java b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayerTemplate.java new file mode 100644 index 000000000..f595fbf47 --- /dev/null +++ b/common/addons/config-tree/src/main/java/com/dfsek/terra/addons/tree/tree/TreeLayerTemplate.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.tree.tree; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; +import com.dfsek.terra.api.structure.Structure; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.util.collection.ProbabilityCollection; +import com.dfsek.terra.api.util.seeded.NoiseSeeded; +import com.dfsek.terra.api.world.Flora; +import com.dfsek.terra.api.world.Tree; + +public class TreeLayerTemplate implements ObjectTemplate { + @Value("density") + private double density; + + @Value("y") + private Range y; + + @Value("items") + private ProbabilityCollection items; + + @Value("distribution") + private NoiseSeeded distribution; + + @Override + public TreeLayer get() { + return new TreeLayer(density, y, items, distribution.apply(2403L)); + } +} diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckFunction.java index f79921a6e..b97a7a6d7 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckFunction.java @@ -48,6 +48,8 @@ public class CheckFunction implements Function { } private String apply(Vector3 vector, World world) { + int y = vector.getBlockY(); + if(y >= world.getMaxHeight() || y < 0) return "AIR"; TerraWorld tw = main.getWorld(world); SamplerCache cache = tw.getConfig().getSamplerCache(); double comp = sample(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), cache); @@ -57,8 +59,8 @@ public class CheckFunction implements Function { //BiomeProvider provider = tw.getBiomeProvider(); //TerraBiome b = provider.getBiome(vector.getBlockX(), vector.getBlockZ()); - //if(vector.getY() > c.getSeaLevel()) return "AIR"; // Above sea level - return "OCEAN"; // Below sea level + /*if(vector.getY() > c.getSeaLevel())*/ return "AIR"; // Above sea level + //return "OCEAN"; // Below sea level } private double sample(int x, int y, int z, SamplerCache cache) { diff --git a/common/implementation/src/main/java/com/dfsek/terra/registry/master/AddonRegistry.java b/common/implementation/src/main/java/com/dfsek/terra/registry/master/AddonRegistry.java index e8490d644..0aba01392 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/registry/master/AddonRegistry.java +++ b/common/implementation/src/main/java/com/dfsek/terra/registry/master/AddonRegistry.java @@ -94,9 +94,9 @@ public class AddonRegistry extends OpenRegistryImpl { registerChecked(loadedAddon.getName(), loadedAddon); } catch(DuplicateEntryException e) { valid = false; - main.logger().severe("Duplicate com.dfsek.terra.addon ID; com.dfsek.terra.addon with ID " + loadedAddon.getName() + " is already loaded."); - main.logger().severe("Existing com.dfsek.terra.addon class: " + get(loadedAddon.getName()).getClass().getCanonicalName()); - main.logger().severe("Duplicate com.dfsek.terra.addon class: " + addonClass.getCanonicalName()); + main.logger().severe("Duplicate addon ID; addon with ID " + loadedAddon.getName() + " is already loaded."); + main.logger().severe("Existing addon class: " + get(loadedAddon.getName()).getClass().getCanonicalName()); + main.logger().severe("Duplicate addon class: " + addonClass.getCanonicalName()); } } } catch(AddonLoadException | IOException e) {