mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-04 00:45:57 +00:00
Merge pull request #236 from PolyhedralDev/dev/addonification
Addonification
This commit is contained in:
commit
3c4c8c62b2
@ -10,4 +10,5 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"implementation"("com.github.jengelman.gradle.plugins:shadow:+")
|
"implementation"("com.github.jengelman.gradle.plugins:shadow:+")
|
||||||
|
"implementation"("org.yaml:snakeyaml:1.27")
|
||||||
}
|
}
|
41
buildSrc/src/main/kotlin/com/dfsek/terra/AddonConfig.kt
Normal file
41
buildSrc/src/main/kotlin/com/dfsek/terra/AddonConfig.kt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package com.dfsek.terra
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.Task
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import java.io.File
|
||||||
|
import java.util.function.Predicate
|
||||||
|
import kotlin.streams.asStream
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a directory where addons will be put.
|
||||||
|
*/
|
||||||
|
fun Project.addonDir(dir: File, task: Task) {
|
||||||
|
task.doFirst {
|
||||||
|
dir.parentFile.mkdirs()
|
||||||
|
matchingAddons(dir) {
|
||||||
|
it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon.
|
||||||
|
}.forEach {
|
||||||
|
println("Deleting old addon: " + it.absolutePath)
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
project(":common:addons").subprojects.forEach { addonProject ->
|
||||||
|
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
||||||
|
|
||||||
|
val target = File(dir, jar.archiveFileName.get())
|
||||||
|
|
||||||
|
val base = "${jar.archiveBaseName.get()}-${project.version}"
|
||||||
|
|
||||||
|
println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base")
|
||||||
|
|
||||||
|
jar.archiveFile.orNull?.asFile?.copyTo(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun matchingAddons(dir: File, matcher: Predicate<File>): Set<File> {
|
||||||
|
val matching = HashSet<File>()
|
||||||
|
dir.walk().maxDepth(1).asStream().filter(matcher).forEach(matching::add)
|
||||||
|
return matching
|
||||||
|
}
|
@ -4,12 +4,20 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
|||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.BasePluginConvention
|
import org.gradle.api.plugins.BasePluginConvention
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.kotlin.dsl.apply
|
import org.gradle.kotlin.dsl.apply
|
||||||
import org.gradle.kotlin.dsl.get
|
import org.gradle.kotlin.dsl.get
|
||||||
import org.gradle.kotlin.dsl.getPlugin
|
import org.gradle.kotlin.dsl.getPlugin
|
||||||
import org.gradle.kotlin.dsl.named
|
import org.gradle.kotlin.dsl.named
|
||||||
|
import org.yaml.snakeyaml.DumperOptions
|
||||||
|
import org.yaml.snakeyaml.Yaml
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.FileWriter
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
fun Project.configureDistribution() {
|
fun Project.configureDistribution() {
|
||||||
apply(plugin = "java-library")
|
apply(plugin = "java-library")
|
||||||
@ -26,7 +34,85 @@ fun Project.configureDistribution() {
|
|||||||
downloadPack(netherPackUrl, project)
|
downloadPack(netherPackUrl, project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tasks["processResources"].dependsOn(downloadDefaultPacks)
|
|
||||||
|
val installAddons = tasks.create("installAddons") {
|
||||||
|
group = "terra"
|
||||||
|
project(":common:addons").subprojects.forEach {
|
||||||
|
it.afterEvaluate {
|
||||||
|
dependsOn(it.tasks.getByName("build")) // Depend on addon JARs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
// The addons are copied into a JAR because of a ShadowJar bug
|
||||||
|
// which expands *all* JARs, even resource ones, into the fat JAR.
|
||||||
|
// To get around this, we copy all addon JARs into a *new* JAR,
|
||||||
|
// then, ShadowJar expands the newly created JAR, putting the original
|
||||||
|
// JARs where they should go.
|
||||||
|
//
|
||||||
|
// https://github.com/johnrengelman/shadow/issues/111
|
||||||
|
val dest = File(buildDir, "/resources/main/addons.jar")
|
||||||
|
dest.parentFile.mkdirs()
|
||||||
|
|
||||||
|
val zip = ZipOutputStream(FileOutputStream(dest))
|
||||||
|
|
||||||
|
project(":common:addons").subprojects.forEach { addonProject ->
|
||||||
|
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
||||||
|
println("Packaging addon ${jar.archiveFileName.get()} to ${dest.absolutePath}.")
|
||||||
|
|
||||||
|
val entry = ZipEntry("addons/${jar.archiveFileName.get()}")
|
||||||
|
zip.putNextEntry(entry)
|
||||||
|
FileInputStream(jar.archiveFile.get().asFile).copyTo(zip)
|
||||||
|
zip.closeEntry()
|
||||||
|
}
|
||||||
|
zip.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val generateResourceManifest = tasks.create("generateResourceManifest") {
|
||||||
|
group = "terra"
|
||||||
|
dependsOn(downloadDefaultPacks)
|
||||||
|
dependsOn(installAddons)
|
||||||
|
doFirst {
|
||||||
|
val resources = HashMap<String, MutableList<String>>()
|
||||||
|
val packsDir = File("${project.buildDir}/resources/main/packs/")
|
||||||
|
|
||||||
|
packsDir.walkTopDown().forEach {
|
||||||
|
if (it.isDirectory || !it.name.endsWith(".zip")) return@forEach
|
||||||
|
resources.computeIfAbsent("packs") { ArrayList() }.add(it.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
val langDir = File("${project(":common:implementation").buildDir}/resources/main/lang/")
|
||||||
|
|
||||||
|
langDir.walkTopDown().forEach {
|
||||||
|
if (it.isDirectory || !it.name.endsWith(".yml")) return@forEach
|
||||||
|
resources.computeIfAbsent("lang") { ArrayList() }.add(it.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
project(":common:addons").subprojects.forEach { addonProject ->
|
||||||
|
val jar = (addonProject.tasks.named("jar").get() as Jar).archiveFileName.get()
|
||||||
|
resources.computeIfAbsent("addons") { ArrayList() }.add(jar)
|
||||||
|
}
|
||||||
|
|
||||||
|
val options = DumperOptions()
|
||||||
|
options.indent = 2
|
||||||
|
options.indentWithIndicator = true
|
||||||
|
options.indicatorIndent = 2
|
||||||
|
options.isPrettyFlow = true
|
||||||
|
options.defaultFlowStyle = DumperOptions.FlowStyle.BLOCK
|
||||||
|
options.defaultScalarStyle = DumperOptions.ScalarStyle.DOUBLE_QUOTED
|
||||||
|
|
||||||
|
val yaml = Yaml(options)
|
||||||
|
|
||||||
|
val manifest = File("${project.buildDir}/resources/main/resources.yml")
|
||||||
|
|
||||||
|
if (manifest.exists()) manifest.delete()
|
||||||
|
manifest.createNewFile()
|
||||||
|
yaml.dump(resources, FileWriter(manifest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks["processResources"].dependsOn(generateResourceManifest)
|
||||||
|
|
||||||
tasks.named<ShadowJar>("shadowJar") {
|
tasks.named<ShadowJar>("shadowJar") {
|
||||||
// Tell shadow to download the packs
|
// Tell shadow to download the packs
|
||||||
@ -45,7 +131,6 @@ fun Project.configureDistribution() {
|
|||||||
relocate("org.javax.annotation", "com.dfsek.terra.lib.javax.annotation")
|
relocate("org.javax.annotation", "com.dfsek.terra.lib.javax.annotation")
|
||||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||||
minimize()
|
|
||||||
}
|
}
|
||||||
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
|
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
|
||||||
|
|
||||||
|
3
common/addons/README.md
Normal file
3
common/addons/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Core Addons
|
||||||
|
|
||||||
|
This directory contains the modularized "core addons" that implement Terra's default behavior.
|
6
common/addons/biome-provider-image/README.md
Normal file
6
common/addons/biome-provider-image/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# biome-provider-image
|
||||||
|
|
||||||
|
Implements and registers the `IMAGE` biome provider, a biome provider which generates
|
||||||
|
biomes from an image, using the `color` attribute of biomes.
|
||||||
|
|
||||||
|
This addon registers the provider type, and all associated config options.
|
45
common/addons/biome-provider-image/build.gradle.kts
Normal file
45
common/addons/biome-provider-image/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.dfsek.terra.api.world.biome.provider;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeProviderBuilder;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
@ -10,7 +11,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ImageBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder { // This provider does not need a seed, so it is its own builder.
|
public class ImageBiomeProvider implements BiomeProvider, BiomeProviderBuilder { // This provider does not need a seed, so it is its own builder.
|
||||||
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
||||||
private final BufferedImage image;
|
private final BufferedImage image;
|
||||||
private final int resolution;
|
private final int resolution;
|
@ -1,15 +1,14 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.provider;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.registry.Registry;
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.biome.provider.ImageBiomeProvider;
|
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ImageProviderTemplate extends BiomeProviderTemplate {
|
public class ImageProviderTemplate /*extends BiomeProviderTemplate */ {
|
||||||
private final Registry<BiomeBuilder> biomes;
|
private final Registry<BiomeBuilder> biomes;
|
||||||
@Value("image.name")
|
@Value("image.name")
|
||||||
private BufferedImage image;
|
private BufferedImage image;
|
||||||
@ -17,11 +16,13 @@ public class ImageProviderTemplate extends BiomeProviderTemplate {
|
|||||||
@Value("image.align")
|
@Value("image.align")
|
||||||
private ImageBiomeProvider.Align align;
|
private ImageBiomeProvider.Align align;
|
||||||
|
|
||||||
|
private int resolution;
|
||||||
|
|
||||||
public ImageProviderTemplate(Registry<BiomeBuilder> set) {
|
public ImageProviderTemplate(Registry<BiomeBuilder> set) {
|
||||||
this.biomes = set;
|
this.biomes = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//@Override
|
||||||
public BiomeProvider build(long seed) {
|
public BiomeProvider build(long seed) {
|
||||||
return new ImageBiomeProvider(biomes.entries().stream().map(biomeBuilder -> biomeBuilder.apply(seed)).collect(Collectors.toSet()), image, resolution, align);
|
return new ImageBiomeProvider(biomes.entries().stream().map(biomeBuilder -> biomeBuilder.apply(seed)).collect(Collectors.toSet()), image, resolution, align);
|
||||||
}
|
}
|
7
common/addons/biome-provider-pipeline/README.md
Normal file
7
common/addons/biome-provider-pipeline/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# biome-provider-pipeline
|
||||||
|
|
||||||
|
Implements the Biome Pipeline, a procedural biome provider that uses a series
|
||||||
|
of "stages" to apply "mutations" to a 2D grid of biomes.
|
||||||
|
|
||||||
|
|
||||||
|
This addon registers the `PIPELINE` biome provider type, and all associated configurations.
|
45
common/addons/biome-provider-pipeline/build.gradle.kts
Normal file
45
common/addons/biome-provider-pipeline/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.vector.Vector2;
|
import com.dfsek.terra.api.vector.Vector2;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeExpander;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeHolder;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||||
|
|
||||||
public class BiomeHolderImpl implements BiomeHolder {
|
public class BiomeHolderImpl implements BiomeHolder {
|
||||||
private final Vector2 origin;
|
private final Vector2 origin;
|
||||||
private final int width;
|
private final int width;
|
||||||
private TerraBiome[][] biomes;
|
|
||||||
private final int offset;
|
private final int offset;
|
||||||
|
private TerraBiome[][] biomes;
|
||||||
|
|
||||||
public BiomeHolderImpl(int width, Vector2 origin) {
|
public BiomeHolderImpl(int width, Vector2 origin) {
|
||||||
width += 4;
|
width += 4;
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.BiomePipelineTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.BiomeProviderBuilderLoader;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.NoiseSourceTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.SourceBuilderLoader;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageBuilderLoader;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.expander.ExpanderStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.stages.ExpanderStage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
||||||
|
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.pack.ConfigPackPreLoadEvent;
|
||||||
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeProviderBuilder;
|
||||||
|
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
@Addon("biome-provider-pipeline")
|
||||||
|
@Author("Terra")
|
||||||
|
@Version("1.0.0")
|
||||||
|
public class BiomePipelineAddon extends TerraAddon implements EventListener {
|
||||||
|
@Inject
|
||||||
|
private TerraPlugin main;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
main.getEventManager().registerListener(this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPackLoad(ConfigPackPreLoadEvent event) {
|
||||||
|
event.getPack().applyLoader(SourceSeeded.class, new SourceBuilderLoader())
|
||||||
|
.applyLoader(StageSeeded.class, new StageBuilderLoader())
|
||||||
|
.applyLoader(ExpanderStage.Type.class, (c, o, l) -> ExpanderStage.Type.valueOf((String) o))
|
||||||
|
.applyLoader(MutatorStage.Type.class, (c, o, l) -> MutatorStage.Type.valueOf((String) o))
|
||||||
|
.applyLoader(NoiseSourceTemplate.class, NoiseSourceTemplate::new)
|
||||||
|
.applyLoader(ReplaceMutatorTemplate.class, ReplaceMutatorTemplate::new)
|
||||||
|
.applyLoader(BorderMutatorTemplate.class, BorderMutatorTemplate::new)
|
||||||
|
.applyLoader(BorderListMutatorTemplate.class, BorderListMutatorTemplate::new)
|
||||||
|
.applyLoader(ReplaceListMutatorTemplate.class, ReplaceListMutatorTemplate::new)
|
||||||
|
.applyLoader(SmoothMutatorTemplate.class, SmoothMutatorTemplate::new)
|
||||||
|
.applyLoader(ExpanderStageTemplate.class, ExpanderStageTemplate::new)
|
||||||
|
.applyLoader((Type) BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(main))
|
||||||
|
.applyLoader(BiomeProviderBuilder.class, new BiomeProviderBuilderLoader());
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,11 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.GlueList;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeHolder;
|
import com.dfsek.terra.api.vector.Vector2;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.Stage;
|
|
||||||
import com.dfsek.terra.vector.Vector2Impl;
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ public class BiomePipelineImpl {
|
|||||||
* @return BiomeHolder containing biomes.
|
* @return BiomeHolder containing biomes.
|
||||||
*/
|
*/
|
||||||
public BiomeHolder getBiomes(int x, int z) {
|
public BiomeHolder getBiomes(int x, int z) {
|
||||||
BiomeHolder holder = new BiomeHolderImpl(init, new Vector2Impl(x * (init - 1), z * (init - 1)));
|
BiomeHolder holder = new BiomeHolderImpl(init, new Vector2(x * (init - 1), z * (init - 1)));
|
||||||
holder.fill(source);
|
holder.fill(source);
|
||||||
for(Stage stage : stages) holder = stage.apply(holder);
|
for(Stage stage : stages) holder = stage.apply(holder);
|
||||||
return holder;
|
return holder;
|
||||||
@ -43,7 +42,7 @@ public class BiomePipelineImpl {
|
|||||||
|
|
||||||
public static final class BiomePipelineBuilder {
|
public static final class BiomePipelineBuilder {
|
||||||
private final int init;
|
private final int init;
|
||||||
List<StageSeeded> stages = new GlueList<>();
|
List<StageSeeded> stages = new ArrayList<>();
|
||||||
private int expand;
|
private int expand;
|
||||||
|
|
||||||
public BiomePipelineBuilder(int init) {
|
public BiomePipelineBuilder(int init) {
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface StageSeeded extends SeededBuilder<Stage> {
|
||||||
|
}
|
@ -1,13 +1,11 @@
|
|||||||
package com.dfsek.terra.api.world.biome.provider;
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.vector.Vector2;
|
import com.dfsek.terra.api.vector.Vector2;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeHolder;
|
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.BiomePipelineImpl;
|
|
||||||
import com.dfsek.terra.vector.Vector2Impl;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
@ -52,6 +50,6 @@ public class StandardBiomeProvider implements BiomeProvider {
|
|||||||
|
|
||||||
int fdX = FastMath.floorDiv(x, pipeline.getSize());
|
int fdX = FastMath.floorDiv(x, pipeline.getSize());
|
||||||
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
||||||
return holderCache.getUnchecked(new Vector2Impl(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
|
return holderCache.getUnchecked(new Vector2(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.world.biome.generation.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
package com.dfsek.terra.api.world.biome.generation.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||||
|
|
||||||
public interface BiomeHolder {
|
public interface BiomeHolder {
|
||||||
BiomeHolder expand(BiomeExpander expander);
|
BiomeHolder expand(BiomeExpander expander);
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.world.biome.generation.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.world.biome.generation.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||||
|
|
||||||
public interface Stage {
|
public interface Stage {
|
||||||
boolean isExpansion();
|
boolean isExpansion();
|
@ -1,13 +1,13 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.provider;
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineImpl;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.StageSeeded;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.StandardBiomeProvider;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.BiomePipelineImpl;
|
|
||||||
import com.dfsek.terra.api.world.biome.provider.StandardBiomeProvider;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeProviderBuilder;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProviderBuilder> {
|
||||||
|
@Override
|
||||||
|
public BiomeProviderBuilder load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||||
|
return loader.loadType(BiomePipelineTemplate.class, c); // TODO: actually implement this lol
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeProviderBuilder;
|
||||||
|
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||||
|
|
||||||
|
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProviderBuilder>, BiomeProviderBuilder {
|
||||||
|
@Value("resolution")
|
||||||
|
@Default
|
||||||
|
protected int resolution = 1;
|
||||||
|
@Value("blend.noise")
|
||||||
|
@Default
|
||||||
|
protected NoiseSeeded blend = NoiseSeeded.zero(2);
|
||||||
|
@Value("blend.amplitude")
|
||||||
|
@Default
|
||||||
|
protected double blendAmp = 0d;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProviderBuilder get() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.addons.biome.pipeline.source.RandomSource;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.source.RandomSource;
|
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
|
||||||
|
|
||||||
public class NoiseSourceTemplate extends SourceTemplate {
|
public class NoiseSourceTemplate extends SourceTemplate {
|
||||||
@Value("noise")
|
@Value("noise")
|
@ -1,25 +1,25 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome;
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.NoiseSourceTemplate;
|
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class SourceBuilderLoader implements TypeLoader<SourceSeeded> {
|
public class SourceBuilderLoader implements TypeLoader<SourceSeeded> {
|
||||||
@Override
|
@Override
|
||||||
public SourceSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
public SourceSeeded load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||||
Map<String, Object> source = (Map<String, Object>) c;
|
Map<String, Object> source = (Map<String, Object>) c;
|
||||||
|
|
||||||
BiomeSource.Type type = loader.loadClass(BiomeSource.Type.class, source.get("type"));
|
BiomeSource.Type type = loader.loadType(BiomeSource.Type.class, source.get("type"));
|
||||||
|
|
||||||
if(type == BiomeSource.Type.NOISE) {
|
if(type == BiomeSource.Type.NOISE) {
|
||||||
return loader.loadClass(NoiseSourceTemplate.class, source);
|
return loader.loadType(NoiseSourceTemplate.class, source);
|
||||||
}
|
}
|
||||||
throw new LoadException("No such loader type: " + type);
|
throw new LoadException("No such loader type: " + type);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.config.stage;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.StageSeeded;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.expander.ExpanderStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.stages.ExpanderStage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public class StageBuilderLoader implements TypeLoader<StageSeeded> {
|
||||||
|
@Override
|
||||||
|
public StageSeeded load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||||
|
Map<String, Object> raw = (Map<String, Object>) c;
|
||||||
|
|
||||||
|
if(raw.size() != 1) throw new LoadException("Illegal stage map size: " + raw.size());
|
||||||
|
|
||||||
|
Map.Entry<String, Object> entry = null;
|
||||||
|
|
||||||
|
for(Map.Entry<String, Object> e : raw.entrySet()) {
|
||||||
|
entry = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> mutator = (Map<String, Object>) entry.getValue();
|
||||||
|
|
||||||
|
if(entry.getKey().equals("expand")) {
|
||||||
|
ExpanderStage.Type stageType = loader.loadType(ExpanderStage.Type.class, mutator.get("type"));
|
||||||
|
if(stageType.equals(ExpanderStage.Type.FRACTAL)) {
|
||||||
|
return loader.loadType(ExpanderStageTemplate.class, mutator);
|
||||||
|
} else throw new LoadException("No such expander \"" + stageType + "\"");
|
||||||
|
} else if(entry.getKey().equals("mutate")) {
|
||||||
|
switch(loader.loadType(MutatorStage.Type.class, mutator.get("type"))) {
|
||||||
|
case SMOOTH:
|
||||||
|
return loader.loadType(SmoothMutatorTemplate.class, mutator);
|
||||||
|
case REPLACE:
|
||||||
|
return loader.loadType(ReplaceMutatorTemplate.class, mutator);
|
||||||
|
case REPLACE_LIST:
|
||||||
|
return loader.loadType(ReplaceListMutatorTemplate.class, mutator);
|
||||||
|
case BORDER:
|
||||||
|
return loader.loadType(BorderMutatorTemplate.class, mutator);
|
||||||
|
case BORDER_LIST:
|
||||||
|
return loader.loadType(BorderListMutatorTemplate.class, mutator);
|
||||||
|
default:
|
||||||
|
throw new LoadException("No such mutator type \"" + mutator.get("type"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new LoadException("No such mutator \"" + entry.getKey() + "\"");
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.StageSeeded;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.Stage;
|
|
||||||
|
|
||||||
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, StageSeeded {
|
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, StageSeeded {
|
||||||
@Value("noise")
|
@Value("noise")
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.expander;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.expand.FractalExpander;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.stages.ExpanderStage;
|
||||||
|
|
||||||
|
public class ExpanderStageTemplate extends StageTemplate {
|
||||||
|
@Override
|
||||||
|
public Stage apply(Long seed) {
|
||||||
|
return new ExpanderStage(new FractalExpander(noise.apply(seed)));
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderListMutator;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BorderListMutator;
|
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,10 +1,10 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderMutator;
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BorderMutator;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BorderMutatorTemplate extends MutatorStageTemplate {
|
public class BorderMutatorTemplate extends MutatorStageTemplate {
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
||||||
|
|
||||||
|
public abstract class MutatorStageTemplate extends StageTemplate {
|
||||||
|
public abstract BiomeMutator build(long seed);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stage apply(Long seed) {
|
||||||
|
return new MutatorStage(build(seed));
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceListMutator;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.ReplaceListMutator;
|
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,10 +1,10 @@
|
|||||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceMutator;
|
||||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.ReplaceMutator;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ReplaceMutatorTemplate extends MutatorStageTemplate {
|
public class ReplaceMutatorTemplate extends MutatorStageTemplate {
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.mutator.SmoothMutator;
|
||||||
|
|
||||||
|
public class SmoothMutatorTemplate extends MutatorStageTemplate {
|
||||||
|
@Override
|
||||||
|
public BiomeMutator build(long seed) {
|
||||||
|
return new SmoothMutator(noise.apply(seed));
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.expand;
|
package com.dfsek.terra.addons.biome.pipeline.expand;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeExpander;
|
|
||||||
|
|
||||||
public class FractalExpander implements BiomeExpander {
|
public class FractalExpander implements BiomeExpander {
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
|
|
||||||
public class BorderMutator implements BiomeMutator {
|
public class BorderMutator implements BiomeMutator {
|
||||||
private final String border;
|
private final String border;
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
|
|
||||||
public class ReplaceMutator implements BiomeMutator {
|
public class ReplaceMutator implements BiomeMutator {
|
||||||
private final String replaceableTag;
|
private final String replaceableTag;
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.source;
|
package com.dfsek.terra.addons.biome.pipeline.source;
|
||||||
|
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.stages;
|
package com.dfsek.terra.addons.biome.pipeline.stages;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeExpander;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeHolder;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
|
||||||
public class ExpanderStage implements Stage {
|
public class ExpanderStage implements Stage {
|
||||||
private final BiomeExpander expander;
|
private final BiomeExpander expander;
|
@ -1,8 +1,8 @@
|
|||||||
package com.dfsek.terra.api.world.biome.pipeline.stages;
|
package com.dfsek.terra.addons.biome.pipeline.stages;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeHolder;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.world.biome.generation.pipeline.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
|
||||||
public class MutatorStage implements Stage {
|
public class MutatorStage implements Stage {
|
||||||
private final BiomeMutator mutator;
|
private final BiomeMutator mutator;
|
4
common/addons/biome-provider-single/README.md
Normal file
4
common/addons/biome-provider-single/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# biome-provider-single
|
||||||
|
|
||||||
|
Registers and configures the `SINGLE` biome provider, a biome provider which
|
||||||
|
accepts a single biome to generate continuously.
|
45
common/addons/biome-provider-single/build.gradle.kts
Normal file
45
common/addons/biome-provider-single/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
package com.dfsek.terra.api.world.biome.provider;
|
package com.dfsek.terra.addons.biome.single;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeProviderBuilder;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
public class SingleBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder {
|
public class SingleBiomeProvider implements BiomeProvider, BiomeProviderBuilder {
|
||||||
private final TerraBiome biome;
|
private final TerraBiome biome;
|
||||||
|
|
||||||
public SingleBiomeProvider(TerraBiome biome) {
|
public SingleBiomeProvider(TerraBiome biome) {
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.single;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeProviderBuilder;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
public class SingleBiomeProviderTemplate implements ObjectTemplate<BiomeProviderBuilder>, BiomeProviderBuilder {
|
||||||
|
@Value("biome")
|
||||||
|
private BiomeBuilder biome;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider build(long seed) {
|
||||||
|
return new SingleBiomeProvider(biome.apply(seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProviderBuilder get() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
4
common/addons/chunk-generator-noise-3d/README.md
Normal file
4
common/addons/chunk-generator-noise-3d/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# chunk-generator-noise-3d
|
||||||
|
|
||||||
|
Registers the `NOISE_3D` chunk generator, a chunk generator which uses biomes'
|
||||||
|
samplers in 3D to generate chunk data.
|
45
common/addons/chunk-generator-noise-3d/build.gradle.kts
Normal file
45
common/addons/chunk-generator-noise-3d/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
|
||||||
|
@Value("palette")
|
||||||
|
private PaletteHolder palette;
|
||||||
|
|
||||||
|
@Value("slant")
|
||||||
|
@Default
|
||||||
|
private SlantHolder slant = null;
|
||||||
|
|
||||||
|
@Value("ocean.level")
|
||||||
|
private int seaLevel;
|
||||||
|
|
||||||
|
@Value("ocean.palette")
|
||||||
|
private Palette oceanPalette;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaletteInfo get() {
|
||||||
|
return new PaletteInfo(palette, slant, oceanPalette, seaLevel);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.generation.generators.NoiseChunkGenerator3D;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolderLoader;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolderLoader;
|
||||||
|
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.ConfigurationLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.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.generator.ChunkGeneratorProvider;
|
||||||
|
|
||||||
|
@Addon("chunk-generator-noise-3d")
|
||||||
|
@Author("Terra")
|
||||||
|
@Version("1.0.0")
|
||||||
|
public class NoiseChunkGenerator3DAddon extends TerraAddon implements EventListener {
|
||||||
|
@Inject
|
||||||
|
private TerraPlugin main;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
main.getEventManager().registerListener(this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPackLoad(ConfigPackPreLoadEvent event) throws DuplicateEntryException {
|
||||||
|
event.getPack().getOrCreateRegistry(ChunkGeneratorProvider.class).register("NOISE_3D", pack -> new NoiseChunkGenerator3D(pack, main));
|
||||||
|
event.getPack().applyLoader(SlantHolder.class, new SlantHolderLoader())
|
||||||
|
.applyLoader(PaletteHolder.class, new PaletteHolderLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBiomeLoad(ConfigurationLoadEvent event) {
|
||||||
|
if(event.is(BiomeBuilder.class)) {
|
||||||
|
event.getLoadedObject(BiomeBuilder.class).getContext().put(event.load(new BiomePaletteTemplate()).get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
import com.dfsek.terra.api.world.generator.Sampler;
|
||||||
|
|
||||||
|
public final class PaletteUtil {
|
||||||
|
public static Palette getPalette(int x, int y, int z, Generator c, Sampler sampler, PaletteInfo paletteInfo) {
|
||||||
|
SlantHolder slant = paletteInfo.getSlantHolder();
|
||||||
|
if(slant != null) {
|
||||||
|
double slope = MathUtil.derivative(sampler, x, y, z);
|
||||||
|
if(slope > slant.getMinSlope()) {
|
||||||
|
return slant.getPalette(slope).getPalette(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paletteInfo.getPaletteHolder().getPalette(y);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,189 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.generation.generators;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.PaletteUtil;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.block.state.properties.base.Properties;
|
||||||
|
import com.dfsek.terra.api.block.state.properties.enums.Direction;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.BiomeGrid;
|
||||||
|
import com.dfsek.terra.api.world.TerraWorld;
|
||||||
|
import com.dfsek.terra.api.world.World;
|
||||||
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
import com.dfsek.terra.api.world.generator.ChunkData;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
import com.dfsek.terra.api.world.generator.Sampler;
|
||||||
|
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
|
||||||
|
import com.dfsek.terra.api.world.generator.TerraGenerationStage;
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class NoiseChunkGenerator3D implements TerraChunkGenerator {
|
||||||
|
private final ConfigPack configPack;
|
||||||
|
private final TerraPlugin main;
|
||||||
|
private final List<TerraGenerationStage> generationStages = new ArrayList<>();
|
||||||
|
|
||||||
|
private final BlockState air;
|
||||||
|
|
||||||
|
public NoiseChunkGenerator3D(ConfigPack c, TerraPlugin main) {
|
||||||
|
this.configPack = c;
|
||||||
|
this.main = main;
|
||||||
|
this.air = main.getWorldHandle().air();
|
||||||
|
c.getStages().forEach(stage -> generationStages.add(stage.newInstance(c)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"try"})
|
||||||
|
static void biomes(@NotNull World world, int chunkX, int chunkZ, @NotNull BiomeGrid biome, TerraPlugin main) {
|
||||||
|
try(ProfileFrame ignore = main.getProfiler().profile("biomes")) {
|
||||||
|
int xOrig = (chunkX << 4);
|
||||||
|
int zOrig = (chunkZ << 4);
|
||||||
|
BiomeProvider grid = main.getWorld(world).getBiomeProvider();
|
||||||
|
for(int x = 0; x < 4; x++) {
|
||||||
|
for(int z = 0; z < 4; z++) {
|
||||||
|
int cx = xOrig + (x << 2);
|
||||||
|
int cz = zOrig + (z << 2);
|
||||||
|
TerraBiome b = grid.getBiome(cx, cz);
|
||||||
|
|
||||||
|
biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator(world).getBiomeNoise(), cx, 0, cz));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigPack getConfigPack() {
|
||||||
|
return configPack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TerraPlugin getMain() {
|
||||||
|
return main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings({"try"})
|
||||||
|
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
||||||
|
try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_3d")) {
|
||||||
|
TerraWorld tw = main.getWorld(world);
|
||||||
|
BiomeProvider grid = tw.getBiomeProvider();
|
||||||
|
|
||||||
|
int xOrig = (chunkX << 4);
|
||||||
|
int zOrig = (chunkZ << 4);
|
||||||
|
|
||||||
|
Sampler sampler = tw.getConfig().getSamplerCache().getChunk(chunkX, chunkZ);
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int z = 0; z < 16; z++) {
|
||||||
|
int paletteLevel = 0;
|
||||||
|
|
||||||
|
int cx = xOrig + x;
|
||||||
|
int cz = zOrig + z;
|
||||||
|
|
||||||
|
TerraBiome biome = grid.getBiome(cx, cz);
|
||||||
|
|
||||||
|
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
||||||
|
|
||||||
|
if(paletteInfo == null) {
|
||||||
|
main.logger().info("null palette: " + biome.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator generator = biome.getGenerator(world);
|
||||||
|
|
||||||
|
int sea = paletteInfo.getSeaLevel();
|
||||||
|
Palette seaPalette = paletteInfo.getOcean();
|
||||||
|
|
||||||
|
boolean justSet = false;
|
||||||
|
BlockState data = null;
|
||||||
|
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
||||||
|
if(sampler.sample(x, y, z) > 0) {
|
||||||
|
justSet = true;
|
||||||
|
|
||||||
|
data = PaletteUtil.getPalette(x, y, z, generator, sampler, paletteInfo).get(paletteLevel, cx, y, cz);
|
||||||
|
chunk.setBlock(x, y, z, data);
|
||||||
|
|
||||||
|
paletteLevel++;
|
||||||
|
} else if(y <= sea) {
|
||||||
|
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig));
|
||||||
|
|
||||||
|
justSet = false;
|
||||||
|
paletteLevel = 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
justSet = false;
|
||||||
|
paletteLevel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean placeStair(BlockState orig, ChunkData chunk, Vector3 block, double thresh, Sampler sampler, BlockState stairNew) {
|
||||||
|
|
||||||
|
if(sampler.sample(block.getBlockX() - 0.55, block.getY(), block.getZ()) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.WEST);
|
||||||
|
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() - 0.55) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.NORTH);
|
||||||
|
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() + 0.55) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.SOUTH);
|
||||||
|
} else if(sampler.sample(block.getX() + 0.55, block.getY(), block.getZ()) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.EAST);
|
||||||
|
} else stairNew = null;
|
||||||
|
if(stairNew != null) {
|
||||||
|
stairNew.setIfPresent(Properties.WATERLOGGED, orig.getBlockType().isWater());
|
||||||
|
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), stairNew);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateBiomes(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biome) {
|
||||||
|
biomes(world, chunkX, chunkZ, biome, main);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth) {
|
||||||
|
return new Sampler3D(chunkX, chunkZ, provider, world, elevationSmooth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TerraGenerationStage> getGenerationStages() {
|
||||||
|
return generationStages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(World world, int x, int y, int z) {
|
||||||
|
TerraWorld terraWorld = main.getWorld(world);
|
||||||
|
BiomeProvider provider = terraWorld.getBiomeProvider();
|
||||||
|
TerraBiome biome = provider.getBiome(x, z);
|
||||||
|
Sampler sampler = terraWorld.getConfig().getSamplerCache().get(x, z);
|
||||||
|
|
||||||
|
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
||||||
|
Palette palette = PaletteUtil.getPalette(x, y, z, biome.getGenerator(world), sampler, paletteInfo);
|
||||||
|
int fdX = FastMath.floorMod(x, 16);
|
||||||
|
int fdZ = FastMath.floorMod(z, 16);
|
||||||
|
double noise = sampler.sample(fdX, y, fdZ);
|
||||||
|
if(noise > 0) {
|
||||||
|
int level = 0;
|
||||||
|
for(int yi = world.getMaxHeight() - 1; yi > y; yi--) {
|
||||||
|
if(sampler.sample(fdX, yi, fdZ) > 0) level++;
|
||||||
|
else level = 0;
|
||||||
|
}
|
||||||
|
return palette.get(level, x, y, z);
|
||||||
|
} else if(y <= paletteInfo.getSeaLevel()) {
|
||||||
|
return paletteInfo.getOcean().get(paletteInfo.getSeaLevel() - y, x, y, z);
|
||||||
|
} else return air;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.world.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.Generator;
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
import com.dfsek.terra.api.world.generator.ChunkInterpolator;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -68,7 +68,7 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double computeNoise(Generator generator, double x, double y, double z) {
|
public double computeNoise(Generator generator, double x, double y, double z) {
|
||||||
return noiseGetter.apply(generator, new Vector3Impl(x, y, z));
|
return noiseGetter.apply(generator, new Vector3(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.world.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.Generator;
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
import com.dfsek.terra.api.world.generator.ChunkInterpolator;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -82,14 +82,14 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double computeNoise(Generator generator, double x, double y, double z) {
|
|
||||||
return noiseGetter.apply(generator, new Vector3Impl(x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int reRange(int value, int high) {
|
private static int reRange(int value, int high) {
|
||||||
return FastMath.max(FastMath.min(value, high), 0);
|
return FastMath.max(FastMath.min(value, high), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double computeNoise(Generator generator, double x, double y, double z) {
|
||||||
|
return noiseGetter.apply(generator, new Vector3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the noise at a pair of internal chunk coordinates.
|
* Gets the noise at a pair of internal chunk coordinates.
|
||||||
*
|
*
|
@ -1,9 +1,8 @@
|
|||||||
package com.dfsek.terra.world.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.Generator;
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.world.generation.WorldGenerator;
|
|
||||||
|
|
||||||
public class ElevationInterpolator {
|
public class ElevationInterpolator {
|
||||||
private final double[][] values = new double[18][18];
|
private final double[][] values = new double[18][18];
|
||||||
@ -12,12 +11,12 @@ public class ElevationInterpolator {
|
|||||||
int xOrigin = chunkX << 4;
|
int xOrigin = chunkX << 4;
|
||||||
int zOrigin = chunkZ << 4;
|
int zOrigin = chunkZ << 4;
|
||||||
|
|
||||||
WorldGenerator[][] gens = new WorldGenerator[18 + 2 * smooth][18 + 2 * smooth];
|
Generator[][] gens = new Generator[18 + 2 * smooth][18 + 2 * smooth];
|
||||||
|
|
||||||
// Precompute generators.
|
// Precompute generators.
|
||||||
for(int x = -1 - smooth; x <= 16 + smooth; x++) {
|
for(int x = -1 - smooth; x <= 16 + smooth; x++) {
|
||||||
for(int z = -1 - smooth; z <= 16 + smooth; z++) {
|
for(int z = -1 - smooth; z <= 16 + smooth; z++) {
|
||||||
gens[x + 1 + smooth][z + 1 + smooth] = (WorldGenerator) provider.getBiome(xOrigin + x, zOrigin + z).getGenerator(world);
|
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z).getGenerator(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.world.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for bilinear interpolation of values arranged on a unit square.
|
* Class for bilinear interpolation of values arranged on a unit square.
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.world.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for bilinear interpolation of values arranged on a unit square.
|
* Class for bilinear interpolation of values arranged on a unit square.
|
@ -1,10 +1,10 @@
|
|||||||
package com.dfsek.terra.world.generation.math.samplers;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator3D;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ElevationInterpolator;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generator.Sampler;
|
import com.dfsek.terra.api.world.generator.Sampler;
|
||||||
import com.dfsek.terra.world.generation.math.interpolation.ChunkInterpolator3D;
|
|
||||||
import com.dfsek.terra.world.generation.math.interpolation.ElevationInterpolator;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
public class Sampler3D implements Sampler {
|
public class Sampler3D implements Sampler {
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
public class PaletteHolder {
|
||||||
|
private final Palette[] palettes;
|
||||||
|
private final int offset;
|
||||||
|
|
||||||
|
protected PaletteHolder(Palette[] palettes, int offset) {
|
||||||
|
this.palettes = palettes;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Palette getPalette(int y) {
|
||||||
|
int index = y + offset;
|
||||||
|
return index >= 0
|
||||||
|
? index < palettes.length
|
||||||
|
? palettes[index]
|
||||||
|
: palettes[palettes.length - 1]
|
||||||
|
: palettes[0];
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.world.palette.holder;
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
@ -14,7 +14,6 @@ public class PaletteHolderBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
|
||||||
public PaletteHolder build() {
|
public PaletteHolder build() {
|
||||||
|
|
||||||
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public PaletteHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||||
|
List<Map<String, Integer>> palette = (List<Map<String, Integer>>) o;
|
||||||
|
PaletteHolderBuilder builder = new PaletteHolderBuilder();
|
||||||
|
for(Map<String, Integer> layer : palette) {
|
||||||
|
for(Map.Entry<String, Integer> entry : layer.entrySet()) {
|
||||||
|
builder.add(entry.getValue(), configLoader.loadType(Palette.class, entry.getKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.properties.Properties;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
public class PaletteInfo implements Properties {
|
||||||
|
private final PaletteHolder paletteHolder;
|
||||||
|
private final SlantHolder slantHolder;
|
||||||
|
private final Palette ocean;
|
||||||
|
|
||||||
|
private final int seaLevel;
|
||||||
|
|
||||||
|
public PaletteInfo(PaletteHolder paletteHolder, SlantHolder slantHolder, Palette ocean, int seaLevel) {
|
||||||
|
this.paletteHolder = paletteHolder;
|
||||||
|
this.slantHolder = slantHolder;
|
||||||
|
this.ocean = ocean;
|
||||||
|
this.seaLevel = seaLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Palette getOcean() {
|
||||||
|
return ocean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaletteHolder getPaletteHolder() {
|
||||||
|
return paletteHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlantHolder getSlantHolder() {
|
||||||
|
return slantHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSeaLevel() {
|
||||||
|
return seaLevel;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package com.dfsek.terra.api.world.palette.slant;
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
|
||||||
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
@ -1,12 +1,10 @@
|
|||||||
package com.dfsek.terra.config.loaders.palette.slant;
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
|
||||||
import com.dfsek.terra.api.world.palette.slant.SlantHolder;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.AnnotatedType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -14,7 +12,7 @@ import java.util.TreeMap;
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class SlantHolderLoader implements TypeLoader<SlantHolder> {
|
public class SlantHolderLoader implements TypeLoader<SlantHolder> {
|
||||||
@Override
|
@Override
|
||||||
public SlantHolder load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
public SlantHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||||
List<Map<Object, Object>> layers = (List<Map<Object, Object>>) o;
|
List<Map<Object, Object>> layers = (List<Map<Object, Object>>) o;
|
||||||
TreeMap<Double, PaletteHolder> slantLayers = new TreeMap<>();
|
TreeMap<Double, PaletteHolder> slantLayers = new TreeMap<>();
|
||||||
double minThreshold = Double.MAX_VALUE;
|
double minThreshold = Double.MAX_VALUE;
|
||||||
@ -22,7 +20,7 @@ public class SlantHolderLoader implements TypeLoader<SlantHolder> {
|
|||||||
for(Map<Object, Object> layer : layers) {
|
for(Map<Object, Object> layer : layers) {
|
||||||
double threshold = ((Number) layer.get("threshold")).doubleValue();
|
double threshold = ((Number) layer.get("threshold")).doubleValue();
|
||||||
if(threshold < minThreshold) minThreshold = threshold;
|
if(threshold < minThreshold) minThreshold = threshold;
|
||||||
slantLayers.put(threshold, (PaletteHolder) configLoader.loadType(PaletteHolder.class, layer.get("palette")));
|
slantLayers.put(threshold, configLoader.loadType(PaletteHolder.class, layer.get("palette")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SlantHolder(slantLayers, minThreshold);
|
return new SlantHolder(slantLayers, minThreshold);
|
3
common/addons/config-biome/README.md
Normal file
3
common/addons/config-biome/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# config-biome
|
||||||
|
|
||||||
|
Registers the default configuration for Terra Biomes, `BIOME`.
|
45
common/addons/config-biome/build.gradle.kts
Normal file
45
common/addons/config-biome/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
|
||||||
|
import com.dfsek.terra.addons.biome.holder.PaletteHolderLoader;
|
||||||
|
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.pack.ConfigPackPreLoadEvent;
|
||||||
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
|
|
||||||
|
@Addon("config-biome")
|
||||||
|
@Author("Terra")
|
||||||
|
@Version("1.0.0")
|
||||||
|
public class BiomeConfigAddon extends TerraAddon implements EventListener {
|
||||||
|
@Inject
|
||||||
|
private TerraPlugin main;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
main.getEventManager().registerListener(this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPackLoad(ConfigPackPreLoadEvent event) {
|
||||||
|
event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), "BIOME", 5);
|
||||||
|
event.getPack().applyLoader(PaletteHolder.class, new PaletteHolderLoader());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.config.ConfigType;
|
||||||
|
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class BiomeConfigType implements ConfigType<BiomeTemplate, BiomeBuilder> {
|
||||||
|
private final ConfigPack pack;
|
||||||
|
private final BiomeFactory factory;
|
||||||
|
|
||||||
|
public BiomeConfigType(ConfigPack pack) {
|
||||||
|
this.pack = pack;
|
||||||
|
this.factory = new BiomeFactory(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeTemplate getTemplate(ConfigPack pack, TerraPlugin main) {
|
||||||
|
return new BiomeTemplate(pack, main);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigFactory<BiomeTemplate, BiomeBuilder> getFactory() {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<BiomeBuilder> getTypeClass() {
|
||||||
|
return BiomeBuilder.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<OpenRegistry<BiomeBuilder>> registrySupplier() {
|
||||||
|
return () -> pack.getRegistryFactory().create(registry -> (TypeLoader<BiomeBuilder>) (t, c, loader) -> {
|
||||||
|
if(c.equals("SELF")) return null;
|
||||||
|
BiomeBuilder obj = registry.get((String) c);
|
||||||
|
if(obj == null)
|
||||||
|
throw new LoadException("No such " + t.getType().getTypeName() + " matching \"" + c + "\" was found in this registry.");
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
|
|
||||||
|
public class BiomeFactory implements ConfigFactory<BiomeTemplate, BiomeBuilder> {
|
||||||
|
private final ConfigPack pack;
|
||||||
|
|
||||||
|
public BiomeFactory(ConfigPack pack) {
|
||||||
|
this.pack = pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBuilder build(BiomeTemplate template, TerraPlugin main) {
|
||||||
|
return new UserDefinedBiomeBuilder(template);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,242 @@
|
|||||||
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.paralithic.eval.parser.Parser;
|
||||||
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.annotations.Final;
|
||||||
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||||
|
import com.dfsek.tectonic.exception.ValidationException;
|
||||||
|
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
|
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||||
|
public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTemplate {
|
||||||
|
private final ConfigPack pack;
|
||||||
|
|
||||||
|
@Value("id")
|
||||||
|
@Final
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Value("extends")
|
||||||
|
@Final
|
||||||
|
@Default
|
||||||
|
private List<String> extended = Collections.emptyList();
|
||||||
|
|
||||||
|
@Value("variables")
|
||||||
|
@Default
|
||||||
|
private Map<String, Double> variables = new HashMap<>();
|
||||||
|
|
||||||
|
@Value("beta.carving.equation")
|
||||||
|
@Default
|
||||||
|
private NoiseSeeded carvingEquation = NoiseSeeded.zero(3);
|
||||||
|
|
||||||
|
@Value("vanilla")
|
||||||
|
private ProbabilityCollection<Biome> vanilla;
|
||||||
|
|
||||||
|
@Value("biome-noise")
|
||||||
|
@Default
|
||||||
|
private NoiseSeeded biomeNoise = NoiseSeeded.zero(2);
|
||||||
|
|
||||||
|
@Value("blend.distance")
|
||||||
|
@Default
|
||||||
|
private int blendDistance = 3;
|
||||||
|
|
||||||
|
@Value("blend.weight")
|
||||||
|
@Default
|
||||||
|
private double blendWeight = 1;
|
||||||
|
|
||||||
|
@Value("blend.step")
|
||||||
|
@Default
|
||||||
|
private int blendStep = 4;
|
||||||
|
|
||||||
|
@Value("noise")
|
||||||
|
private NoiseSeeded noiseEquation;
|
||||||
|
|
||||||
|
@Value("ocean.level")
|
||||||
|
@Default
|
||||||
|
private int seaLevel = 62;
|
||||||
|
|
||||||
|
@Value("elevation.equation")
|
||||||
|
@Default
|
||||||
|
private NoiseSeeded elevationEquation = NoiseSeeded.zero(2);
|
||||||
|
|
||||||
|
@Value("elevation.weight")
|
||||||
|
@Default
|
||||||
|
private double elevationWeight = 1;
|
||||||
|
|
||||||
|
@Value("slabs.enable")
|
||||||
|
@Default
|
||||||
|
private boolean doSlabs = false;
|
||||||
|
|
||||||
|
@Value("slabs.threshold")
|
||||||
|
@Default
|
||||||
|
private double slabThreshold = 0.0075D;
|
||||||
|
|
||||||
|
@Value("slabs.palettes")
|
||||||
|
@Default
|
||||||
|
private Map<BlockType, Palette> slabPalettes;
|
||||||
|
|
||||||
|
@Value("slabs.stair-palettes")
|
||||||
|
@Default
|
||||||
|
private Map<BlockType, Palette> stairPalettes;
|
||||||
|
|
||||||
|
@Value("interpolate-elevation")
|
||||||
|
@Default
|
||||||
|
private boolean interpolateElevation = true;
|
||||||
|
|
||||||
|
@Value("color")
|
||||||
|
@Final
|
||||||
|
@Default
|
||||||
|
private int color = 0;
|
||||||
|
|
||||||
|
@Value("tags")
|
||||||
|
@Default
|
||||||
|
private Set<String> tags = new HashSet<>();
|
||||||
|
|
||||||
|
@Value("colors")
|
||||||
|
@Default
|
||||||
|
private Map<String, Integer> colors = new HashMap<>(); // Plain ol' map, so platforms can decide what to do with colors (if anything).
|
||||||
|
|
||||||
|
public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
|
||||||
|
this.pack = pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getExtended() {
|
||||||
|
return extended;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getColors() {
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBlendWeight() {
|
||||||
|
return blendWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlendDistance() {
|
||||||
|
return blendDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean interpolateElevation() {
|
||||||
|
return interpolateElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSlabThreshold() {
|
||||||
|
return slabThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean doSlabs() {
|
||||||
|
return doSlabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BlockType, Palette> getSlabPalettes() {
|
||||||
|
return slabPalettes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BlockType, Palette> getStairPalettes() {
|
||||||
|
return stairPalettes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSeeded getBiomeNoise() {
|
||||||
|
return biomeNoise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSeeded getElevationEquation() {
|
||||||
|
return elevationEquation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSeeded getCarvingEquation() {
|
||||||
|
return carvingEquation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigPack getPack() {
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSeaLevel() {
|
||||||
|
return seaLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProbabilityCollection<Biome> getVanilla() {
|
||||||
|
return vanilla;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSeeded getNoiseEquation() {
|
||||||
|
return noiseEquation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getElevationWeight() {
|
||||||
|
return elevationWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlendStep() {
|
||||||
|
return blendStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Double> getVariables() {
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate() throws ValidationException {
|
||||||
|
color |= 0xff000000; // Alpha adjustment
|
||||||
|
Parser tester = new Parser();
|
||||||
|
Scope testScope = new Scope();
|
||||||
|
|
||||||
|
variables.forEach(testScope::create);
|
||||||
|
|
||||||
|
testScope.addInvocationVariable("x");
|
||||||
|
testScope.addInvocationVariable("y");
|
||||||
|
testScope.addInvocationVariable("z");
|
||||||
|
|
||||||
|
|
||||||
|
//pack.getTemplate().getNoiseBuilderMap().forEach((id, builder) -> tester.registerFunction(id, new BlankFunction(builder.getDimensions()))); // Register dummy functions
|
||||||
|
|
||||||
|
try {
|
||||||
|
noiseEquation.apply(0L);
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new ValidationException("Invalid noise sampler: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
carvingEquation.apply(0L);
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new ValidationException("Invalid carving sampler: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
elevationEquation.apply(0L);
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new ValidationException("Invalid elevation sampler: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.math.paralithic;
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
|
||||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
|
||||||
|
import com.dfsek.terra.api.world.biome.PaletteSettings;
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
public class PaletteSettingsImpl implements PaletteSettings {
|
||||||
|
private final PaletteHolder palette;
|
||||||
|
|
||||||
|
public PaletteSettingsImpl(PaletteHolder palette) {
|
||||||
|
this.palette = palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Palette getPalette(int y) {
|
||||||
|
return palette.getPalette(y);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
package com.dfsek.terra.api.world.biome;
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.properties.Context;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.world.generation.WorldGenerator;
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -11,21 +13,23 @@ import java.util.Set;
|
|||||||
* Class representing a config-defined biome
|
* Class representing a config-defined biome
|
||||||
*/
|
*/
|
||||||
public class UserDefinedBiome implements TerraBiome {
|
public class UserDefinedBiome implements TerraBiome {
|
||||||
private final WorldGenerator gen;
|
private final UserDefinedGenerator gen;
|
||||||
private final ProbabilityCollection<Biome> vanilla;
|
private final ProbabilityCollection<Biome> vanilla;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final BiomeTemplate config;
|
private final BiomeTemplate config;
|
||||||
private final int color;
|
private final int color;
|
||||||
private final Set<String> tags;
|
private final Set<String> tags;
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, WorldGenerator gen, BiomeTemplate config) {
|
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, UserDefinedGenerator gen, BiomeTemplate config, Context context) {
|
||||||
this.vanilla = vanilla;
|
this.vanilla = vanilla;
|
||||||
this.gen = gen;
|
this.gen = gen;
|
||||||
this.id = config.getID();
|
this.id = config.getID();
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.color = config.getColor();
|
this.color = config.getColor();
|
||||||
this.tags = config.getTags();
|
this.tags = config.getTags();
|
||||||
|
this.context = context;
|
||||||
tags.add("BIOME:" + id);
|
tags.add("BIOME:" + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,4 +71,9 @@ public class UserDefinedBiome implements TerraBiome {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "{BIOME:" + getID() + "}";
|
return "{BIOME:" + getID() + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.properties.Context;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class UserDefinedBiomeBuilder implements BiomeBuilder {
|
||||||
|
private final BiomeTemplate template;
|
||||||
|
private final Context context = new Context();
|
||||||
|
|
||||||
|
private final Map<Long, UserDefinedBiome> biomeMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public UserDefinedBiomeBuilder(BiomeTemplate template) {
|
||||||
|
this.template = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDefinedBiome apply(Long seed) {
|
||||||
|
synchronized(biomeMap) {
|
||||||
|
return biomeMap.computeIfAbsent(seed,
|
||||||
|
s -> {
|
||||||
|
UserDefinedGenerator generator = new UserDefinedGenerator(template.getNoiseEquation().apply(seed), template.getElevationEquation().apply(seed), template.getCarvingEquation().apply(seed), template.getBiomeNoise().apply(seed), template.getElevationWeight(),
|
||||||
|
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
|
||||||
|
return new UserDefinedBiome(template.getVanilla(), generator, template, context);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProbabilityCollection<Biome> getVanillaBiomes() {
|
||||||
|
return template.getVanilla();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,11 @@
|
|||||||
package com.dfsek.terra.world.generation;
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.world.biome.Generator;
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.biome.PaletteSettings;
|
||||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
|
||||||
import com.dfsek.terra.api.world.palette.slant.SlantHolder;
|
|
||||||
|
|
||||||
public class WorldGenerator implements Generator {
|
public class UserDefinedGenerator implements Generator {
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
|
||||||
private final PaletteHolder palettes;
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
|
||||||
private final SlantHolder slantPalettes;
|
|
||||||
|
|
||||||
private final NoiseSampler noise;
|
private final NoiseSampler noise;
|
||||||
private final NoiseSampler elevation;
|
private final NoiseSampler elevation;
|
||||||
@ -22,9 +17,7 @@ public class WorldGenerator implements Generator {
|
|||||||
private final int blendStep;
|
private final int blendStep;
|
||||||
private final double blendWeight;
|
private final double blendWeight;
|
||||||
|
|
||||||
public WorldGenerator(PaletteHolder palettes, SlantHolder slantPalettes, NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
|
public UserDefinedGenerator(NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
|
||||||
this.palettes = palettes;
|
|
||||||
this.slantPalettes = slantPalettes;
|
|
||||||
this.noise = noise;
|
this.noise = noise;
|
||||||
this.elevation = elevation;
|
this.elevation = elevation;
|
||||||
this.carving = carving;
|
this.carving = carving;
|
||||||
@ -61,16 +54,6 @@ public class WorldGenerator implements Generator {
|
|||||||
return blendWeight;
|
return blendWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the BlockPalette to generate the biome with.
|
|
||||||
*
|
|
||||||
* @return BlockPalette - The biome's palette.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Palette getPalette(int y) {
|
|
||||||
return palettes.getPalette(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler getBiomeNoise() {
|
public NoiseSampler getBiomeNoise() {
|
||||||
return biomeNoise;
|
return biomeNoise;
|
@ -1,27 +1,31 @@
|
|||||||
package com.dfsek.terra.api.world.locate;
|
package com.dfsek.terra.addons.biome.command.biome;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public abstract class AsyncFeatureFinder<T> implements Runnable {
|
/**
|
||||||
|
* Runnable that locates a biome asynchronously
|
||||||
|
*/
|
||||||
|
public class AsyncBiomeFinder implements Runnable {
|
||||||
|
|
||||||
protected final BiomeProvider provider;
|
protected final BiomeProvider provider;
|
||||||
protected final T target;
|
protected final TerraBiome target;
|
||||||
protected final int startRadius;
|
protected final int startRadius;
|
||||||
protected final int maxRadius;
|
protected final int maxRadius;
|
||||||
protected final int centerX;
|
protected final int centerX;
|
||||||
protected final int centerZ;
|
protected final int centerZ;
|
||||||
protected final World world;
|
protected final World world;
|
||||||
|
protected final TerraPlugin main;
|
||||||
private final Consumer<Vector3> callback;
|
private final Consumer<Vector3> callback;
|
||||||
protected int searchSize = 1;
|
protected int searchSize = 1;
|
||||||
protected final TerraPlugin main;
|
|
||||||
|
|
||||||
public AsyncFeatureFinder(BiomeProvider provider, T target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
public AsyncBiomeFinder(BiomeProvider provider, TerraBiome target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
@ -33,6 +37,22 @@ public abstract class AsyncFeatureFinder<T> implements Runnable {
|
|||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get biome at location
|
||||||
|
*
|
||||||
|
* @param x X coordinate
|
||||||
|
* @param z Z coordinate
|
||||||
|
* @return TerraBiome at coordinates
|
||||||
|
*/
|
||||||
|
public boolean isValid(int x, int z, TerraBiome target) {
|
||||||
|
int res = main.getTerraConfig().getBiomeSearchResolution();
|
||||||
|
return getProvider().getBiome(x * res, z * res).equals(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 finalizeVector(Vector3 orig) {
|
||||||
|
return orig.multiply(main.getTerraConfig().getBiomeSearchResolution());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int x = centerX;
|
int x = centerX;
|
||||||
@ -66,16 +86,11 @@ public abstract class AsyncFeatureFinder<T> implements Runnable {
|
|||||||
run++;
|
run++;
|
||||||
toggle = !toggle;
|
toggle = !toggle;
|
||||||
}
|
}
|
||||||
Vector3 finalSpawn = found ? finalizeVector(new Vector3Impl(x, 0, z)) : null;
|
Vector3 finalSpawn = found ? finalizeVector(new Vector3(x, 0, z)) : null;
|
||||||
callback.accept(finalSpawn);
|
callback.accept(finalSpawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerraBiome getTarget() {
|
||||||
public abstract Vector3 finalizeVector(Vector3 orig);
|
|
||||||
|
|
||||||
public abstract boolean isValid(int x, int z, T target);
|
|
||||||
|
|
||||||
public T getTarget() {
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.dfsek.terra.commands.biome;
|
package com.dfsek.terra.addons.biome.command.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Command;
|
import com.dfsek.terra.api.command.annotation.Command;
|
||||||
@ -9,9 +10,7 @@ import com.dfsek.terra.api.command.annotation.type.WorldCommand;
|
|||||||
import com.dfsek.terra.api.entity.CommandSender;
|
import com.dfsek.terra.api.entity.CommandSender;
|
||||||
import com.dfsek.terra.api.entity.Player;
|
import com.dfsek.terra.api.entity.Player;
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.config.lang.LangUtil;
|
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
subcommands = {
|
subcommands = {
|
||||||
@ -40,6 +39,6 @@ public class BiomeCommand implements CommandTemplate {
|
|||||||
|
|
||||||
BiomeProvider provider = main.getWorld(player.world()).getBiomeProvider();
|
BiomeProvider provider = main.getWorld(player.world()).getBiomeProvider();
|
||||||
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position());
|
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position());
|
||||||
LangUtil.send("command.biome.in", sender, biome.getID());
|
sender.sendMessage("You are standing in " + biome.getID());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,16 +1,16 @@
|
|||||||
package com.dfsek.terra.commands.biome;
|
package com.dfsek.terra.addons.biome.command.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.BiomeTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.UserDefinedBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.command.biome.arg.BiomeArgumentParser;
|
||||||
|
import com.dfsek.terra.addons.biome.command.biome.tab.BiomeTabCompleter;
|
||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Argument;
|
import com.dfsek.terra.api.command.annotation.Argument;
|
||||||
import com.dfsek.terra.api.command.annotation.Command;
|
import com.dfsek.terra.api.command.annotation.Command;
|
||||||
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
|
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
|
||||||
import com.dfsek.terra.api.entity.CommandSender;
|
import com.dfsek.terra.api.entity.CommandSender;
|
||||||
|
import com.dfsek.terra.api.structure.ConfiguredStructure;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|
||||||
import com.dfsek.terra.commands.biome.arg.BiomeArgumentParser;
|
|
||||||
import com.dfsek.terra.commands.biome.tab.BiomeTabCompleter;
|
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
|
||||||
import com.dfsek.terra.world.population.items.TerraStructure;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -41,17 +41,6 @@ public class BiomeInfoCommand implements CommandTemplate {
|
|||||||
sender.sendMessage("------Parent Biomes-----");
|
sender.sendMessage("------Parent Biomes-----");
|
||||||
bio.getExtended().forEach(id -> sender.sendMessage(" - " + id));
|
bio.getExtended().forEach(id -> sender.sendMessage(" - " + id));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TerraStructure> structureConfigs = bio.getStructures();
|
|
||||||
|
|
||||||
if(structureConfigs.size() == 0) {
|
|
||||||
sender.sendMessage("No Structures");
|
|
||||||
} else {
|
|
||||||
sender.sendMessage("-------Structures-------");
|
|
||||||
for(TerraStructure c : structureConfigs) {
|
|
||||||
sender.sendMessage(" - " + c.getTemplate().getID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.dfsek.terra.commands.biome;
|
package com.dfsek.terra.addons.biome.command.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.command.biome.arg.BiomeArgumentParser;
|
||||||
|
import com.dfsek.terra.addons.biome.command.biome.tab.BiomeTabCompleter;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Argument;
|
import com.dfsek.terra.api.command.annotation.Argument;
|
||||||
@ -13,12 +15,8 @@ import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
|
|||||||
import com.dfsek.terra.api.entity.CommandSender;
|
import com.dfsek.terra.api.entity.CommandSender;
|
||||||
import com.dfsek.terra.api.entity.Player;
|
import com.dfsek.terra.api.entity.Player;
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.locate.AsyncBiomeFinder;
|
|
||||||
import com.dfsek.terra.commands.biome.arg.BiomeArgumentParser;
|
|
||||||
import com.dfsek.terra.commands.biome.tab.BiomeTabCompleter;
|
|
||||||
import com.dfsek.terra.config.lang.LangUtil;
|
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@ -66,11 +64,11 @@ public class BiomeLocateCommand implements CommandTemplate {
|
|||||||
|
|
||||||
new Thread(new AsyncBiomeFinder(main.getWorld(player.world()).getBiomeProvider(), biome, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> {
|
new Thread(new AsyncBiomeFinder(main.getWorld(player.world()).getBiomeProvider(), biome, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> {
|
||||||
if(location != null) {
|
if(location != null) {
|
||||||
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3Impl(0, player.position().getY(), 0)).distance(player.position())));
|
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position())));
|
||||||
if(teleport) {
|
if(teleport) {
|
||||||
main.runPossiblyUnsafeTask(() -> player.position(new Vector3Impl(location.getX(), player.position().getY(), location.getZ())));
|
main.runPossiblyUnsafeTask(() -> player.position(new Vector3(location.getX(), player.position().getY(), location.getZ())));
|
||||||
}
|
}
|
||||||
} else LangUtil.send("command.biome.unable-to-locate", sender);
|
} else sender.sendMessage("Unable to locate biome \"" + biome.getID() + "\"");
|
||||||
}, main), "Biome Location Thread").start();
|
}, main), "Biome Location Thread").start();
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.commands.biome.arg;
|
package com.dfsek.terra.addons.biome.command.biome.arg;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.command.arg.ArgumentParser;
|
import com.dfsek.terra.api.command.arg.ArgumentParser;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.commands.biome.tab;
|
package com.dfsek.terra.addons.biome.command.biome.tab;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.command.tab.TabCompleter;
|
import com.dfsek.terra.api.command.tab.TabCompleter;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.world.palette.holder;
|
package com.dfsek.terra.addons.biome.holder;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.holder;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public class PaletteHolderBuilder {
|
||||||
|
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
||||||
|
|
||||||
|
public PaletteHolderBuilder add(int y, Palette palette) {
|
||||||
|
paletteMap.put(y, palette);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaletteHolder build() {
|
||||||
|
|
||||||
|
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
||||||
|
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
||||||
|
|
||||||
|
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
||||||
|
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
||||||
|
Palette d = null;
|
||||||
|
for(Map.Entry<Integer, Palette> e : paletteMap.entrySet()) {
|
||||||
|
if(e.getKey() >= y) {
|
||||||
|
d = e.getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(d == null) throw new IllegalArgumentException("No palette for Y=" + y);
|
||||||
|
palettes[y - min] = d;
|
||||||
|
}
|
||||||
|
return new PaletteHolder(palettes, -min);
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +1,24 @@
|
|||||||
package com.dfsek.terra.config.loaders.palette;
|
package com.dfsek.terra.addons.biome.holder;
|
||||||
|
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
|
||||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolderBuilder;
|
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public PaletteHolder load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
public PaletteHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||||
List<Map<String, Integer>> palette = (List<Map<String, Integer>>) o;
|
List<Map<String, Integer>> palette = (List<Map<String, Integer>>) o;
|
||||||
PaletteHolderBuilder builder = new PaletteHolderBuilder();
|
PaletteHolderBuilder builder = new PaletteHolderBuilder();
|
||||||
for(Map<String, Integer> layer : palette) {
|
for(Map<String, Integer> layer : palette) {
|
||||||
for(Map.Entry<String, Integer> entry : layer.entrySet()) {
|
for(Map.Entry<String, Integer> entry : layer.entrySet()) {
|
||||||
builder.add(entry.getValue(), (Palette) configLoader.loadType(Palette.class, entry.getKey()));
|
builder.add(entry.getValue(), configLoader.loadType(Palette.class, entry.getKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
3
common/addons/config-carver/README.md
Normal file
3
common/addons/config-carver/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# config-carver
|
||||||
|
|
||||||
|
Registers the default configuration for Terra Carvers, `CARVER`.
|
45
common/addons/config-carver/build.gradle.kts
Normal file
45
common/addons/config-carver/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,19 @@
|
|||||||
package com.dfsek.terra.carving;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.carver.carving.Worm;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.util.FastRandom;
|
|
||||||
import com.dfsek.terra.api.util.GlueList;
|
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
import com.dfsek.terra.api.util.PopulationUtil;
|
import com.dfsek.terra.api.util.PopulationUtil;
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.carving.Worm;
|
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -34,17 +32,20 @@ public class CarverCache {
|
|||||||
int chunkX = (int) (key >> 32);
|
int chunkX = (int) (key >> 32);
|
||||||
int chunkZ = (int) key.longValue();
|
int chunkZ = (int) key.longValue();
|
||||||
BiomeProvider provider = main.getWorld(w).getBiomeProvider();
|
BiomeProvider provider = main.getWorld(w).getBiomeProvider();
|
||||||
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new FastRandom(PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new Random(PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
||||||
long seed = PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
long seed = PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
||||||
Random r = new FastRandom(seed);
|
Random r = new Random(seed);
|
||||||
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3Impl((chunkX << 4) + r.nextInt(16), CarverCache.this.carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16), CarverCache.this.carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
||||||
List<Worm.WormPoint> points = new GlueList<>();
|
List<Worm.WormPoint> points = new ArrayList<>();
|
||||||
for(int i = 0; i < carving.getLength(); i++) {
|
for(int i = 0; i < carving.getLength(); i++) {
|
||||||
carving.step();
|
carving.step();
|
||||||
TerraBiome biome = provider.getBiome(carving.getRunning());
|
TerraBiome biome = provider.getBiome(carving.getRunning());
|
||||||
|
/*
|
||||||
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in
|
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
points.add(carving.getPoint());
|
points.add(carving.getPoint());
|
||||||
}
|
}
|
||||||
return points;
|
return points;
|
@ -1,20 +1,20 @@
|
|||||||
package com.dfsek.terra.config.factories;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
|
||||||
import com.dfsek.terra.config.pack.ConfigPackImpl;
|
|
||||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CarverFactory implements ConfigFactory<CarverTemplate, UserDefinedCarver> {
|
public class CarverFactory implements ConfigFactory<CarverTemplate, UserDefinedCarver> {
|
||||||
private final ConfigPackImpl pack;
|
private final ConfigPack pack;
|
||||||
|
|
||||||
public CarverFactory(ConfigPackImpl pack) {
|
public CarverFactory(ConfigPack pack) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public class CarverFactory implements ConfigFactory<CarverTemplate, UserDefinedC
|
|||||||
long hash = MathUtil.hashToLong(config.getID());
|
long hash = MathUtil.hashToLong(config.getID());
|
||||||
UserDefinedCarver carver;
|
UserDefinedCarver carver;
|
||||||
try {
|
try {
|
||||||
carver = new UserDefinedCarver(config.getHeight(), config.getLength(), start, mutate, radius, pack.getVarScope(), hash, config.getCutTop(), config.getCutBottom(), config, main, pack.getTemplate().getNoiseBuilderMap(), pack.getTemplate().getFunctions());
|
carver = new UserDefinedCarver(config.getHeight(), config.getLength(), start, mutate, radius, new Scope(), hash, config.getCutTop(), config.getCutBottom(), config, main);
|
||||||
} catch(ParseException e) {
|
} catch(ParseException e) {
|
||||||
throw new LoadException("Unable to parse radius equations", e);
|
throw new LoadException("Unable to parse radius equations", e);
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.carving;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
import com.dfsek.terra.api.block.BlockData;
|
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
import com.dfsek.terra.api.util.ProbabilityCollection;
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -13,8 +13,8 @@ import java.util.TreeMap;
|
|||||||
public class CarverPalette {
|
public class CarverPalette {
|
||||||
private final boolean blacklist;
|
private final boolean blacklist;
|
||||||
private final MaterialSet replace;
|
private final MaterialSet replace;
|
||||||
private final TreeMap<Integer, ProbabilityCollection<BlockData>> map = new TreeMap<>();
|
private final TreeMap<Integer, ProbabilityCollection<BlockState>> map = new TreeMap<>();
|
||||||
private ProbabilityCollection<BlockData>[] layers;
|
private ProbabilityCollection<BlockState>[] layers;
|
||||||
private int offset = 0;
|
private int offset = 0;
|
||||||
|
|
||||||
public CarverPalette(MaterialSet replaceable, boolean blacklist) {
|
public CarverPalette(MaterialSet replaceable, boolean blacklist) {
|
||||||
@ -22,12 +22,12 @@ public class CarverPalette {
|
|||||||
this.replace = replaceable;
|
this.replace = replaceable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarverPalette add(ProbabilityCollection<BlockData> collection, int y) {
|
public CarverPalette add(ProbabilityCollection<BlockState> collection, int y) {
|
||||||
map.put(y, collection);
|
map.put(y, collection);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProbabilityCollection<BlockData> get(int y) {
|
public ProbabilityCollection<BlockState> get(int y) {
|
||||||
int index = y + offset;
|
int index = y + offset;
|
||||||
return index >= 0
|
return index >= 0
|
||||||
? index < layers.length
|
? index < layers.length
|
||||||
@ -49,8 +49,8 @@ public class CarverPalette {
|
|||||||
|
|
||||||
layers = new ProbabilityCollection[map.lastKey() + 1 - min];
|
layers = new ProbabilityCollection[map.lastKey() + 1 - min];
|
||||||
for(int y = min; y <= FastMath.max(map.lastKey(), max); y++) {
|
for(int y = min; y <= FastMath.max(map.lastKey(), max); y++) {
|
||||||
ProbabilityCollection<BlockData> d = null;
|
ProbabilityCollection<BlockState> d = null;
|
||||||
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : map.entrySet()) {
|
for(Map.Entry<Integer, ProbabilityCollection<BlockState>> e : map.entrySet()) {
|
||||||
if(e.getKey() >= y) {
|
if(e.getKey() >= y) {
|
||||||
d = e.getValue();
|
d = e.getValue();
|
||||||
break;
|
break;
|
@ -1,114 +1,94 @@
|
|||||||
package com.dfsek.terra.config.templates;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Abstractable;
|
|
||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.annotations.Final;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
import com.dfsek.terra.api.math.range.ConstantRange;
|
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||||
|
import com.dfsek.terra.api.util.ConstantRange;
|
||||||
import com.dfsek.terra.api.util.Range;
|
import com.dfsek.terra.api.util.Range;
|
||||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||||
import com.dfsek.terra.carving.CarverPalette;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||||
public class CarverTemplate extends AbstractableTemplate {
|
public class CarverTemplate implements AbstractableTemplate {
|
||||||
@Value("id")
|
@Value("id")
|
||||||
|
@Final
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@Value("step")
|
@Value("step")
|
||||||
@Abstractable
|
|
||||||
@Default
|
@Default
|
||||||
private int step = 2;
|
private int step = 2;
|
||||||
|
|
||||||
@Value("recalculate-magnitude")
|
@Value("recalculate-magnitude")
|
||||||
@Default
|
@Default
|
||||||
@Abstractable
|
|
||||||
private double recaclulateMagnitude = 4;
|
private double recaclulateMagnitude = 4;
|
||||||
|
|
||||||
@Value("recalculate-direction")
|
@Value("recalculate-direction")
|
||||||
@Abstractable
|
|
||||||
@Default
|
@Default
|
||||||
private Range recalc = new ConstantRange(8, 10);
|
private Range recalc = new ConstantRange(8, 10);
|
||||||
|
|
||||||
@Value("length")
|
@Value("length")
|
||||||
@Abstractable
|
|
||||||
private Range length;
|
private Range length;
|
||||||
|
|
||||||
@Value("start.x")
|
@Value("start.x")
|
||||||
@Abstractable
|
|
||||||
private double startX;
|
private double startX;
|
||||||
|
|
||||||
@Value("start.y")
|
@Value("start.y")
|
||||||
@Abstractable
|
|
||||||
private double startY;
|
private double startY;
|
||||||
|
|
||||||
@Value("start.z")
|
@Value("start.z")
|
||||||
@Abstractable
|
|
||||||
private double startZ;
|
private double startZ;
|
||||||
|
|
||||||
@Value("start.radius.x")
|
@Value("start.radius.x")
|
||||||
@Abstractable
|
|
||||||
private String radMX;
|
private String radMX;
|
||||||
|
|
||||||
@Value("start.radius.y")
|
@Value("start.radius.y")
|
||||||
@Abstractable
|
|
||||||
private String radMY;
|
private String radMY;
|
||||||
|
|
||||||
@Value("start.radius.z")
|
@Value("start.radius.z")
|
||||||
@Abstractable
|
|
||||||
private String radMZ;
|
private String radMZ;
|
||||||
|
|
||||||
@Value("start.height")
|
@Value("start.height")
|
||||||
@Abstractable
|
|
||||||
private Range height;
|
private Range height;
|
||||||
|
|
||||||
@Value("cut.bottom")
|
@Value("cut.bottom")
|
||||||
@Abstractable
|
|
||||||
@Default
|
@Default
|
||||||
private int cutBottom = 0;
|
private int cutBottom = 0;
|
||||||
|
|
||||||
@Value("cut.top")
|
@Value("cut.top")
|
||||||
@Abstractable
|
|
||||||
@Default
|
@Default
|
||||||
private int cutTop = 0;
|
private int cutTop = 0;
|
||||||
|
|
||||||
@Value("mutate.x")
|
@Value("mutate.x")
|
||||||
@Abstractable
|
|
||||||
private double mutateX;
|
private double mutateX;
|
||||||
|
|
||||||
@Value("mutate.y")
|
@Value("mutate.y")
|
||||||
@Abstractable
|
|
||||||
private double mutateY;
|
private double mutateY;
|
||||||
|
|
||||||
@Value("mutate.z")
|
@Value("mutate.z")
|
||||||
@Abstractable
|
|
||||||
private double mutateZ;
|
private double mutateZ;
|
||||||
|
|
||||||
@Value("palette.top")
|
@Value("palette.top")
|
||||||
@Abstractable
|
|
||||||
private CarverPalette top;
|
private CarverPalette top;
|
||||||
|
|
||||||
@Value("palette.bottom")
|
@Value("palette.bottom")
|
||||||
@Abstractable
|
|
||||||
private CarverPalette bottom;
|
private CarverPalette bottom;
|
||||||
|
|
||||||
@Value("palette.outer")
|
@Value("palette.outer")
|
||||||
@Abstractable
|
|
||||||
private CarverPalette outer;
|
private CarverPalette outer;
|
||||||
|
|
||||||
@Value("palette.inner")
|
@Value("palette.inner")
|
||||||
@Abstractable
|
|
||||||
private CarverPalette inner;
|
private CarverPalette inner;
|
||||||
|
|
||||||
@Value("shift")
|
@Value("shift")
|
||||||
@Abstractable
|
|
||||||
@Default
|
@Default
|
||||||
private Map<BlockType, MaterialSet> shift = new HashMap<>();
|
private Map<BlockType, MaterialSet> shift = new HashMap<>();
|
||||||
|
|
||||||
@Value("update")
|
@Value("update")
|
||||||
@Abstractable
|
|
||||||
@Default
|
@Default
|
||||||
private MaterialSet update = new MaterialSet();
|
private MaterialSet update = new MaterialSet();
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
package com.dfsek.terra.world.population;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.block.BlockData;
|
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
import com.dfsek.terra.api.config.WorldConfig;
|
import com.dfsek.terra.api.config.WorldConfig;
|
||||||
import com.dfsek.terra.api.handle.WorldHandle;
|
import com.dfsek.terra.api.handle.WorldHandle;
|
||||||
import com.dfsek.terra.api.profiler.ProfileFrame;
|
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||||
@ -12,17 +12,15 @@ import com.dfsek.terra.api.world.Chunk;
|
|||||||
import com.dfsek.terra.api.world.TerraWorld;
|
import com.dfsek.terra.api.world.TerraWorld;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.generator.Chunkified;
|
import com.dfsek.terra.api.world.generator.Chunkified;
|
||||||
import com.dfsek.terra.api.world.generator.TerraBlockPopulator;
|
import com.dfsek.terra.api.world.generator.TerraGenerationStage;
|
||||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
|
||||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class CavePopulator implements TerraBlockPopulator, Chunkified {
|
public class CavePopulator implements TerraGenerationStage, Chunkified {
|
||||||
private static final Map<BlockType, BlockData> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
|
private static final Map<BlockType, BlockState> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
|
|
||||||
public CavePopulator(TerraPlugin main) {
|
public CavePopulator(TerraPlugin main) {
|
||||||
@ -34,19 +32,17 @@ public class CavePopulator implements TerraBlockPopulator, Chunkified {
|
|||||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
WorldHandle handle = main.getWorldHandle();
|
WorldHandle handle = main.getWorldHandle();
|
||||||
BlockData AIR = handle.createBlockData("minecraft:air");
|
|
||||||
try(ProfileFrame ignore = main.getProfiler().profile("carving")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("carving")) {
|
||||||
Random random = PopulationUtil.getRandom(chunk);
|
Random random = PopulationUtil.getRandom(chunk);
|
||||||
if(!tw.isSafe()) return;
|
|
||||||
WorldConfig config = tw.getConfig();
|
WorldConfig config = tw.getConfig();
|
||||||
if(config.disableCarving()) return;
|
if(config.disableCarving()) return;
|
||||||
|
|
||||||
for(UserDefinedCarver c : config.getRegistry(UserDefinedCarver.class).entries()) {
|
for(UserDefinedCarver c : config.getRegistry(UserDefinedCarver.class).entries()) {
|
||||||
CarverTemplate template = c.getConfig();
|
CarverTemplate template = c.getConfig();
|
||||||
Map<Vector3, BlockData> shiftCandidate = new HashMap<>();
|
Map<Vector3, BlockState> shiftCandidate = new HashMap<>();
|
||||||
c.carve(chunk.getX(), chunk.getZ(), world, (v, type) -> {
|
c.carve(chunk.getX(), chunk.getZ(), world, (v, type) -> {
|
||||||
try(ProfileFrame ignored = main.getProfiler().profile("carving:" + c.getConfig().getID())) {
|
try(ProfileFrame ignored = main.getProfiler().profile("carving:" + c.getConfig().getID())) {
|
||||||
BlockData m = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
BlockState m = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
||||||
BlockType re = m.getBlockType();
|
BlockType re = m.getBlockType();
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case CENTER:
|
case CENTER:
|
||||||
@ -76,10 +72,10 @@ public class CavePopulator implements TerraBlockPopulator, Chunkified {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for(Map.Entry<Vector3, BlockData> entry : shiftCandidate.entrySet()) {
|
for(Map.Entry<Vector3, BlockState> entry : shiftCandidate.entrySet()) {
|
||||||
Vector3 l = entry.getKey();
|
Vector3 l = entry.getKey();
|
||||||
Vector3 mut = l.clone();
|
Vector3 mut = l.clone();
|
||||||
BlockData orig = chunk.getBlock(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
BlockState orig = chunk.getBlock(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
||||||
do mut.subtract(0, 1, 0);
|
do mut.subtract(0, 1, 0);
|
||||||
while(mut.getY() > world.getMinHeight() && chunk.getBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ()).matches(orig));
|
while(mut.getY() > world.getMinHeight() && chunk.getBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ()).matches(orig));
|
||||||
try {
|
try {
|
@ -1,26 +1,16 @@
|
|||||||
package com.dfsek.terra.carving;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
import com.dfsek.paralithic.Expression;
|
import com.dfsek.paralithic.Expression;
|
||||||
import com.dfsek.paralithic.eval.parser.Parser;
|
import com.dfsek.paralithic.eval.parser.Parser;
|
||||||
import com.dfsek.paralithic.eval.parser.Scope;
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
|
import com.dfsek.terra.addons.carver.carving.Carver;
|
||||||
|
import com.dfsek.terra.addons.carver.carving.Worm;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
|
import com.dfsek.terra.api.util.ConstantRange;
|
||||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2;
|
|
||||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3;
|
|
||||||
import com.dfsek.terra.api.math.range.ConstantRange;
|
|
||||||
import com.dfsek.terra.api.util.FastRandom;
|
|
||||||
import com.dfsek.terra.api.util.Range;
|
import com.dfsek.terra.api.util.Range;
|
||||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|
||||||
import com.dfsek.terra.api.world.carving.Carver;
|
|
||||||
import com.dfsek.terra.api.world.carving.Worm;
|
|
||||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
|
||||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -47,7 +37,7 @@ public class UserDefinedCarver extends Carver {
|
|||||||
private Range recalc = new ConstantRange(8, 10);
|
private Range recalc = new ConstantRange(8, 10);
|
||||||
private double recalcMagnitude = 3;
|
private double recalcMagnitude = 3;
|
||||||
|
|
||||||
public UserDefinedCarver(Range height, Range length, double[] start, double[] mutate, List<String> radii, Scope parent, long hash, int topCut, int bottomCut, CarverTemplate config, TerraPlugin main, Map<String, NoiseSeeded> functions, Map<String, FunctionTemplate> definedFunctions) throws ParseException {
|
public UserDefinedCarver(Range height, Range length, double[] start, double[] mutate, List<String> radii, Scope parent, long hash, int topCut, int bottomCut, CarverTemplate config, TerraPlugin main) throws ParseException {
|
||||||
super(height.getMin(), height.getMax());
|
super(height.getMin(), height.getMax());
|
||||||
this.length = length;
|
this.length = length;
|
||||||
this.start = start;
|
this.start = start;
|
||||||
@ -60,21 +50,6 @@ public class UserDefinedCarver extends Carver {
|
|||||||
|
|
||||||
Parser p = new Parser();
|
Parser p = new Parser();
|
||||||
|
|
||||||
functions.forEach((id, noise) -> {
|
|
||||||
switch(noise.getDimensions()) {
|
|
||||||
case 2:
|
|
||||||
p.registerFunction(id, new NoiseFunction2(noise.apply(hash)));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
p.registerFunction(id, new NoiseFunction3(noise.apply(hash)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for(Map.Entry<String, FunctionTemplate> entry : definedFunctions.entrySet()) {
|
|
||||||
p.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), p, parent));
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope s = new Scope().withParent(parent);
|
Scope s = new Scope().withParent(parent);
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +70,7 @@ public class UserDefinedCarver extends Carver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Worm getWorm(long l, Vector3 vector) {
|
public Worm getWorm(long l, Vector3 vector) {
|
||||||
Random r = new FastRandom(l + hash);
|
Random r = new Random(l + hash);
|
||||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut, l);
|
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,10 +106,10 @@ public class UserDefinedCarver extends Carver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
|
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
|
||||||
BiomeTemplate conf = ((UserDefinedBiome) main.getWorld(w).getBiomeProvider().getBiome((chunkX << 4) + 8, (chunkZ << 4) + 8)).getConfig();
|
/*BiomeTemplate conf = ((UserDefinedBiome) main.getWorld(w).getBiomeProvider().getBiome((chunkX << 4) + 8, (chunkZ << 4) + 8)).getConfig();
|
||||||
if(conf.getCarvers().get(this) != null) {
|
if(conf.getCarvers().get(this) != null) {
|
||||||
return new FastRandom(random.nextLong() + hash).nextInt(100) < conf.getCarvers().get(this);
|
return new Random(random.nextLong() + hash).nextInt(100) < conf.getCarvers().get(this);
|
||||||
}
|
}*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +120,10 @@ public class UserDefinedCarver extends Carver {
|
|||||||
private class UserDefinedWorm extends Worm {
|
private class UserDefinedWorm extends Worm {
|
||||||
private final Vector3 direction;
|
private final Vector3 direction;
|
||||||
private final Vector3 origin;
|
private final Vector3 origin;
|
||||||
|
private final long seed;
|
||||||
private int steps;
|
private int steps;
|
||||||
private int nextDirection = 0;
|
private int nextDirection = 0;
|
||||||
private double[] currentRotation = new double[3];
|
private double[] currentRotation = new double[3];
|
||||||
private final long seed;
|
|
||||||
|
|
||||||
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut, long seed) {
|
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut, long seed) {
|
||||||
super(length, r, origin);
|
super(length, r, origin);
|
||||||
@ -156,7 +131,7 @@ public class UserDefinedCarver extends Carver {
|
|||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
super.setTopCut(topCut);
|
super.setTopCut(topCut);
|
||||||
super.setBottomCut(bottomCut);
|
super.setBottomCut(bottomCut);
|
||||||
direction = new Vector3Impl((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1], (r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
direction = new Vector3((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1], (r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
||||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), length, 0, seed};
|
double[] args = {origin.getX(), origin.getY(), origin.getZ(), length, 0, seed};
|
||||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.api.world.carving;
|
package com.dfsek.terra.addons.carver.carving;
|
||||||
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
@ -1,8 +1,7 @@
|
|||||||
package com.dfsek.terra.api.world.carving;
|
package com.dfsek.terra.addons.carver.carving;
|
||||||
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.vector.Vector3Impl;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -98,12 +97,12 @@ public abstract class Worm {
|
|||||||
for(int z = -zRad - 1; z <= zRad + 1; z++) {
|
for(int z = -zRad - 1; z <= zRad + 1; z++) {
|
||||||
if(!(FastMath.floorDiv(origin.getBlockZ() + z, 16) == chunkZ)) continue;
|
if(!(FastMath.floorDiv(origin.getBlockZ() + z, 16) == chunkZ)) continue;
|
||||||
for(int y = -yRad - 1; y <= yRad + 1; y++) {
|
for(int y = -yRad - 1; y <= yRad + 1; y++) {
|
||||||
Vector3 position = origin.clone().add(new Vector3Impl(x, y, z));
|
Vector3 position = origin.clone().add(new Vector3(x, y, z));
|
||||||
if(position.getY() < world.getMinHeight() || position.getY() > world.getMaxHeight()) continue;
|
if(position.getY() < world.getMinHeight() || position.getY() > world.getMaxHeight()) continue;
|
||||||
double eq = ellipseEquation(x, y, z, xRad, yRad, zRad);
|
double eq = ellipseEquation(x, y, z, xRad, yRad, zRad);
|
||||||
if(eq <= 1 &&
|
if(eq <= 1 &&
|
||||||
y >= -yRad - 1 + bottomCut && y <= yRad + 1 - topCut) {
|
y >= -yRad - 1 + bottomCut && y <= yRad + 1 - topCut) {
|
||||||
consumer.accept(new Vector3Impl(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), Carver.CarvingType.CENTER);
|
consumer.accept(new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), Carver.CarvingType.CENTER);
|
||||||
} else if(eq <= 1.5) {
|
} else if(eq <= 1.5) {
|
||||||
Carver.CarvingType type = Carver.CarvingType.WALL;
|
Carver.CarvingType type = Carver.CarvingType.WALL;
|
||||||
if(y <= -yRad - 1 + bottomCut) {
|
if(y <= -yRad - 1 + bottomCut) {
|
||||||
@ -111,7 +110,7 @@ public abstract class Worm {
|
|||||||
} else if(y >= yRad + 1 - topCut) {
|
} else if(y >= yRad + 1 - topCut) {
|
||||||
type = Carver.CarvingType.TOP;
|
type = Carver.CarvingType.TOP;
|
||||||
}
|
}
|
||||||
consumer.accept(new Vector3Impl(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), type);
|
consumer.accept(new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
3
common/addons/config-flora/README.md
Normal file
3
common/addons/config-flora/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# config-flora
|
||||||
|
|
||||||
|
Registers the default configuration for Terra Flora, `FLORA`.
|
45
common/addons/config-flora/build.gradle.kts
Normal file
45
common/addons/config-flora/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
idea
|
||||||
|
}
|
||||||
|
|
||||||
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
|
|
||||||
|
group = "com.dfsek.terra.common"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
"shadedApi"(project(":common:api"))
|
||||||
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
artifact(tasks["jar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
|
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
|
maven(mavenUrl) {
|
||||||
|
val mavenUsername: String? by project
|
||||||
|
val mavenPassword: String? by project
|
||||||
|
if (mavenUsername != null && mavenPassword != null) {
|
||||||
|
credentials {
|
||||||
|
username = mavenUsername
|
||||||
|
password = mavenPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.addons.flora;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.flora.config.BlockLayerTemplate;
|
||||||
|
import com.dfsek.terra.addons.flora.flora.gen.BlockLayer;
|
||||||
|
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.pack.ConfigPackPreLoadEvent;
|
||||||
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
|
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||||
|
|
||||||
|
@Addon("config-flora")
|
||||||
|
@Author("Terra")
|
||||||
|
@Version("0.1.0")
|
||||||
|
public class FloraAddon extends TerraAddon implements EventListener {
|
||||||
|
@Inject
|
||||||
|
private TerraPlugin main;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
main.getEventManager().registerListener(this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPackLoad(ConfigPackPreLoadEvent event) throws DuplicateEntryException {
|
||||||
|
event.getPack().registerConfigType(new FloraConfigType(event.getPack()), "FLORA", 2);
|
||||||
|
event.getPack().applyLoader(BlockLayer.class, BlockLayerTemplate::new);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.dfsek.terra.addons.flora;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.config.ConfigType;
|
||||||
|
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||||
|
import com.dfsek.terra.api.world.Flora;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class FloraConfigType implements ConfigType<FloraTemplate, Flora> {
|
||||||
|
private final FloraFactory factory = new FloraFactory();
|
||||||
|
private final ConfigPack pack;
|
||||||
|
|
||||||
|
public FloraConfigType(ConfigPack pack) {
|
||||||
|
this.pack = pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FloraTemplate getTemplate(ConfigPack pack, TerraPlugin main) {
|
||||||
|
return new FloraTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigFactory<FloraTemplate, Flora> getFactory() {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Flora> getTypeClass() {
|
||||||
|
return Flora.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<OpenRegistry<Flora>> registrySupplier() {
|
||||||
|
return pack.getRegistryFactory()::create;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.dfsek.terra.addons.flora;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.flora.flora.gen.TerraFlora;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
|
import com.dfsek.terra.api.world.Flora;
|
||||||
|
|
||||||
|
public class FloraFactory implements ConfigFactory<FloraTemplate, Flora> {
|
||||||
|
@Override
|
||||||
|
public TerraFlora build(FloraTemplate config, TerraPlugin main) {
|
||||||
|
return new TerraFlora(config.getLayers(), config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable(), config.getRotatable(), config.getMaxPlacements(), config.getSearch(), config.isSpawnBlacklist(), config.getIrrigableOffset(), main, config.getNoiseDistribution().apply(2403L));
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user