From 7a38284158b38a9f3982abc5f8131ee316779bc4 Mon Sep 17 00:00:00 2001 From: dfsek Date: Wed, 14 Jul 2021 07:30:22 -0700 Subject: [PATCH] implement flora populator --- .../addons/flora/BiomeFloraTemplate.java | 19 ++++++++++++ .../dfsek/terra/addons/flora/FloraAddon.java | 23 ++++++++++++++- .../terra/addons/flora/FloraLayerLoader.java | 29 +++++++++++++++++++ .../terra/addons/flora/FloraPopulator.java | 18 ++++++++---- .../event/events/config/ConfigLoadEvent.java | 11 ++++++- .../terra/config/pack/ConfigPackImpl.java | 5 ++-- 6 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/BiomeFloraTemplate.java create mode 100644 common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraLayerLoader.java diff --git a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/BiomeFloraTemplate.java b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/BiomeFloraTemplate.java new file mode 100644 index 000000000..810ea1e90 --- /dev/null +++ b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/BiomeFloraTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.flora; + +import com.dfsek.tectonic.annotations.Default; +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.config.ConfigTemplate; +import com.dfsek.terra.addons.flora.flora.FloraLayer; + +import java.util.Collections; +import java.util.List; + +public class BiomeFloraTemplate implements ConfigTemplate { + @Value("flora") + @Default + private List flora = Collections.emptyList(); + + public List getFlora() { + return flora; + } +} diff --git a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraAddon.java b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraAddon.java index 34d599476..cb31c17c9 100644 --- a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraAddon.java +++ b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraAddon.java @@ -1,16 +1,24 @@ package com.dfsek.terra.addons.flora; +import com.dfsek.terra.addons.flora.flora.FloraLayer; 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.HashMap; +import java.util.List; +import java.util.Map; + @Addon("config-flora") @Author("Terra") @Version("0.1.0") @@ -18,13 +26,26 @@ public class FloraAddon extends TerraAddon implements EventListener { @Inject private TerraPlugin main; + private final Map> flora = new HashMap<>(); // store Flora layers per biome by biome ID + @Override public void initialize() { main.getEventManager().registerListener(this, this); + main.applyLoader(FloraLayer.class, FloraLayerLoader::new); } public void onPackLoad(ConfigPackPreLoadEvent event) throws DuplicateEntryException { event.getPack().registerConfigType(new FloraConfigType(event.getPack()), "FLORA", 2); - event.getPack().getOrCreateRegistry(GenerationStageProvider.class).register("FLORA", pack -> new FloraPopulator(main)); + event.getPack().getOrCreateRegistry(GenerationStageProvider.class).register("FLORA", pack -> new FloraPopulator(main, this)); + } + + public void onBiomeLoad(ConfigLoadEvent event) { + if(BiomeBuilder.class.isAssignableFrom(event.getType().getTypeClass())) { + flora.put(event.getConfiguration().getID(), event.load(new BiomeFloraTemplate()).getFlora()); + } + } + + public List getFlora(TerraBiome biome) { + return flora.get(biome.getID()); } } diff --git a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraLayerLoader.java b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraLayerLoader.java new file mode 100644 index 000000000..cec57ea8c --- /dev/null +++ b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraLayerLoader.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.flora; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; +import com.dfsek.terra.addons.flora.flora.FloraLayer; +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; + +public class FloraLayerLoader implements ObjectTemplate { + @Value("density") + private double density; + + @Value("y") + private Range y; + + @Value("items") + private ProbabilityCollection items; + + @Value("distribution") + private NoiseSeeded distribution; + + + @Override + public FloraLayer get() { + return new FloraLayer(density, y, items, distribution.apply(2403L)); + } +} diff --git a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraPopulator.java b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraPopulator.java index d9dbe3cb0..f0c60343e 100644 --- a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraPopulator.java +++ b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/FloraPopulator.java @@ -1,21 +1,32 @@ package com.dfsek.terra.addons.flora; +import com.dfsek.terra.addons.flora.flora.FloraLayer; 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; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.generator.TerraGenerationStage; import org.jetbrains.annotations.NotNull; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + /** * Populates Flora */ public class FloraPopulator implements TerraGenerationStage { private final TerraPlugin main; + private final FloraAddon floraAddon; - public FloraPopulator(TerraPlugin main) { + public FloraPopulator(TerraPlugin main, FloraAddon floraAddon) { this.main = main; + this.floraAddon = floraAddon; } @SuppressWarnings("try") @@ -23,7 +34,6 @@ public class FloraPopulator implements TerraGenerationStage { public void populate(@NotNull World world, @NotNull Chunk chunk) { TerraWorld tw = main.getWorld(world); try(ProfileFrame ignore = main.getProfiler().profile("flora")) { - /* if(tw.getConfig().disableFlora()) return; if(!tw.isSafe()) return; @@ -31,9 +41,8 @@ public class FloraPopulator implements TerraGenerationStage { Map> layers = new HashMap<>(); for(int x = 0; x < 16; x++) { for(int z = 0; z < 16; z++) { - UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z); Vector2 l = new Vector2(x, z); - layers.put(l, biome.getConfig().getFlora()); + layers.put(l, floraAddon.getFlora(provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z))); } } @@ -51,7 +60,6 @@ public class FloraPopulator implements TerraGenerationStage { } iter++; } - */ } } } diff --git a/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigLoadEvent.java b/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigLoadEvent.java index 9e188d381..ee8dbb486 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigLoadEvent.java +++ b/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigLoadEvent.java @@ -17,11 +17,14 @@ public class ConfigLoadEvent implements PackEvent { private final Consumer loader; private final ConfigType type; - public ConfigLoadEvent(ConfigPack pack, AbstractConfiguration configuration, Consumer loader, ConfigType type) { + private final Object loaded; + + public ConfigLoadEvent(ConfigPack pack, AbstractConfiguration configuration, Consumer loader, ConfigType type, Object loaded) { this.pack = pack; this.configuration = configuration; this.loader = loader; this.type = type; + this.loaded = loaded; } @Override @@ -41,4 +44,10 @@ public class ConfigLoadEvent implements PackEvent { public ConfigType getType() { return type; } + + @SuppressWarnings("unchecked") + public T getLoadedObject(Class clazz) { + if(!clazz.isAssignableFrom(type.getTypeClass())) throw new ClassCastException("Cannot assign object from loader of type " + type.getTypeClass().getCanonicalName() + " to class " + clazz.getCanonicalName()); + return (T) loaded; + } } diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java b/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java index 4a48fdcfa..7dd311b49 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java +++ b/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java @@ -241,8 +241,9 @@ public class ConfigPackImpl implements ConfigPack { CheckedRegistry registry = getCheckedRegistry(configType.getTypeClass()); for(AbstractConfiguration config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()))) { try { - registry.register(config.getID(), ((ConfigFactory) configType.getFactory()).build(selfLoader.load(configType.getTemplate(this, main), config), main)); - main.getEventManager().callEvent(new ConfigLoadEvent(this, config, template -> selfLoader.load(template, configuration), configType)); + Object loaded = ((ConfigFactory) configType.getFactory()).build(selfLoader.load(configType.getTemplate(this, main), config), main); + registry.register(config.getID(), loaded); + main.getEventManager().callEvent(new ConfigLoadEvent(this, config, template -> selfLoader.load(template, configuration), configType, loaded)); } catch(DuplicateEntryException e) { throw new LoadException("Duplicate registry entry: ", e); }